diff --git a/.DS_Store b/.DS_Store
index 04caf51..a75af8a 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/index.css b/index.css
new file mode 100644
index 0000000..0c52521
--- /dev/null
+++ b/index.css
@@ -0,0 +1,1393 @@
+body {
+ font-family: 'Be Vietnam Pro', cursive;
+ transition: background-color 0.5s ease;
+ /* NEW: Add Polaroid theme variables */
+ --polaroid-bg-color: #450A0A;
+ --polaroid-placeholder-color: #b45309;
+ --footer-bg-color: rgba(0, 0, 0, 0.8);
+}
+
+.theme-sdvn {
+ background-color: #151523;
+ background-image: linear-gradient(to bottom, #5858e6, #151523);
+ /* OVERRIDE: Polaroid theme variables */
+ --polaroid-bg-color: #1e1b4b; /* A deep indigo/purple */
+ --polaroid-placeholder-color: #a5b4fc; /* A soft, light indigo */
+ --footer-bg-color: rgba(30, 27, 75, 0.8);
+}
+
+/* .theme-vietnam {
+ background-image:
+ url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3e%3cpath d='M50,5 L61.8,38.2 L98.2,38.2 L68.2,59.8 L79.6,92.7 L50,71.5 L20.4,92.7 L31.8,59.8 L1.8,38.2 L38.2,38.2 Z' fill='%23FFFF00' fill-opacity='0.15'/%3e%3c/svg%3e"),
+ radial-gradient(ellipse at bottom, #DA251D, #a21a14);
+ background-position: center, 0 0;
+ background-repeat: no-repeat, no-repeat;
+ background-size: 80vmin, cover;
+ background-attachment: fixed, fixed;
+
+ --polaroid-bg-color: #450A0A;
+ --polaroid-placeholder-color: #b45309;
+ --footer-bg-color: rgba(69, 10, 10, 0.5);
+} */
+
+.theme-vietnam {
+ background-image: radial-gradient(ellipse at bottom, #c62921, #a21a14);
+ --polaroid-bg-color: #450A0A; /* bg-red-950 */
+ --polaroid-placeholder-color: #b45309; /* text-yellow-700 */
+ --footer-bg-color: rgba(69, 10, 10, 0.5); /* UPDATED: Increased transparency */
+}
+
+.theme-skyline {
+ background-color: #0052D4; /* Fallback color */
+ background-image: linear-gradient(to left, #6FB1FC, #4364F7, #0052D4);
+ /* OVERRIDE: Polaroid theme variables */
+ --polaroid-bg-color: #052e6c; /* A deep, rich blue */
+ --polaroid-placeholder-color: #a7cffd; /* A soft, sky blue */
+ --footer-bg-color: rgba(0, 82, 212, 0.5); /* UPDATED: Increased transparency */
+}
+
+/* NEW: Hidden Jaguar Theme */
+.theme-hidden-jaguar {
+ background-image: linear-gradient(to bottom, #0fd850 0%, #f9f047 100%);
+ --polaroid-bg-color: #14532d;
+ --polaroid-placeholder-color: #d9f99d;
+ --footer-bg-color: rgba(20, 83, 45, 0.6);
+}
+
+/* NEW: Wide Matrix Theme */
+.theme-wide-matrix {
+ background-image: linear-gradient(to top, #fcc5e4 0%, #fda34b 15%, #ff7882 35%, #c8699e 52%, #7046aa 71%, #0c1db8 87%, #020f75 100%);
+ --polaroid-bg-color: #020f75;
+ --polaroid-placeholder-color: #fcc5e4;
+ --footer-bg-color: rgba(2, 15, 117, 0.6);
+}
+
+/* === Additional Themes === */
+.theme-rainbow {
+ background-image: linear-gradient(to right, #0575E6, #00F260);
+ --polaroid-bg-color: #064e3b;
+ --polaroid-placeholder-color: #00F260;
+ --footer-bg-color: rgba(5, 150, 105, 0.6);
+}
+
+.theme-soundcloud {
+ background-image: linear-gradient(to right, #f83600, #fe8c00);
+ --polaroid-bg-color: #7f1d1d;
+ --polaroid-placeholder-color: #fe8c00;
+ --footer-bg-color: rgba(127, 29, 29, 0.6);
+}
+
+.theme-amin {
+ background-image: linear-gradient(to right, #4A00E0, #8E2DE2);
+ --polaroid-bg-color: #3b0764;
+ --polaroid-placeholder-color: #8E2DE2;
+ --footer-bg-color: rgba(59, 7, 100, 0.6);
+}
+
+
+.title-font {
+ font-family: 'Asimovian', sans-serif;
+}
+
+/* .title-font {
+ font-family: 'Taviraj', serif;
+ font-weight: 300;
+ font-style: italic;
+} */
+.sub-title-font {
+ font-family: 'Playwrite AU SA', cursive;
+}
+.base-font {
+ font-family: "Be Vietnam Pro", sans-serif;
+}
+
+/* === NEW: Centralized Component Styles === */
+
+/* --- Footer Theming --- */
+.footer-themed-bg {
+ background-color: var(--footer-bg-color);
+ transition: background-color 0.5s ease;
+}
+
+/* --- NEW: Theme swatch styles --- */
+.theme-swatch {
+ width: 1rem; /* w-4 */
+ height: 1rem; /* h-4 */
+ border-radius: 9999px; /* rounded-full */
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ flex-shrink: 0;
+}
+
+/* --- NEW: Custom Theme Dropdown styles --- */
+.theme-dropdown {
+ position: relative;
+}
+
+.theme-dropdown-button {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem; /* gap-2 */
+ background-color: rgba(0, 0, 0, 0.4);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 0.5rem; /* rounded-lg - Increased radius */
+ padding: 0.375rem 0.75rem; /* py-1.5 px-3 - Increased padding */
+ color: #E5E5E5; /* text-neutral-200 */
+ transition: background-color 150ms;
+ min-width: 150px;
+ justify-content: space-between;
+}
+
+.theme-dropdown-button:hover {
+ background-color: rgba(0, 0, 0, 0.6);
+}
+
+.theme-dropdown-button:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: 0 0 0 2px #FBBF24; /* focus:ring-2 focus:ring-yellow-400 */
+}
+
+.theme-dropdown-panel {
+ position: absolute;
+ bottom: 100%; /* position above the button */
+ margin-bottom: 0.5rem; /* mb-2, space between button and panel */
+ left: 0;
+ right: 0;
+ background-color: rgba(23, 23, 23, 0.95); /* bg-neutral-900 @ 95% */
+ backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 0.75rem; /* rounded-xl - More rounded */
+ z-index: 50;
+ list-style: none;
+ padding: 0.5rem; /* p-2 */
+ max-height: 20rem; /* max-h-80 */
+ overflow-y: auto;
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5); /* Enhanced shadow */
+}
+
+/* Custom Scrollbar for Dropdown */
+.theme-dropdown-panel::-webkit-scrollbar {
+ width: 6px;
+}
+.theme-dropdown-panel::-webkit-scrollbar-track {
+ background: transparent;
+}
+.theme-dropdown-panel::-webkit-scrollbar-thumb {
+ background-color: #404040; /* neutral-700 */
+ border-radius: 10px;
+}
+
+.theme-dropdown-item {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem; /* gap-3 */
+ padding: 0.5rem 0.75rem; /* p-2 px-3 */
+ cursor: pointer;
+ border-radius: 0.5rem; /* rounded-lg */
+ color: #E5E5E5; /* text-neutral-200 */
+ transition: background-color 150ms;
+ font-size: 0.875rem;
+}
+
+.theme-dropdown-item:hover, .theme-dropdown-item[data-headlessui-state="active"] {
+ background-color: rgba(251, 191, 36, 0.2); /* bg-yellow-400/20 */
+ color: #FBBF24; /* text-yellow-400 */
+}
+
+
+/* --- Buttons --- */
+.btn {
+ font-family: "Be Vietnam Pro", sans-serif;
+ font-weight: 600; /* semibold */
+ font-size: 1rem; /* text-base */
+ text-align: center;
+ padding: 0.625rem 1.5rem; /* py-2.5 px-6 */
+ border-radius: 0.5rem; /* rounded-lg */
+ transition: transform 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
+ -webkit-tap-highlight-color: transparent; /* Remove tap highlight on mobile */
+}
+
+.btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none;
+}
+
+.btn-primary {
+ color: #171717; /* neutral-900 */
+ background-color: #FBBF24; /* bg-yellow-400 */
+ border: 1px solid #FBBF24;
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* shadow-sm */
+}
+.btn-primary:hover:not(:disabled) {
+ transform: translateY(-2px);
+ background-color: #FCD34D; /* hover:bg-yellow-300 */
+ border-color: #FCD34D;
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); /* shadow-md */
+}
+.btn-primary:disabled:hover {
+ background-color: #FBBF24;
+}
+
+.btn-secondary {
+ color: #E5E5E5; /* text-neutral-200 */
+ background-color: rgba(255, 255, 255, 0.1);
+ -webkit-backdrop-filter: blur(4px); /* backdrop-blur-sm */
+ backdrop-filter: blur(4px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+}
+.btn-secondary:hover:not(:disabled) {
+ transform: translateY(-2px);
+ background-color: rgba(255, 255, 255, 0.2);
+ border-color: rgba(255, 255, 255, 0.3);
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+}
+
+.btn-back {
+ z-index: 20;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ color: white;
+ background-color: rgba(255, 255, 255, 0.1);
+ -webkit-backdrop-filter: blur(4px); /* backdrop-blur-sm */
+ backdrop-filter: blur(4px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ padding: 0.5rem 1rem; /* py-2 px-4 */
+ border-radius: 9999px; /* rounded-full */
+ font-size: 0.875rem; /* text-sm */
+ transition-property: background-color;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.btn-back:hover {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+
+.btn-search {
+ z-index: 20;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ background-color: rgba(255, 255, 255, 0.1);
+ -webkit-backdrop-filter: blur(4px);
+ backdrop-filter: blur(4px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ width: 2.25rem; /* h-9, w-9 */
+ height: 2.25rem;
+ padding: 0;
+ border-radius: 9999px; /* rounded-full */
+ transition: background-color 150ms;
+}
+
+.btn-search:hover:not(:disabled) {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+
+.btn-search:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none;
+}
+
+.btn-gallery {
+ z-index: 20;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ background-color: rgba(255, 255, 255, 0.1);
+ -webkit-backdrop-filter: blur(4px);
+ backdrop-filter: blur(4px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ width: 2.25rem; /* h-9, w-9 */
+ height: 2.25rem;
+ padding: 0;
+ border-radius: 9999px; /* rounded-full */
+ transition: background-color 150ms, opacity 150ms, transform 150ms;
+}
+.btn-gallery:hover:not(:disabled) {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+.btn-gallery:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none;
+}
+
+.btn-sm {
+ padding: 0.5rem 1.25rem; /* py-2 px-5 */
+ font-size: 0.875rem; /* text-sm */
+}
+
+/* --- Home Screen App Card --- */
+.app-card {
+ background-color: rgba(0, 0, 0, 0.2);
+ -webkit-backdrop-filter: blur(4px); /* backdrop-blur-sm */
+ backdrop-filter: blur(4px);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 2rem;
+ cursor: pointer;
+ transition: all 300ms;
+ flex-basis: 100%;
+ max-width: 420px;
+ /* NEW styles */
+ position: relative;
+ overflow: hidden;
+ aspect-ratio: 16 / 9;
+}
+
+
+@media(min-width: 640px) { /* sm breakpoint */
+ .app-card {
+ flex-basis: calc(50% - 0.75rem); /* for 2 columns with 1.5rem gap */
+ max-width: none; /* Remove max-width for multi-column layouts */
+ }
+}
+
+@media(min-width: 1024px) { /* lg breakpoint */
+ .app-card {
+ flex-basis: calc(25% - 1.125rem); /* for 4 columns with 1.5rem gap */
+ }
+}
+
+.app-card:hover {
+ background-color: rgba(0, 0, 0, 0.4);
+ border-color: rgba(251, 191, 36, 0.5); /* hover:border-yellow-400/50 */
+ transform: translateY(-0.5rem); /* hover:-translate-y-2 */
+}
+
+/* --- Forms (Selects, Textareas) --- */
+.form-input {
+ width: 100%;
+ padding: 0.75rem; /* p-3 */
+ background-color: rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(255, 255, 255, 0.15); /* Increased border visibility */
+ border-radius: 0.5rem; /* rounded-lg */
+ color: #E5E5E5; /* text-neutral-200 */
+ transition: all 150ms;
+}
+
+.form-input:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: 0 0 0 2px #FBBF24; /* focus:ring-2 focus:ring-yellow-400 */
+ background-color: rgba(0, 0, 0, 0.4);
+}
+
+.form-input::placeholder {
+ color: #A3A3A3; /* placeholder-neutral-400 */
+}
+
+/* --- UPDATED: Custom Select Styling to fix white/white issue and visuals --- */
+select.form-input {
+ appearance: none; /* Remove default arrow */
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right 0.75rem center;
+ background-size: 1rem;
+ padding-right: 2.5rem; /* Space for arrow */
+ cursor: pointer;
+}
+
+select.form-input option {
+ background-color: #171717; /* Dark background for options */
+ color: #E5E5E5; /* Light text */
+}
+
+/* --- Polaroid Card --- */
+.polaroid-card {
+ background-color: #F5F5F5; /* bg-neutral-100 */
+ padding: 1rem; /* !p-4 */
+ padding-bottom: 4rem; /* !pb-16 */
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-start;
+ border-radius: 0.375rem; /* rounded-md */
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
+ position: relative;
+}
+
+.polaroid-image-container {
+ width: 100%;
+ background-color: var(--polaroid-bg-color); /* MODIFIED */
+ box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05); /* shadow-inner */
+ position: relative;
+ overflow: hidden;
+ transition: all 0.5s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+@media (min-width: 768px) { /* md */
+ .polaroid-image-container {
+ height: 18rem;
+ width: auto;
+ }
+ .polaroid-image-container.has-image {
+ height: 27rem; /* 18rem * 1.5 */
+ }
+}
+
+/* Placeholder styles using CSS variables */
+.placeholder-icon-wrapper {
+ color: var(--polaroid-placeholder-color);
+ opacity: 0.4;
+ transition: opacity 0.3s ease, color 0.5s ease;
+}
+
+.polaroid-image-container.group:hover .placeholder-icon-wrapper {
+ opacity: 0.6;
+}
+
+.polaroid-caption {
+ font-family: 'Playwrite AU SA', cursive;
+ font-weight: 700;
+ font-size: 1.125rem; /* text-lg */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding-bottom: 0.25rem; /* pb-1 */
+}
+
+/* --- Modal --- */
+.modal-overlay {
+ position: fixed;
+ inset: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ z-index: 50;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 1rem;
+}
+
+.modal-content {
+ background-color: rgba(38, 38, 38, 0.75); /* bg-neutral-800 @ 75% */
+ -webkit-backdrop-filter: blur(12px);
+ backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 0.5rem; /* rounded-lg */
+ box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); /* shadow-2xl */
+ padding: 1.5rem; /* p-6 */
+ width: 100%;
+ max-width: 32rem; /* max-w-lg */
+ margin-left: auto;
+ margin-right: auto;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem; /* gap-4 */
+}
+
+.modal-textarea {
+ width: 100%;
+ height: 7rem; /* h-28 */
+ padding: 0.75rem; /* p-3 */
+ background-color: #171717; /* bg-neutral-900 */
+ border: 1px solid #404040; /* border-neutral-700 */
+ border-radius: 0.375rem; /* rounded-md */
+ color: #E5E5E5; /* text-neutral-200 */
+ transition: box-shadow 150ms;
+}
+.modal-textarea:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: 0 0 0 2px #FBBF24; /* focus:ring-2 focus:ring-yellow-400 */
+}
+.modal-textarea::placeholder {
+ color: #737373; /* placeholder-neutral-500 */
+}
+
+/* --- NEW: Prompt Result Card --- */
+/* This is a polaroid-style card specifically for displaying text content like prompts. */
+.prompt-card {
+ background-color: #F5F5F5; /* bg-neutral-100 */
+ padding: 1rem; /* p-4 */
+ border-radius: 0.375rem; /* rounded-md */
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
+
+ /* Flexbox setup to enable scrolling content */
+ display: flex;
+ flex-direction: column;
+ position: relative; /* For the copy button */
+ overflow: hidden; /* Crucial to contain the flex children and enable inner scroll */
+
+ /* Ensure it doesn't shrink and takes available width */
+ width: 100%;
+}
+
+/* The scrollable content area within the prompt card */
+.prompt-card-content {
+ flex: 1 1 0%; /* flex-1 */
+ min-height: 0; /* Crucial for allowing shrinkage in flexbox */
+ overflow-y: auto; /* Enable vertical scrollbar when content overflows */
+ padding-right: 0.5rem; /* Add some padding so text doesn't touch the scrollbar */
+ max-height:350px;
+}
+
+/* Custom scrollbar styling for a cleaner look */
+.prompt-card-content::-webkit-scrollbar {
+ width: 8px;
+}
+
+.prompt-card-content::-webkit-scrollbar-track {
+ background: transparent; /* Make the track invisible */
+}
+
+.prompt-card-content::-webkit-scrollbar-thumb {
+ background-color: #a3a3a3; /* neutral-400 */
+ border-radius: 10px;
+ /* Add padding around the thumb to make it appear thinner */
+ border: 2px solid #F5F5F5; /* Use card background color for padding */
+}
+
+.prompt-card-content::-webkit-scrollbar-thumb:hover {
+ background-color: #737373; /* neutral-500 */
+}
+
+
+/* --- NEW: Results View Actions --- */
+.results-actions {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1rem;
+ width: 100%;
+}
+.results-actions > * { /* Target buttons, etc. */
+ width: 100%;
+}
+
+@media(min-width: 640px) { /* sm breakpoint */
+ .results-actions {
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
+ width: auto;
+ padding: 0;
+ }
+ .results-actions > * {
+ width: auto;
+ max-width: none;
+ }
+}
+.results-actions > .btn {
+ padding: 0.375rem 1rem; /* py-1.5 px-4 */
+ font-size: 0.875rem; /* text-sm */
+ border-width: 1px;
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* shadow-sm */
+}
+
+/* --- Pagination Controls --- */
+.pagination-nav {
+ display: flex;
+ align-items: center;
+ gap: 1rem; /* gap-4 */
+ color: #D4D4D4; /* text-neutral-300 */
+ font-family: "Be Vietnam Pro", sans-serif;
+ font-weight: 600;
+}
+
+/* MODIFIED: Target only text buttons to avoid style conflicts with icon buttons */
+.pagination-nav button:not(.btn-search):not(.btn-gallery) {
+ color: white;
+ background-color: rgba(255, 255, 255, 0.1);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ padding: 0.5rem 1rem; /* py-2 px-4 */
+ border-radius: 9999px; /* rounded-full */
+ font-size: 0.875rem; /* text-sm */
+ font-weight: 600;
+ transition: background-color 150ms;
+}
+
+.pagination-nav button:not(.btn-search):not(.btn-gallery):hover:not(:disabled) {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+
+.pagination-nav button:not(.btn-search):not(.btn-gallery):disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+/* --- UPDATED: Searchable Dropdown --- */
+.searchable-dropdown-container {
+ position: relative;
+ width: 100%;
+}
+
+.searchable-dropdown-list {
+ position: absolute;
+ top: calc(100% + 0.5rem); /* Push down slightly */
+ left: 0;
+ right: 0;
+ z-index: 60; /* Higher than standard input */
+ background-color: rgba(23, 23, 23, 0.95); /* bg-neutral-900 @ 95% */
+ -webkit-backdrop-filter: blur(12px);
+ backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 0.75rem; /* rounded-xl */
+ max-height: 18rem; /* max-h-72 */
+ overflow-y: auto;
+ list-style: none;
+ padding: 0.5rem;
+ box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.6); /* Stronger shadow */
+}
+
+/* Custom scrollbar for dropdown list */
+.searchable-dropdown-list::-webkit-scrollbar {
+ width: 6px;
+}
+.searchable-dropdown-list::-webkit-scrollbar-track {
+ background: transparent;
+}
+.searchable-dropdown-list::-webkit-scrollbar-thumb {
+ background-color: #404040; /* neutral-700 */
+ border-radius: 10px;
+}
+.searchable-dropdown-list::-webkit-scrollbar-thumb:hover {
+ background-color: #525252; /* neutral-600 */
+}
+
+
+.searchable-dropdown-item {
+ padding: 0.5rem 0.75rem; /* py-2 px-3 */
+ cursor: pointer;
+ color: #E5E5E5; /* text-neutral-200 */
+ transition: background-color 150ms, color 150ms;
+ border-radius: 0.5rem; /* rounded-lg */
+ font-size: 0.875rem;
+ margin-bottom: 0.125rem;
+}
+
+.searchable-dropdown-item:hover, .searchable-dropdown-item.is-highlighted {
+ background-color: rgba(251, 191, 36, 0.2); /* bg-yellow-400/20 */
+ color: #FBBF24; /* text-yellow-400 */
+}
+
+/* --- NEW: Searchable Dropdown Group Header --- */
+.searchable-dropdown-group-header {
+ padding: 0.75rem 0.75rem 0.25rem;
+ font-size: 0.75rem; /* text-xs */
+ font-weight: 700;
+ color: #a3a3a3; /* neutral-400 */
+ text-transform: uppercase;
+ /* background-color: #1f1f1f; REMOVED: Let transparency work */
+ position: sticky;
+ top: 0;
+ z-index: 1; /* Keep it above items when scrolling */
+ pointer-events: none;
+}
+
+/* --- NEW: Slider --- */
+.slider-container {
+ position: relative;
+ padding: 0.75rem 0; /* py-3 */
+}
+
+.slider-track {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 100%;
+ height: 0.5rem; /* h-2 */
+ background-color: rgba(0, 0, 0, 0.4);
+ border-radius: 9999px; /* rounded-full */
+ outline: none;
+ transition: opacity 0.2s;
+ cursor: pointer;
+}
+
+.slider-track::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 1rem; /* w-4 */
+ height: 1rem; /* h-4 */
+ background-color: #FBBF24; /* bg-yellow-400 */
+ border-radius: 9999px; /* rounded-full */
+ border: 2px solid #171717; /* border-neutral-900 */
+ box-shadow: 0 0 0 1px #FBBF24; /* ring-1 ring-yellow-400 */
+ cursor: pointer;
+ transition: transform 0.2s ease-in-out;
+}
+.slider-track::-webkit-slider-thumb:hover {
+ transform: scale(1.1);
+}
+
+.slider-track::-moz-range-thumb {
+ width: 1rem; /* w-4 */
+ height: 1rem; /* h-4 */
+ background-color: #FBBF24; /* bg-yellow-400 */
+ border-radius: 9999px; /* rounded-full */
+ border: 2px solid #171717; /* border-neutral-900 */
+ box-shadow: 0 0 0 1px #FBBF24; /* ring-1 ring-yellow-400 */
+ cursor: pointer;
+ transition: transform 0.2s ease-in-out;
+}
+.slider-track::-moz-range-thumb:hover {
+ transform: scale(1.1);
+}
+
+
+.slider-labels {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 0.75rem; /* mt-3 */
+ padding: 0 0.5rem; /* px-2 to align with thumb edges */
+}
+
+.slider-label {
+ font-family: "Be Vietnam Pro", sans-serif;
+ font-size: 0.75rem; /* text-xs */
+ color: #a3a3a3; /* text-neutral-400 */
+ text-align: center;
+ flex: 1;
+ font-weight: 500;
+ transition: color 0.2s, font-weight 0.2s;
+}
+
+.slider-label-active {
+ color: #FBBF24; /* text-yellow-400 */
+ font-weight: 700;
+}
+
+/* --- NEW: Gallery Modal (Pinterest Layout) --- */
+.gallery-grid {
+ flex-grow: 1;
+ overflow-y: auto;
+ column-count: 2; /* Default for mobile */
+ column-gap: 0.75rem; /* gap-3 */
+ padding: 0.25rem;
+}
+@media(min-width: 640px) { .gallery-grid { column-count: 3; } }
+@media(min-width: 1024px) { .gallery-grid { column-count: 4; } }
+@media(min-width: 1280px) { .gallery-grid { column-count: 5; } }
+
+.gallery-grid-item {
+ break-inside: avoid;
+ margin-bottom: 0.75rem; /* Vertical gap */
+ border-radius: 0.25rem; /* rounded-sm */
+ overflow: hidden;
+ cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s;
+ position: relative; /* Needed for action buttons */
+}
+.gallery-grid-item:hover {
+ transform: scale(1.02);
+ box-shadow: 0 0 10px rgba(251, 191, 36, 0.5); /* shadow-lg shadow-yellow-400/50 */
+}
+.gallery-grid-item img, .gallery-grid-item video {
+ width: 100%;
+ height: auto; /* Allow natural aspect ratio */
+ display: block; /* Remove any bottom space */
+}
+
+/* --- NEW: Gallery Thumbnail Actions --- */
+.thumbnail-actions {
+ position: absolute;
+ top: 0.5rem; /* top-2 */
+ right: 0.5rem; /* right-2 */
+ z-index: 10;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem; /* gap-2 */
+ opacity: 0;
+ transition-property: opacity, transform;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 200ms;
+ transform: translateY(0.25rem); /* Start slightly down */
+}
+
+.group:hover .thumbnail-actions {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.thumbnail-action-btn {
+ padding: 0.5rem; /* p-2 */
+ background-color: rgba(0, 0, 0, 0.6);
+ border-radius: 9999px; /* rounded-full */
+ color: white;
+ transition: all 150ms;
+}
+
+.thumbnail-action-btn:hover {
+ background-color: rgb(75 85 99); /* hover:bg-neutral-600 */
+ transform: scale(1.1);
+}
+
+.thumbnail-action-btn:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: 0 0 0 2px white; /* focus:ring-2 focus:ring-white */
+}
+
+
+/* --- UPDATED: Gallery Lightbox --- */
+.gallery-lightbox {
+ position: fixed;
+ inset: 0;
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.gallery-lightbox-backdrop {
+ position: absolute;
+ inset: 0;
+ background-color: rgba(0,0,0,0.85);
+ -webkit-backdrop-filter: blur(8px);
+ backdrop-filter: blur(8px);
+ cursor: pointer;
+}
+.gallery-lightbox-img {
+ position: relative;
+ max-width: 90vw;
+ max-height: 85vh;
+ object-fit: contain;
+ border-radius: 0.5rem; /* rounded-lg */
+ box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5); /* shadow-2xl */
+}
+.lightbox-action-btn {
+ position: absolute;
+ top: 0.75rem;
+ right: 0.75rem;
+ z-index: 120;
+ background-color: rgba(0, 0, 0, 0.5);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ color: white;
+ width: 2.5rem;
+ height: 2.5rem;
+ border-radius: 9999px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background-color 0.2s, transform 0.2s;
+ cursor: pointer;
+}
+.lightbox-action-btn:hover {
+ background-color: rgba(0, 0, 0, 0.7);
+ transform: scale(1.1);
+}
+
+/* --- NEW: Image Editor Modal --- */
+.image-editor-modal-content {
+ max-height: 100vh;
+}
+
+.image-editor-preview-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: rgba(0,0,0,0.3);
+ border-radius: 0.25rem;
+ flex-grow: 1;
+ min-height: 0;
+}
+
+.image-editor-preview {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ display: block;
+}
+
+/* --- NEW: Before-After Modal --- */
+.comparison-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ border-radius: 0.25rem; /* rounded-sm */
+ user-select: none;
+}
+.comparison-image-wrapper {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+.comparison-image {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ pointer-events: none;
+}
+.comparison-slider-handle {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 1px;
+ background-color: rgba(255, 255, 255, 0.9);
+ cursor: ew-resize;
+ pointer-events: none;
+ transform: translateX(-50%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 0 5px rgba(0,0,0,0.3);
+}
+.comparison-slider-handle::after {
+ content: '';
+ width: 28px;
+ height: 28px;
+ background-color: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 9999px;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='black' stroke-width='2.5'%3e%3cpath stroke-linecap='round' stroke-linejoin='round' d='M10 19l-7-7 7-7m4 14l7-7-7-7'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 65%;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+.comparison-range-input {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ -webkit-appearance: none;
+ appearance: none;
+ background: transparent;
+ cursor: ew-resize;
+ z-index: 10;
+}
+.comparison-range-input::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 40px;
+ height: 100%;
+ background: transparent;
+}
+.comparison-range-input::-moz-range-thumb {
+ width: 40px;
+ height: 100%;
+ background: transparent;
+ border: 0;
+ border-radius: 0;
+}
+
+/* --- NEW: Before-After Modal Sidebar Grid --- */
+.before-after-sidebar-grid {
+ flex-grow: 1;
+ overflow-y: auto;
+ column-count: 1; /* Default for mobile */
+ column-gap: 0.75rem; /* gap-3 */
+ padding: 0.25rem;
+}
+@media(min-width: 640px) { .before-after-sidebar-grid { column-count: 2; } }
+
+/* --- NEW: Layer Composer Infinite Canvas Background --- */
+.infinite-canvas-bg {
+ background-color: #22252a; /* A dark, slightly blue-gray */
+ background-image:
+ linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(255, 255, 255, 0.07) 1px, transparent 1px);
+ background-size: 20px 20px;
+}
+
+/* --- NEW: AI Process Logger --- */
+.ai-process-logger {
+ position: fixed;
+ bottom: 4.5rem; /* Above footer */
+ right: 1.5rem;
+ width: 100%;
+ max-width: 24rem; /* max-w-md */
+ background-color: rgba(30, 30, 30, 0.8);
+ -webkit-backdrop-filter: blur(8px);
+ backdrop-filter: blur(8px);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 0.75rem; /* rounded-xl */
+ padding: 1rem;
+ z-index: 100; /* Above most other UI */
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.ai-process-logger-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-bottom: 0.5rem;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.ai-process-logger-title {
+ font-family: "Be Vietnam Pro", sans-serif;
+ font-weight: 700;
+ color: #FBBF24; /* text-yellow-400 */
+}
+
+.ai-process-logger-close {
+ padding: 0.25rem;
+ border-radius: 9999px;
+ color: #a3a3a3; /* neutral-400 */
+ transition: background-color 0.2s;
+}
+.ai-process-logger-close:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ color: white;
+}
+
+.ai-process-logger-content {
+ max-height: 15rem; /* max-h-60 */
+ overflow-y: auto;
+ list-style-type: none;
+ padding: 0.5rem 0.25rem 0 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+/* Custom scrollbar for logger */
+.ai-process-logger-content::-webkit-scrollbar {
+ width: 6px;
+}
+.ai-process-logger-content::-webkit-scrollbar-track {
+ background: transparent;
+}
+.ai-process-logger-content::-webkit-scrollbar-thumb {
+ background-color: #737373; /* neutral-500 */
+ border-radius: 10px;
+}
+
+.ai-process-logger-item {
+ font-size: 0.875rem; /* text-sm */
+ line-height: 1.4;
+}
+
+.log-item-info {
+ color: #d4d4d4; /* neutral-300 */
+}
+
+.log-item-spinner {
+ color: #d4d4d4; /* neutral-300 */
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.log-item-prompt {
+ background-color: rgba(0, 0, 0, 0.3);
+ padding: 0.75rem;
+ border-radius: 0.375rem; /* rounded-md */
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ color: #e5e5e5; /* neutral-200 */
+ position: relative;
+}
+
+.log-item-prompt pre {
+ white-space: pre-wrap;
+ word-break: break-word;
+ font-family: monospace;
+}
+
+.log-item-prompt .copy-btn {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+ padding: 0.25rem;
+ background-color: rgba(255, 255, 255, 0.1);
+ border-radius: 9999px;
+ color: #a3a3a3; /* neutral-400 */
+ transition: all 0.2s;
+}
+.log-item-prompt .copy-btn:hover {
+ background-color: rgba(255, 255, 255, 0.2);
+ color: white;
+}
+
+.log-item-success {
+ color: #4ade80; /* green-400 */
+ font-weight: 600;
+}
+
+.log-item-error {
+ color: #f87171; /* red-400 */
+ font-weight: 600;
+}
+
+/* --- NEW: Toggle Switch --- */
+.switch {
+ position: relative;
+ display: inline-block;
+ width: 40px; /* smaller width */
+ height: 22px; /* smaller height */
+}
+
+.switch input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+}
+
+.switch-slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #4b5563; /* gray-600 */
+ transition: .4s;
+ border-radius: 22px; /* fully rounded */
+}
+
+.switch-slider:before {
+ position: absolute;
+ content: "";
+ height: 16px; /* smaller knob */
+ width: 16px; /* smaller knob */
+ left: 3px;
+ bottom: 3px;
+ background-color: white;
+ transition: .4s;
+ border-radius: 50%;
+}
+
+input:checked + .switch-slider {
+ background-color: #FBBF24; /* yellow-400 */
+}
+
+input:focus + .switch-slider {
+ box-shadow: 0 0 1px #FBBF24;
+}
+
+input:checked + .switch-slider:before {
+ transform: translateX(18px); /* adjusted for new size */
+}
+
+/* --- NEW: Chatbot Markdown Styles --- */
+.chatbot-code-block {
+ position: relative;
+ background-color: #1a1a1a;
+ border-radius: 0.5rem; /* rounded-lg */
+ border: 1px solid #333;
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+ overflow: hidden;
+}
+
+.chatbot-code-block .code-block-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #2a2a2a;
+ padding: 0.25rem 0.75rem;
+ font-family: monospace;
+ font-size: 0.75rem; /* text-xs */
+ color: #a3a3a3; /* neutral-400 */
+}
+
+.chatbot-code-block pre {
+ white-space: pre-wrap;
+ word-break: break-word;
+ font-family: monospace;
+ font-size: 0.875rem; /* text-sm */
+ color: #e5e5e5; /* neutral-200 */
+ padding: 0.75rem;
+}
+
+.chatbot-code-block .copy-btn {
+ padding: 0.25rem;
+ border-radius: 9999px; /* rounded-full */
+ color: #a3a3a3; /* neutral-400 */
+ transition: all 0.2s;
+ cursor: pointer;
+}
+
+.chatbot-code-block .copy-btn:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ color: white;
+}
+
+/* Styles for comprehensive markdown */
+.chatbot-message > *:first-child { margin-top: 0; }
+.chatbot-message > *:last-child { margin-bottom: 0; }
+.chatbot-message p { margin-bottom: 0.5rem; }
+.chatbot-message h1,
+.chatbot-message h2,
+.chatbot-message h3 {
+ font-weight: 700;
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ color: #FBBF24; /* yellow-400 */
+}
+.chatbot-message h1 { font-size: 1.25em; }
+.chatbot-message h2 { font-size: 1.1em; }
+.chatbot-message h3 { font-size: 1.0em; }
+.chatbot-message ul,
+.chatbot-message ol {
+ margin-left: 0;
+ padding-left: 1.5rem; /* Indentation for lists */
+ margin-bottom: 0.5rem;
+}
+.chatbot-message li {
+ margin-bottom: 0.25rem;
+}
+.chatbot-message blockquote {
+ border-left: 3px solid #737373; /* neutral-500 */
+ padding-left: 1rem;
+ margin: 0.75rem 0;
+ color: #a3a3a3; /* neutral-400 */
+ font-style: italic;
+}
+.chatbot-message a {
+ color: #FBBF24; /* yellow-400 */
+ text-decoration: underline;
+ transition: color 0.2s;
+}
+.chatbot-message a:hover {
+ color: #FCD34D; /* yellow-300 */
+}
+.chatbot-message hr {
+ border: 0;
+ border-top: 1px solid #404040; /* neutral-700 */
+ margin: 1rem 0;
+}
+
+/* NEW: Chatbot Send Button */
+.chatbot-send-btn {
+ position: absolute;
+ bottom: 0.75rem; /* 12px */
+ right: 0.5rem; /* 8px */
+ padding: 0.375rem; /* 6px */
+ border-radius: 9999px; /* rounded-full */
+ transition: all 150ms;
+ color: #a3a3a3; /* neutral-400 */
+}
+
+.chatbot-send-btn:not(:disabled) {
+ cursor: pointer;
+ color: #e5e5e5; /* neutral-200 */
+}
+
+.chatbot-send-btn:not(:disabled):hover {
+ background-color: rgba(251, 191, 36, 0.2); /* bg-yellow-400/20 */
+ color: #FBBF24; /* text-yellow-400 */
+}
+
+.chatbot-send-btn:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+/* --- NEW: Results View Horizontal Scrollbar --- */
+.results-scroll-container::-webkit-scrollbar {
+ height: 12px;
+ width: 8px;
+}
+
+.results-scroll-container::-webkit-scrollbar-track {
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 10px;
+}
+
+.results-scroll-container::-webkit-scrollbar-thumb {
+ background: rgba(251, 191, 36, 0.5);
+ border-radius: 10px;
+ border: 2px solid transparent;
+ background-clip: padding-box;
+}
+
+.results-scroll-container::-webkit-scrollbar-thumb:hover {
+ background: rgba(251, 191, 36, 0.8);
+}
+
+.results-scroll-container::-webkit-scrollbar:horizontal {
+ height: 12px;
+}
+
+/* --- NEW: Storyboard Panel --- */
+.storyboard-panel {
+ display: flex;
+ flex-direction: column;
+ background-color: rgba(38, 38, 38, 0.7); /* neutral-800/70 */
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 0.75rem; /* rounded-xl */
+ overflow: hidden;
+ transition: box-shadow 0.2s;
+ min-height: 22.5rem; /* 360px */
+}
+.storyboard-panel:hover {
+ box-shadow: 0 0 15px rgba(251, 191, 36, 0.2);
+}
+.storyboard-panel-image-container {
+ position: relative;
+ width: 100%;
+ background-color: #171717; /* neutral-900 */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.storyboard-panel-content {
+ padding: 0.75rem; /* p-3 */
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 120px; /* Give it a minimum height */
+}
+.storyboard-panel-description {
+ font-size: 0.75rem; /* text-xs */
+ color: #d4d4d4; /* neutral-300 */
+ overflow-y: auto;
+ padding-right: 0.25rem;
+ white-space: pre-wrap;
+ height: 120px; /* Fixed height */
+}
+/* Custom scrollbar for description */
+.storyboard-panel-description::-webkit-scrollbar { width: 4px; }
+.storyboard-panel-description::-webkit-scrollbar-track { background: transparent; }
+.storyboard-panel-description::-webkit-scrollbar-thumb { background-color: #737373; border-radius: 4px; }
+
+.storyboard-panel-textarea {
+ width: 100%;
+ height: 90px; /* Fixed height */
+ background-color: #171717;
+ border: 1px solid #404040;
+ border-radius: 0.375rem;
+ color: #e5e5e5;
+ font-size: 0.75rem;
+ padding: 0.5rem;
+ resize: none;
+}
+.storyboard-panel-textarea:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: 0 0 0 2px #FBBF24;
+}
+
+.storyboard-panel-actions {
+ padding: 0 0.75rem 0.75rem; /* px-3 pb-3 */
+}
+
+/* --- NEW: Storyboard Scene Group --- */
+.storyboard-scene-group {
+ background-color: rgba(10, 10, 10, 0.2);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 1rem; /* rounded-2xl */
+ padding: 0.5rem; /* p-2 */
+ display: flex;
+ flex-direction: column;
+ gap: 1rem; /* gap-4 */
+}
+
+.storyboard-scene-group-title {
+ font-family: "Be Vietnam Pro", sans-serif;
+ font-weight: 700; /* bold */
+ font-size: 1rem; /* text-lg */
+ color: #FBBF24; /* text-yellow-400 */
+ padding-bottom: 0.75rem; /* pb-3 */
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ margin-bottom: 0.5rem; /* mb-2 */
+}
diff --git a/static/script.js b/static/script.js
index 157c895..c61fb20 100644
--- a/static/script.js
+++ b/static/script.js
@@ -75,7 +75,10 @@ document.addEventListener('DOMContentLoaded', () => {
const promptInput = document.getElementById('prompt');
const promptNoteInput = document.getElementById('prompt-note');
const promptHighlight = document.getElementById('prompt-highlight');
+ const noteHighlight = document.getElementById('note-highlight');
+ const themeOptionsContainer = document.getElementById('theme-options');
const promptPlaceholderText = promptInput?.getAttribute('placeholder') || '';
+ const promptNotePlaceholderText = promptNoteInput?.getAttribute('placeholder') || '';
const aspectRatioInput = document.getElementById('aspect-ratio');
const resolutionInput = document.getElementById('resolution');
const apiKeyInput = document.getElementById('api-key');
@@ -142,10 +145,11 @@ document.addEventListener('DOMContentLoaded', () => {
if (settings.note) promptNoteInput.value = settings.note;
if (settings.aspectRatio) aspectRatioInput.value = settings.aspectRatio;
if (settings.resolution) resolutionInput.value = settings.resolution;
- if (settings.model && apiModelSelect) {
- apiModelSelect.value = settings.model;
+ if (apiModelSelect) {
+ apiModelSelect.value = settings.model || apiModelSelect.value || 'gemini-3-pro-image-preview';
toggleResolutionVisibility();
}
+ currentTheme = settings.theme || DEFAULT_THEME;
return settings;
}
} catch (e) {
@@ -155,8 +159,10 @@ document.addEventListener('DOMContentLoaded', () => {
}
function persistSettings() {
- // Check if slotManager is initialized
- const referenceImages = (typeof slotManager !== 'undefined') ? slotManager.getImages() : [];
+ // Safely collect cached reference images for restoration
+ const referenceImages = (typeof slotManager !== 'undefined' && typeof slotManager.serializeReferenceImages === 'function')
+ ? slotManager.serializeReferenceImages()
+ : [];
const settings = {
apiKey: apiKeyInput.value,
@@ -165,7 +171,8 @@ document.addEventListener('DOMContentLoaded', () => {
aspectRatio: aspectRatioInput.value,
resolution: resolutionInput.value,
model: apiModelSelect ? apiModelSelect.value : 'gemini-3-pro-image-preview',
- referenceImages: referenceImages,
+ referenceImages,
+ theme: currentTheme || DEFAULT_THEME,
};
try {
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
@@ -208,6 +215,22 @@ document.addEventListener('DOMContentLoaded', () => {
'#a855f7', // purple
];
+ const DEFAULT_THEME = 'theme-sdvn';
+
+ const themeOptionsData = [
+ { id: 'theme-sdvn', name: 'SDVN', gradient: 'linear-gradient(to bottom, #5858e6, #151523)' },
+ { id: 'theme-vietnam', name: 'Vietnam', gradient: 'radial-gradient(ellipse at bottom, #c62921, #a21a14)' },
+ { id: 'theme-skyline', name: 'Skyline', gradient: 'linear-gradient(to left, #6FB1FC, #4364F7, #0052D4)' },
+ { id: 'theme-hidden-jaguar', name: 'Hidden Jaguar', gradient: 'linear-gradient(to bottom, #0fd850 0%, #f9f047 100%)' },
+ { id: 'theme-wide-matrix', name: 'Wide Matrix', gradient: 'linear-gradient(to top, #fcc5e4 0%, #fda34b 15%, #ff7882 35%, #c8699e 52%, #7046aa 71%, #0c1db8 87%, #020f75 100%)' },
+ { id: 'theme-rainbow', name: 'Rainbow', gradient: 'linear-gradient(to right, #0575E6, #00F260)' },
+ { id: 'theme-soundcloud', name: 'SoundCloud', gradient: 'linear-gradient(to right, #f83600, #fe8c00)' },
+ { id: 'theme-amin', name: 'Amin', gradient: 'linear-gradient(to right, #4A00E0, #8E2DE2)' },
+ ];
+
+ let currentPlaceholderSegments = [];
+ let currentTheme = DEFAULT_THEME;
+
function escapeHtml(value) {
return value.replace(/[&<>"']/g, (char) => {
switch (char) {
@@ -224,6 +247,7 @@ document.addEventListener('DOMContentLoaded', () => {
function buildPromptHighlightHtml(value) {
if (!promptHighlight) return '';
if (!value) {
+ currentPlaceholderSegments = [];
return `${escapeHtml(promptPlaceholderText)}`;
}
@@ -232,24 +256,100 @@ document.addEventListener('DOMContentLoaded', () => {
let match;
let colorIndex = 0;
let html = '';
+ const segments = [];
while ((match = placeholderRegex.exec(value)) !== null) {
html += escapeHtml(value.slice(lastIndex, match.index));
const color = promptHighlightColors[colorIndex % promptHighlightColors.length];
+ segments.push({
+ text: match[0],
+ color,
+ });
html += `${escapeHtml(match[0])}`;
lastIndex = match.index + match[0].length;
colorIndex++;
}
html += escapeHtml(value.slice(lastIndex));
+ currentPlaceholderSegments = segments;
return html || `${escapeHtml(promptPlaceholderText)}`;
}
+ function buildNoteHighlightHtml(value) {
+ if (!noteHighlight) return '';
+ if (!value) {
+ return `${escapeHtml(promptNotePlaceholderText)}`;
+ }
+
+ const lines = value.split('\n');
+ return lines
+ .map((line, index) => {
+ const color = currentPlaceholderSegments[index]?.color;
+ const styleAttr = color ? ` style="color:${color}"` : '';
+ return `${escapeHtml(line)}`;
+ })
+ .join('
');
+ }
+
function refreshPromptHighlight() {
if (!promptHighlight || !promptInput) return;
promptHighlight.innerHTML = buildPromptHighlightHtml(promptInput.value);
promptHighlight.scrollTop = promptInput.scrollTop;
promptHighlight.scrollLeft = promptInput.scrollLeft;
+ refreshNoteHighlight();
+ }
+
+ function refreshNoteHighlight() {
+ if (!noteHighlight || !promptNoteInput) return;
+ noteHighlight.innerHTML = buildNoteHighlightHtml(promptNoteInput.value);
+ noteHighlight.scrollTop = promptNoteInput.scrollTop;
+ noteHighlight.scrollLeft = promptNoteInput.scrollLeft;
+ }
+
+ function updateThemeSelectionUi() {
+ if (!themeOptionsContainer) return;
+ themeOptionsContainer.querySelectorAll('.theme-option').forEach(btn => {
+ const isActive = btn.dataset.themeId === currentTheme;
+ btn.classList.toggle('active', isActive);
+ btn.setAttribute('aria-selected', isActive);
+ });
+ }
+
+ function applyThemeClass(themeId) {
+ const themeIds = themeOptionsData.map(option => option.id);
+ document.body.classList.remove(...themeIds);
+ if (themeId && themeIds.includes(themeId)) {
+ document.body.classList.add(themeId);
+ currentTheme = themeId;
+ } else {
+ currentTheme = '';
+ }
+ updateThemeSelectionUi();
+ }
+
+ function selectTheme(themeId, { persist = true } = {}) {
+ applyThemeClass(themeId);
+ if (persist) {
+ persistSettings();
+ }
+ }
+
+ function renderThemeOptions(initialTheme) {
+ if (!themeOptionsContainer) return;
+ themeOptionsContainer.innerHTML = '';
+ themeOptionsData.forEach(option => {
+ const btn = document.createElement('button');
+ btn.type = 'button';
+ btn.className = 'theme-option';
+ btn.dataset.themeId = option.id;
+ btn.setAttribute('role', 'option');
+ btn.setAttribute('aria-label', `Chọn theme ${option.name}`);
+ btn.style.backgroundImage = option.gradient;
+ btn.innerHTML = `${option.name}`;
+ btn.addEventListener('click', () => selectTheme(option.id));
+ themeOptionsContainer.appendChild(btn);
+ });
+ applyThemeClass(initialTheme);
}
// --- End Helper Functions ---
@@ -326,6 +426,8 @@ document.addEventListener('DOMContentLoaded', () => {
});
const savedSettings = loadSettings();
+ renderThemeOptions(currentTheme || DEFAULT_THEME);
+ applyThemeClass(currentTheme || DEFAULT_THEME);
slotManager.initialize(savedSettings.referenceImages || []);
refreshPromptHighlight();
@@ -359,9 +461,18 @@ document.addEventListener('DOMContentLoaded', () => {
promptHighlight.scrollTop = promptInput.scrollTop;
promptHighlight.scrollLeft = promptInput.scrollLeft;
});
- promptNoteInput.addEventListener('input', persistSettings);
+ promptNoteInput.addEventListener('input', () => {
+ refreshNoteHighlight();
+ persistSettings();
+ });
+ promptNoteInput.addEventListener('scroll', () => {
+ if (!noteHighlight) return;
+ noteHighlight.scrollTop = promptNoteInput.scrollTop;
+ noteHighlight.scrollLeft = promptNoteInput.scrollLeft;
+ });
aspectRatioInput.addEventListener('change', persistSettings);
resolutionInput.addEventListener('change', persistSettings);
+ window.addEventListener('beforeunload', persistSettings);
const queueCounter = document.getElementById('queue-counter');
const queueCountText = document.getElementById('queue-count-text');
diff --git a/static/style.css b/static/style.css
index 13f92be..f0d56eb 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1,7 +1,7 @@
:root {
--bd-bg: radial-gradient(circle at 15% 20%, #2e2ce0 0%, #0b0b1b 35%, #03030b 100%);
--panel-bg: rgba(10, 11, 22, 0.95);
- --panel-backdrop: rgba(6, 7, 20, 0.7);
+ --panel-backdrop: rgba(6, 7, 20, 0.5);
--border-color: rgba(255, 255, 255, 0.12);
--text-primary: #f5f5f5;
--text-secondary: #cbd5f5;
@@ -402,6 +402,16 @@ textarea {
min-height: 100px;
}
+/* Theme overrides driven from index.css gradients */
+body.theme-sdvn { --bd-bg: radial-gradient(circle at 15% 20%, #2e2ce0 0%, #0b0b1b 35%, #03030b 100%); }
+body.theme-vietnam { --bd-bg: radial-gradient(ellipse at bottom, #c62921, #a21a14); }
+body.theme-skyline { --bd-bg: linear-gradient(to left, #6FB1FC, #4364F7, #0052D4); }
+body.theme-hidden-jaguar { --bd-bg: linear-gradient(to bottom, #0fd850 0%, #f9f047 100%); }
+body.theme-wide-matrix { --bd-bg: linear-gradient(to top, #fcc5e4 0%, #fda34b 15%, #ff7882 35%, #c8699e 52%, #7046aa 71%, #0c1db8 87%, #020f75 100%); }
+body.theme-rainbow { --bd-bg: linear-gradient(to right, #0575E6, #00F260); }
+body.theme-soundcloud { --bd-bg: linear-gradient(to right, #f83600, #fe8c00); }
+body.theme-amin { --bd-bg: linear-gradient(to right, #4A00E0, #8E2DE2); }
+
.prompt-wrapper {
position: relative;
width: 100%;
@@ -414,7 +424,7 @@ textarea {
.prompt-wrapper.prompt-highlighting {
position: relative;
border: 1px solid var(--border-color);
- /* border-radius: 0.5rem; */
+ border-radius: 0.5rem;
/* background-color: var(--input-bg); */
backdrop-filter: blur(6px);
overflow: hidden;
@@ -467,10 +477,118 @@ textarea {
font-size: 0.875rem;
line-height: 1.4;
resize: vertical;
- min-height: 100px;
+ width: 100%;
+ height: 100%;
opacity:0.3
}
+.note-wrapper.note-highlighting {
+ position: relative;
+ border: 1px solid var(--border-color);
+ border-radius: 0.5rem;
+ /* background-color: var(--input-bg); */
+ backdrop-filter: blur(6px);
+}
+
+.note-highlight {
+ position: absolute;
+ inset: 0;
+ padding: 0.75rem;
+ overflow: auto;
+ pointer-events: none;
+ white-space: pre-wrap;
+ word-break: break-word;
+ z-index: 1;
+ color: var(--text-secondary);
+ font-family: inherit;
+ font-size: 0.875rem;
+ line-height: 1.4;
+}
+
+.note-highlight::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+}
+
+.note-highlight .note-placeholder {
+ color: var(--text-secondary);
+}
+
+.note-highlight .note-line {
+ display: inline;
+}
+
+.note-wrapper.note-highlighting textarea {
+ position: relative;
+ z-index: 2;
+ border: none;
+ outline: none;
+ background: transparent;
+ color: transparent;
+ caret-color: var(--accent-color);
+ padding: 0.75rem;
+ font-family: inherit;
+ font-size: 0.875rem;
+ line-height: 1.4;
+ resize: vertical;
+ opacity: 0.3;
+ width: 100%;
+ height: 100%;
+}
+
+.theme-option-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
+ gap: 0.4rem;
+}
+
+.theme-option {
+ position: relative;
+ border: 1px solid rgba(255, 255, 255, 0.18);
+ border-radius: 1rem;
+ padding: 0.6rem;
+ color: #fff;
+ cursor: pointer;
+ transition: transform 0.15s ease, border-color 0.2s ease, box-shadow 0.2s ease, background-position 0.4s ease;
+ text-align: left;
+ height: 40px;
+ overflow: hidden;
+}
+
+.theme-option::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(to top right, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.05));
+ pointer-events: none;
+}
+
+.theme-option .theme-option-name {
+ position: relative;
+ z-index: 1;
+ font-weight: 700;
+ letter-spacing: 0.3px;
+ font-size: 0.85rem;
+ text-shadow: 0 1px 6px rgba(0, 0, 0, 0.35);
+}
+
+.theme-option:focus-visible {
+ outline: 2px solid var(--accent-color);
+ outline-offset: 2px;
+}
+
+.theme-option:hover {
+ transform: translateY(-1px);
+ border-color: var(--accent-color);
+ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.45);
+ background-position: 80% 20%;
+}
+
+.theme-option.active {
+ border-color: var(--accent-color);
+ box-shadow: 0 0 0 1px rgba(251, 191, 36, 0.5), 0 12px 28px rgba(251, 191, 36, 0.18);
+}
+
.prompt-actions {
display: flex;
justify-content: flex-end;
@@ -709,7 +827,7 @@ button#generate-btn:disabled {
padding: 2rem;
overflow: hidden;
position: relative;
- background: radial-gradient(circle at top, rgba(27, 38, 102, 0.4), rgba(6, 6, 18, 0.95));
+ background: var(--panel-backdrop);
border-radius: 1.5rem;
cursor: grab;
user-select: none;
@@ -930,7 +1048,7 @@ button#generate-btn:disabled {
height: 180px;
flex-shrink: 0;
width: 100%;
- background: transparent;
+ background: var(--panel-backdrop);
}
.history-section h3 {
diff --git a/templates/index.html b/templates/index.html
index 0ee4943..19808d8 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -90,8 +90,11 @@