/* ══════════════════════════════════════════════════ SUNO FORGE — Dark Terminal Theme ══════════════════════════════════════════════════ */ /* ── CSS Custom Properties ── */ :root { --bg-primary: #0d0d0d; --bg-secondary: #111111; --bg-panel: #0a0a0a; --bg-input: #080808; --bg-card: #101010; --cyan: #00f5ff; --green: #39ff14; --magenta: #ff00cc; --red: #ff2244; --amber: #ffaa00; --white: #e0e0e0; --dim: #555555; --dimmer: #333333; --border: #1a1a1a; --font: 'JetBrains Mono', monospace; --glow-cyan: 0 0 8px #00f5ff, 0 0 2px #00f5ff; --glow-green: 0 0 8px #39ff14, 0 0 2px #39ff14; --glow-magenta: 0 0 8px #ff00cc, 0 0 2px #ff00cc; } /* ── Reset ── */ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } html { font-size: 14px; scroll-behavior: smooth; } body { font-family: var(--font); background: var(--bg-primary); color: var(--white); min-height: 100vh; overflow-x: hidden; line-height: 1.5; } /* ── Scanline Overlay ── */ body::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999; background: repeating-linear-gradient( 0deg, transparent, transparent 2px, rgba(0, 245, 255, 0.015) 2px, rgba(0, 245, 255, 0.015) 4px ); } /* ── Scrollbar ── */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: var(--bg-primary); } ::-webkit-scrollbar-thumb { background: var(--dimmer); border: none; } ::-webkit-scrollbar-thumb:hover { background: var(--cyan); } /* ── Header ── */ .header { display: flex; align-items: center; justify-content: space-between; padding: 12px 24px; border-bottom: 1px solid var(--dimmer); background: var(--bg-secondary); position: sticky; top: 0; z-index: 100; } .header-title { font-size: 1.4rem; font-weight: 700; letter-spacing: 4px; text-transform: uppercase; color: var(--cyan); text-shadow: var(--glow-cyan); display: flex; align-items: center; gap: 10px; } .header-title .emoji { font-size: 1.2rem; filter: drop-shadow(0 0 4px var(--cyan)); } .header-subtitle { font-size: 0.7rem; color: var(--dim); letter-spacing: 2px; text-transform: uppercase; margin-top: 2px; } .header-right { display: flex; align-items: center; gap: 12px; } /* ── Settings Toggle ── */ .settings-toggle { background: none; border: 1px solid var(--dimmer); color: var(--dim); font-family: var(--font); font-size: 1.2rem; cursor: pointer; padding: 6px 10px; transition: all 0.2s; border-radius: 0; } .settings-toggle:hover { color: var(--cyan); border-color: var(--cyan); box-shadow: var(--glow-cyan); } /* ── Settings Dropdown ── */ .settings-panel { position: absolute; top: 56px; right: 24px; width: 380px; background: var(--bg-secondary); border: 1px solid var(--cyan); box-shadow: var(--glow-cyan), 0 8px 32px rgba(0, 0, 0, 0.6); padding: 20px; z-index: 200; display: none; } .settings-panel.active { display: block; } .settings-panel h3 { font-size: 0.8rem; color: var(--cyan); text-transform: uppercase; letter-spacing: 2px; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid var(--dimmer); } .settings-group { margin-bottom: 14px; } .settings-group label { display: block; font-size: 0.7rem; color: var(--dim); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 4px; } .settings-group .input-row { display: flex; gap: 6px; } .settings-group .input-row input { flex: 1; } .settings-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--dimmer); } .model-meta { font-size: 0.6rem; color: var(--dim); margin-top: 4px; letter-spacing: 0.5px; line-height: 1.6; } .model-meta .model-context { color: var(--cyan); } .model-meta .model-free { color: var(--green); font-weight: 600; } .model-count { font-size: 0.6rem; color: var(--dimmer); margin-top: 2px; } /* ── Iframe Banner ── */ .iframe-banner { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 8px 24px; background: rgba(255, 170, 0, 0.08); border-bottom: 1px solid var(--amber); font-size: 0.7rem; color: var(--amber); letter-spacing: 0.5px; flex-wrap: wrap; } .btn-iframe-open { background: var(--amber); color: #000; border-color: var(--amber); font-weight: 700; padding: 4px 12px; text-decoration: none; font-family: var(--font); font-size: 0.65rem; letter-spacing: 1px; box-shadow: 0 0 6px rgba(255, 170, 0, 0.4); transition: all 0.2s; } .btn-iframe-open:hover { box-shadow: 0 0 12px rgba(255, 170, 0, 0.6); background: #ffbb33; } .iframe-dismiss { border: none; color: var(--amber); font-size: 0.7rem; padding: 2px 6px; } .iframe-dismiss:hover { color: var(--white); } .iframe-notice { margin-top: 14px; padding: 10px 12px; border: 1px solid var(--amber); background: rgba(255, 170, 0, 0.05); font-size: 0.65rem; color: var(--dim); line-height: 1.6; } .iframe-notice a { color: var(--amber); text-decoration: underline; font-weight: 600; } .iframe-notice a:hover { color: var(--white); } /* ── Main Grid ── */ .main-grid { display: grid; grid-template-columns: 240px 1fr 1fr; gap: 0; min-height: calc(100vh - 56px - 140px); } /* ── Panels ── */ .panel { border-right: 1px solid var(--dimmer); padding: 16px; overflow-y: auto; } .panel:last-child { border-right: none; } .panel-label { font-size: 0.65rem; color: var(--dim); text-transform: uppercase; letter-spacing: 3px; margin-bottom: 16px; padding-bottom: 6px; border-bottom: 1px solid var(--dimmer); } /* ── Channel Panel (Left) ── */ .channel-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; } .channel-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px; border: 1px solid transparent; cursor: pointer; transition: all 0.15s; font-size: 0.8rem; } .channel-item:hover { border-color: var(--dimmer); background: rgba(0, 245, 255, 0.03); } .channel-item.active { border-color: var(--cyan); background: rgba(0, 245, 255, 0.05); box-shadow: inset 3px 0 0 var(--cyan); } .channel-item .ch-name { color: var(--white); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; } .channel-item .ch-badge { font-size: 0.6rem; padding: 2px 8px; border: 1px solid var(--green); color: var(--green); text-transform: uppercase; letter-spacing: 1px; white-space: nowrap; } .channel-item .ch-delete { font-size: 0.7rem; color: var(--dimmer); cursor: pointer; padding: 0 4px; transition: color 0.15s; background: none; border: none; font-family: var(--font); } .channel-item .ch-delete:hover { color: var(--red); } /* ── New Channel Form ── */ .new-channel-form { display: none; padding: 12px; border: 1px solid var(--cyan); margin-top: 8px; } .new-channel-form.active { display: block; } .new-channel-form .form-group { margin-bottom: 8px; } .new-channel-form .form-actions { display: flex; gap: 6px; margin-top: 10px; } /* ── Buttons ── */ .btn { font-family: var(--font); font-size: 0.75rem; padding: 8px 16px; border: 1px solid var(--dimmer); background: transparent; color: var(--white); cursor: pointer; text-transform: uppercase; letter-spacing: 2px; transition: all 0.2s; border-radius: 0; font-weight: 600; } .btn:hover { border-color: var(--cyan); color: var(--cyan); } .btn-new-channel { width: 100%; border: 1px dashed var(--dimmer); color: var(--dim); padding: 10px; margin-top: 8px; } .btn-new-channel:hover { border-color: var(--cyan); color: var(--cyan); border-style: solid; } .btn-forge { width: 100%; background: var(--green); color: #000; border: 1px solid var(--green); font-weight: 700; font-size: 0.85rem; padding: 12px; letter-spacing: 3px; box-shadow: var(--glow-green); position: relative; overflow: hidden; } .btn-forge:hover { background: #2de010; box-shadow: 0 0 16px #39ff14, 0 0 4px #39ff14; } .btn-forge:active { transform: scale(0.98); } .btn-forge.loading { pointer-events: none; opacity: 0.7; } .btn-forge.loading::after { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent); animation: forge-shimmer 1.5s infinite; } @keyframes forge-shimmer { to { left: 100%; } } .btn-surprise { width: 100%; border: 1px solid var(--cyan); color: var(--cyan); padding: 10px; letter-spacing: 2px; } .btn-surprise:hover { background: rgba(0, 245, 255, 0.08); box-shadow: var(--glow-cyan); } .btn-copy { font-size: 0.65rem; padding: 4px 12px; border: 1px solid var(--dimmer); color: var(--dim); } .btn-copy:hover { border-color: var(--green); color: var(--green); } .btn-copy.copied { border-color: var(--green); color: var(--green); box-shadow: var(--glow-green); } .btn-save { border-color: var(--green); color: var(--green); } .btn-save:hover { background: rgba(57, 255, 20, 0.08); box-shadow: var(--glow-green); } .btn-cancel { border-color: var(--dim); color: var(--dim); } .btn-cancel:hover { border-color: var(--red); color: var(--red); } .btn-danger { border-color: var(--red); color: var(--red); } .btn-danger:hover { background: rgba(255, 34, 68, 0.1); } .btn-sm { font-size: 0.65rem; padding: 5px 10px; letter-spacing: 1px; } .btn-icon { padding: 5px 8px; font-size: 0.8rem; border: 1px solid var(--dimmer); background: none; color: var(--dim); cursor: pointer; font-family: var(--font); transition: all 0.15s; border-radius: 0; } .btn-icon:hover { border-color: var(--cyan); color: var(--cyan); } /* ── Form Elements ── */ .form-group { margin-bottom: 12px; } .form-group label { display: block; font-size: 0.65rem; color: var(--dim); text-transform: uppercase; letter-spacing: 2px; margin-bottom: 4px; } input[type="text"], input[type="password"], select, textarea { width: 100%; background: var(--bg-input); border: 1px solid var(--dimmer); color: var(--white); font-family: var(--font); font-size: 0.8rem; padding: 8px 10px; outline: none; transition: border-color 0.2s, box-shadow 0.2s; border-radius: 0; -webkit-appearance: none; appearance: none; } input[type="text"]:focus, input[type="password"]:focus, select:focus, textarea:focus { border-color: var(--cyan); box-shadow: var(--glow-cyan); } select { cursor: pointer; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%2300f5ff'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; padding-right: 30px; } select option { background: var(--bg-primary); color: var(--white); } textarea { resize: vertical; min-height: 60px; } /* ── Checkbox ── */ .checkbox-group { display: flex; align-items: center; gap: 8px; cursor: pointer; } .checkbox-group input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--cyan); cursor: pointer; } .checkbox-group label { font-size: 0.75rem; color: var(--dim); cursor: pointer; margin: 0; } /* ── Builder Panel (Center) ── */ .active-channel-label { font-size: 0.75rem; color: var(--dimmer); letter-spacing: 2px; text-transform: uppercase; margin-bottom: 16px; } .builder-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 20px; } .error-message { font-size: 0.7rem; color: var(--red); text-shadow: 0 0 6px rgba(255, 34, 68, 0.5); padding: 8px; border: 1px solid var(--red); margin-top: 8px; display: none; } .error-message.active { display: block; animation: error-flash 0.3s ease; } @keyframes error-flash { 0% { opacity: 0; transform: translateY(-4px); } 100% { opacity: 1; transform: translateY(0); } } /* ── Output Panel (Right) ── */ .output-section { margin-bottom: 20px; } .output-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } .output-label { font-size: 0.65rem; color: var(--cyan); text-transform: uppercase; letter-spacing: 2px; font-weight: 600; } .output-textarea { width: 100%; background: var(--bg-input); border: 1px solid var(--dimmer); color: var(--white); font-family: var(--font); font-size: 0.75rem; padding: 10px; resize: none; outline: none; border-radius: 0; } .output-textarea:focus { border-color: var(--cyan); } .char-counter { font-size: 0.6rem; text-align: right; margin-top: 3px; letter-spacing: 1px; } .char-counter.green { color: var(--green); } .char-counter.amber { color: var(--amber); } .char-counter.red { color: var(--red); } .token-usage { font-size: 0.65rem; color: var(--dimmer); letter-spacing: 1px; padding: 8px 0; border-top: 1px solid var(--dimmer); margin-top: 12px; } .btn-save-history { width: 100%; margin-top: 8px; } /* ── Lyrics Section ── */ .lyrics-section { display: none; } .lyrics-section.active { display: block; } /* ── History Strip ── */ .history-strip { border-top: 1px solid var(--dimmer); padding: 12px 24px; background: var(--bg-secondary); } .history-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; } .history-header h3 { font-size: 0.65rem; color: var(--dim); text-transform: uppercase; letter-spacing: 3px; } .history-scroll { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 8px; } .history-tile { min-width: 180px; max-width: 200px; padding: 10px 12px; border: 1px solid var(--dimmer); background: var(--bg-card); cursor: pointer; transition: all 0.15s; flex-shrink: 0; } .history-tile:hover { border-color: var(--cyan); background: rgba(0, 245, 255, 0.03); } .history-tile .ht-channel { font-size: 0.7rem; font-weight: 600; color: var(--white); margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .history-tile .ht-genre { font-size: 0.6rem; color: var(--green); } .history-tile .ht-time { font-size: 0.55rem; color: var(--dimmer); margin-top: 4px; } .history-empty { font-size: 0.7rem; color: var(--dimmer); padding: 10px 0; font-style: italic; } /* ── Loading Spinner ── */ .spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid transparent; border-top-color: #000; border-right-color: #000; animation: spin 0.6s linear infinite; margin-right: 8px; vertical-align: middle; } @keyframes spin { to { transform: rotate(360deg); } } /* ── Password toggle ── */ .password-wrapper { position: relative; } .password-wrapper input { padding-right: 40px; } .password-toggle { position: absolute; right: 1px; top: 1px; bottom: 1px; width: 36px; background: var(--bg-input); border: none; border-left: 1px solid var(--dimmer); color: var(--dim); cursor: pointer; font-family: var(--font); font-size: 0.7rem; transition: color 0.15s; } .password-toggle:hover { color: var(--cyan); } /* ── File input ── */ .file-input-wrapper { position: relative; overflow: hidden; } .file-input-wrapper input[type="file"] { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; } /* ── Responsive ── */ @media (max-width: 900px) { .main-grid { grid-template-columns: 1fr; min-height: auto; } .panel { border-right: none; border-bottom: 1px solid var(--dimmer); } .settings-panel { width: calc(100% - 48px); right: 24px; left: 24px; } .history-scroll { flex-direction: column; } .history-tile { min-width: auto; max-width: none; } } @media (max-width: 480px) { .header { padding: 10px 12px; } .header-title { font-size: 1rem; letter-spacing: 2px; } .panel { padding: 12px; } .history-strip { padding: 12px; } } /* ── Fade-in animation ── */ @keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fade-in 0.3s ease; } /* ── Pulse for active generation ── */ @keyframes pulse-border { 0%, 100% { border-color: var(--cyan); } 50% { border-color: var(--green); } } .pulse-border { animation: pulse-border 1.5s ease infinite; } /* ── Modal Overlay ── */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.85); backdrop-filter: blur(4px); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 16px; } .modal-card { background: var(--bg-secondary); border: 1px solid var(--cyan); box-shadow: var(--glow-cyan), 0 10px 40px rgba(0, 0, 0, 0.9); width: 100%; max-width: 560px; padding: 20px; } .modal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--dimmer); } .modal-header h3 { font-size: 0.85rem; color: var(--cyan); text-transform: uppercase; letter-spacing: 2px; } .sql-textarea { font-family: var(--font); font-size: 0.65rem; line-height: 1.5; color: var(--green); background: #050505; border: 1px solid var(--dimmer); padding: 10px; resize: vertical; }