Liveweave: Generative AI Web Editor & HTML/CSS/JS Playground
Initializing
Liveweave
Web
expand_more
home
Home
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
frame_source
Python Playground
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Fork
account_circle
Login
settings
Settings
expand_more
Editor font
14
px
A
A
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
left_panel_close
AI Assistant
dashboard
All
HTML
CSS
JS
visibility
Preview
bolt
Live Preview
terminal
JS Console
<!DOCTYPE html> <html> <head> <title>Background design playground</title> </head> <body> <!-- Start your code here --> <div class="chroma-app" id="chromaApp"> <a class="skip-link" href="#workspaceMain">Skip to workspace</a> <!-- SIDEBAR --> <aside class="chroma-sidebar" aria-label="Visual effects controls"> <div class="sidebar-brand"> <div class="brand-icon" aria-hidden="true">◈</div> <div> <strong>CHROMA</strong> <span>VISUAL LAB / 02</span> </div> </div> <div class="sidebar-scroll"> <div class="sidebar-label">WORKSPACE</div> <div class="sidebar-nav" aria-label="Workspace mode"> <button class="side-tab active" id="imagesTab" type="button" data-tab="images" aria-pressed="true" > <span class="tab-icon" aria-hidden="true">▦</span> <span>Image Effects</span> <span class="tab-check" aria-hidden="true">✓</span> </button> <button class="side-tab" id="gradientsTab" type="button" data-tab="gradients" aria-pressed="false" > <span class="tab-icon" aria-hidden="true">◉</span> <span>Gradient Studio</span> <span class="tab-check" aria-hidden="true">✓</span> </button> </div> <!-- IMAGE CONTROLS --> <section class="control-panel active" id="imagesPanel" aria-labelledby="imagesTab" > <div class="control-heading"> <span>01</span> <h2>Choose an image</h2> </div> <div class="image-presets" role="group" aria-label="Background images"> <button class="image-choice active" type="button" data-image="mountain" aria-pressed="true" > <img src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=320&q=75" alt="" > <span class="choice-name">Mountains</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="image-choice" type="button" data-image="desert" aria-pressed="false" > <img src="https://images.unsplash.com/photo-1509316785289-025f5b846b35?w=320&q=75" alt="" > <span class="choice-name">Desert</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="image-choice" type="button" data-image="architecture" aria-pressed="false" > <img src="https://images.unsplash.com/photo-1487958449943-2429e8be8625?w=320&q=75" alt="" > <span class="choice-name">Architecture</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="image-choice" type="button" data-image="forest" aria-pressed="false" > <img src="https://images.unsplash.com/photo-1448375240586-882707db888b?w=320&q=75" alt="" > <span class="choice-name">Forest</span> <span class="choice-check" aria-hidden="true">✓</span> </button> </div> <div class="control-divider"></div> <div class="control-heading"> <span>02</span> <h2>Photo treatments</h2> </div> <div class="filter-grid" role="group" aria-label="Photo filters"> <button class="filter-choice active" type="button" data-filter="normal" aria-pressed="true">Original</button> <button class="filter-choice" type="button" data-filter="mono" aria-pressed="false">Monochrome</button> <button class="filter-choice" type="button" data-filter="vintage" aria-pressed="false">Vintage</button> <button class="filter-choice" type="button" data-filter="cinematic" aria-pressed="false">Cinematic</button> <button class="filter-choice" type="button" data-filter="dream" aria-pressed="false">Dreamy</button> <button class="filter-choice" type="button" data-filter="dramatic" aria-pressed="false">Dramatic</button> </div> <div class="control-divider"></div> <div class="control-heading"> <span>03</span> <h2>Adjustments</h2> </div> <div class="slider-control"> <div class="slider-top"> <label for="brightnessRange">Brightness</label> <output for="brightnessRange" id="brightnessValue">100%</output> </div> <input type="range" id="brightnessRange" min="30" max="170" value="100"> </div> <div class="slider-control"> <div class="slider-top"> <label for="contrastRange">Contrast</label> <output for="contrastRange" id="contrastValue">100%</output> </div> <input type="range" id="contrastRange" min="50" max="200" value="100"> </div> <div class="slider-control"> <div class="slider-top"> <label for="imageSaturationRange">Saturation</label> <output for="imageSaturationRange" id="imageSaturationValue">100%</output> </div> <input type="range" id="imageSaturationRange" min="0" max="200" value="100"> </div> <div class="slider-control"> <div class="slider-top"> <label for="imageBlurRange">Blur</label> <output for="imageBlurRange" id="imageBlurValue">0px</output> </div> <input type="range" id="imageBlurRange" min="0" max="20" value="0"> </div> <button class="reset-button" id="resetImageButton" type="button"> Reset image adjustments </button> </section> <!-- GRADIENT CONTROLS --> <section class="control-panel" id="gradientsPanel" aria-labelledby="gradientsTab" hidden > <div class="control-heading"> <span>01</span> <h2>Gradient presets</h2> </div> <div class="preset-grid" role="group" aria-label="Gradient presets"> <button class="preset active" type="button" data-preset="aurora" aria-pressed="true"> <span class="preset-preview aurora"></span> <span class="preset-name">Aurora</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="sunset" aria-pressed="false"> <span class="preset-preview sunset"></span> <span class="preset-name">Sunset</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="ocean" aria-pressed="false"> <span class="preset-preview ocean"></span> <span class="preset-name">Ocean</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="neon" aria-pressed="false"> <span class="preset-preview neon"></span> <span class="preset-name">Neon</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="mesh" aria-pressed="false"> <span class="preset-preview mesh"></span> <span class="preset-name">Mesh</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="midnight" aria-pressed="false"> <span class="preset-preview midnight"></span> <span class="preset-name">Midnight</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="candy" aria-pressed="false"> <span class="preset-preview candy"></span> <span class="preset-name">Candy</span> <span class="choice-check" aria-hidden="true">✓</span> </button> <button class="preset" type="button" data-preset="forest" aria-pressed="false"> <span class="preset-preview forest"></span> <span class="preset-name">Forest</span> <span class="choice-check" aria-hidden="true">✓</span> </button> </div> <div class="control-divider"></div> <div class="control-heading"> <span>02</span> <h2>Fine tune</h2> </div> <div class="slider-control"> <div class="slider-top"> <label for="angleRange">Gradient angle</label> <output for="angleRange" id="angleValue">135°</output> </div> <input type="range" id="angleRange" min="0" max="360" value="135"> </div> <div class="slider-control"> <div class="slider-top"> <label for="blurRange">Softness</label> <output for="blurRange" id="blurValue">0px</output> </div> <input type="range" id="blurRange" min="0" max="60" value="0"> </div> <div class="slider-control"> <div class="slider-top"> <label for="saturationRange">Saturation</label> <output for="saturationRange" id="saturationValue">100%</output> </div> <input type="range" id="saturationRange" min="0" max="200" value="100"> </div> <div class="slider-control"> <div class="slider-top"> <label for="speedRange">Animation speed</label> <output for="speedRange" id="speedValue">12s</output> </div> <input type="range" id="speedRange" min="3" max="40" value="12"> </div> <div class="control-divider"></div> <div class="control-heading"> <span>03</span> <h2>Colors</h2> </div> <div class="color-inputs"> <label> <span>Color 01</span> <input type="color" id="colorOne" value="#7c3aed"> </label> <label> <span>Color 02</span> <input type="color" id="colorTwo" value="#06b6d4"> </label> <label> <span>Color 03</span> <input type="color" id="colorThree" value="#f472b6"> </label> </div> </section> </div> <div class="sidebar-footer"> <span class="status-dot" aria-hidden="true"></span> READY TO CREATE </div> </aside> <!-- MAIN WORKSPACE --> <main class="chroma-main" id="workspaceMain"> <header class="workspace-header"> <div> <span class="workspace-kicker">CREATIVE WORKSPACE</span> <h1>Background Playground<span>.</span></h1> <p class="workspace-description"> Experiment with color, photography, and atmosphere. </p> </div> <div class="header-actions"> <button class="action-btn secondary" id="randomButton" type="button"> <span aria-hidden="true">↻</span> Randomize </button> <button class="action-btn primary" id="copyButton" type="button"> Copy CSS <span aria-hidden="true">↗</span> </button> </div> </header> <!-- TOOLBAR --> <div class="workspace-toolbar"> <div class="toolbar-left"> <span class="live-indicator" aria-hidden="true"></span> <span>LIVE PREVIEW</span> <span class="toolbar-divider" aria-hidden="true"></span> <span id="activePresetLabel">MOUNTAINS / ORIGINAL</span> </div> <div class="toolbar-right"> <label class="toggle-label" for="animateToggle"> <span>Animate</span> <input type="checkbox" id="animateToggle" checked> <span class="toggle-track" aria-hidden="true"></span> <span class="toggle-state" id="animateState">On</span> </label> <label class="toggle-label" for="glassToggle"> <span>Glass</span> <input type="checkbox" id="glassToggle" checked> <span class="toggle-track" aria-hidden="true"></span> <span class="toggle-state" id="glassState">On</span> </label> </div> </div> <!-- PREVIEW --> <div class="preview-shell"> <div class="preview-canvas" id="previewCanvas" role="img" aria-label="Live visual preview with a mountain background and decorative typography" > <div class="background-layer" id="backgroundLayer"></div> <div class="preview-overlay"></div> <div class="preview-grid"></div> <div class="preview-content"> <div class="preview-topline"> <span>CHROMA / EXPERIMENT 001</span> <span>DESIGNED IN REAL TIME</span> </div> <div class="preview-center"> <div class="preview-badge"> <span class="badge-star" aria-hidden="true">✳</span> YOUR CANVAS. YOUR RULES. </div> <h2> MAKE<br> <em>WAVES.</em> </h2> <p> An infinite canvas for beautiful ideas. Play with color, light, and atmosphere. </p> <button class="preview-cta" id="previewExplore" type="button"> EXPLORE MORE <span aria-hidden="true">↗</span> </button> </div> <div class="preview-bottomline"> <span>01 / VISUAL EXPERIMENTS</span> <span>CREATE SOMETHING NEW</span> </div> </div> <div class="glass-card visible" id="glassCard"> <span class="glass-card-icon" aria-hidden="true">✦</span> <span>CREATIVE FREQUENCY</span> <strong>100%</strong> <small>IMAGINATION ACTIVATED</small> </div> </div> </div> <!-- INFORMATION CARDS --> <div class="workspace-bottom"> <div class="info-card"> <span>ACTIVE EFFECT</span> <strong id="effectName">Original Photo Effect</strong> </div> <div class="info-card"> <span>RENDERING</span> <strong>CSS / GPU</strong> </div> <div class="info-card"> <span>FORMAT</span> <strong>RESPONSIVE</strong> </div> <div class="workspace-note"> <span aria-hidden="true">✳</span> Every background begins with an idea. </div> </div> </main> <!-- SCREEN READER ANNOUNCEMENTS --> <div class="sr-only" id="liveStatus" role="status" aria-live="polite"></div> <!-- TOAST --> <div class="chroma-toast" id="chromaToast" aria-hidden="true"> CSS copied to clipboard </div> </div> <!-- End your code here --> </body> </html>
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800;900&family=IBM+Plex+Mono:wght@400;500;600&display=swap'); :root { color-scheme: dark; --bg: #0d1016; --sidebar: #171b24; --surface: #1d2330; --surface-hover: #30394a; --surface-selected: #344234; --border: #667085; --border-soft: #465063; --text: #ffffff; --text-secondary: #e0e6f0; --text-muted: #bac4d3; --accent: #d7ff75; --accent-text: #10180a; --focus: #ffe08a; --radius: 10px; } /* GLOBAL */ * { box-sizing: border-box; } html { scroll-behavior: smooth; } body { margin: 0; min-height: 100vh; background: var(--bg); color: var(--text); font-family: 'Outfit', sans-serif; font-size: 14px; line-height: 1.5; } button, input { font: inherit; } button { cursor: pointer; } button:focus-visible, input:focus-visible, a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; } button:disabled { opacity: .55; cursor: not-allowed; } [hidden] { display: none !important; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .skip-link { position: fixed; top: -100px; left: 20px; z-index: 1000; padding: 14px 20px; background: var(--accent); color: var(--accent-text); font-weight: 800; border-radius: 8px; } .skip-link:focus { top: 20px; } /* APPLICATION */ .chroma-app { display: grid; grid-template-columns: 320px minmax(0, 1fr); min-height: 100vh; } /* SIDEBAR */ .chroma-sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; min-width: 0; background: var(--sidebar); border-right: 1px solid var(--border-soft); } .sidebar-brand { display: flex; align-items: center; gap: 14px; padding: 26px 24px; border-bottom: 1px solid var(--border-soft); } .brand-icon { display: grid; place-items: center; width: 46px; height: 46px; flex-shrink: 0; background: var(--accent); color: var(--accent-text); border-radius: 12px; font-size: 29px; } .sidebar-brand strong { display: block; color: var(--text); font-size: 20px; font-weight: 900; letter-spacing: 2px; } .sidebar-brand span { display: block; margin-top: 2px; color: var(--text-muted); font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: 1px; } .sidebar-scroll { flex: 1; overflow-y: auto; padding: 26px 20px; } .sidebar-label { margin-bottom: 14px; color: var(--text-muted); font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600; letter-spacing: 1.5px; } /* NAVIGATION */ .sidebar-nav { display: flex; flex-direction: column; gap: 8px; margin-bottom: 34px; } .side-tab { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-secondary); text-align: left; font-size: 14px; font-weight: 600; transition: background .2s, border-color .2s; } .side-tab:hover { background: var(--surface-hover); border-color: #a3b0c2; } .side-tab.active { background: var(--surface-selected); border: 2px solid var(--accent); color: var(--text); } .tab-icon { font-size: 20px; line-height: 1; } .tab-check { display: none; margin-left: auto; color: var(--accent); font-size: 18px; font-weight: 900; } .side-tab.active .tab-check { display: inline; } /* CONTROL PANELS */ .control-panel { display: none; } .control-panel.active { display: block; } .control-heading { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; } .control-heading > span { color: var(--accent); font-family: 'IBM Plex Mono', monospace; font-size: 12px; font-weight: 600; } .control-heading h2 { margin: 0; color: var(--text); font-size: 15px; font-weight: 700; } .control-divider { height: 1px; margin: 30px 0; background: var(--border-soft); } /* IMAGE CHOICES */ .image-presets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } .image-choice { position: relative; min-width: 0; padding: 7px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text-secondary); text-align: left; transition: background .2s, border-color .2s; } .image-choice:hover { background: var(--surface-hover); border-color: #a3b0c2; } .image-choice.active { border: 2px solid var(--accent); padding: 6px; background: var(--surface-selected); color: var(--text); } .image-choice img { display: block; width: 100%; height: 82px; object-fit: cover; border-radius: 6px; } .choice-name, .preset-name { display: block; padding: 9px 4px 4px; font-size: 12px; font-weight: 600; } .choice-check { display: none; position: absolute; top: 12px; right: 12px; width: 26px; height: 26px; border-radius: 50%; background: var(--accent); color: var(--accent-text); text-align: center; line-height: 26px; font-size: 15px; font-weight: 900; box-shadow: 0 2px 8px #0008; } .image-choice.active .choice-check, .preset.active .choice-check { display: block; } /* FILTER BUTTONS */ .filter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; } .filter-choice { min-height: 46px; padding: 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text-secondary); font-size: 12px; font-weight: 600; transition: background .2s; } .filter-choice:hover { background: var(--surface-hover); border-color: #a3b0c2; } .filter-choice.active { background: var(--accent); color: var(--accent-text); border: 2px solid var(--accent); font-weight: 800; } .filter-choice.active::before { content: "\2713"; margin-right: 6px; } /* SLIDERS */ .slider-control { margin-bottom: 25px; } .slider-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 13px; } .slider-top label { color: var(--text-secondary); font-size: 13px; font-weight: 600; } .slider-top output { min-width: 48px; padding: 4px 7px; border: 1px solid #697784; border-radius: 5px; background: #2b3441; color: var(--accent); font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600; text-align: center; } input[type="range"] { display: block; width: 100%; height: 24px; margin: 0; appearance: none; -webkit-appearance: none; background: transparent; cursor: pointer; } input[type="range"]::-webkit-slider-runnable-track { height: 8px; border-radius: 10px; background: #8e9bae; } input[type="range"]::-moz-range-track { height: 8px; border-radius: 10px; background: #8e9bae; } input[type="range"]::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; width: 22px; height: 22px; margin-top: -7px; border: 3px solid #172016; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px #ffffff; } input[type="range"]::-moz-range-thumb { width: 17px; height: 17px; border: 3px solid #172016; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px #ffffff; } /* RESET BUTTON */ .reset-button { width: 100%; min-height: 44px; margin-top: 5px; padding: 10px; border: 1px solid #b5c1d1; border-radius: 8px; background: transparent; color: var(--text); font-size: 12px; font-weight: 700; } .reset-button:hover { background: var(--surface-hover); } /* GRADIENT PRESETS */ .preset-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; } .preset { position: relative; padding: 7px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text-secondary); text-align: left; } .preset:hover { background: var(--surface-hover); border-color: #a3b0c2; } .preset.active { padding: 6px; border: 2px solid var(--accent); background: var(--surface-selected); color: var(--text); } .preset-preview { display: block; height: 65px; border-radius: 6px; } .aurora { background: linear-gradient(135deg, #7c3aed, #06b6d4, #f472b6); } .sunset { background: linear-gradient(135deg, #ff512f, #f09819, #ffcf71); } .ocean { background: linear-gradient(135deg, #020024, #00c6ff, #0072ff); } .neon { background: linear-gradient(135deg, #090909, #b400ff, #00ffd5); } .mesh { background: radial-gradient(at 20% 30%, #ff7eb3, transparent 50%), radial-gradient(at 80% 20%, #7afcff, transparent 50%), radial-gradient(at 50% 90%, #feff9c, transparent 50%), #b4a0ff; } .midnight { background: linear-gradient(135deg, #0f0c29, #302b63, #24243e); } .candy { background: linear-gradient(135deg, #ff9a9e, #fad0c4, #fbc2eb); } .forest { background: linear-gradient(135deg, #134e5e, #71b280, #b6e3a0); } /* COLOR INPUTS */ .color-inputs { display: flex; gap: 12px; } .color-inputs label { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 9px; color: var(--text-secondary); font-size: 11px; font-weight: 600; } .color-inputs input { width: 100%; height: 46px; padding: 4px; border: 1px solid #a6b2c2; border-radius: 8px; background: #2b3441; cursor: pointer; } /* FOOTER */ .sidebar-footer { padding: 19px 24px; border-top: 1px solid var(--border-soft); color: var(--text-secondary); font-family: 'IBM Plex Mono', monospace; font-size: 10px; font-weight: 600; letter-spacing: 1px; } .status-dot { display: inline-block; width: 9px; height: 9px; margin-right: 8px; border-radius: 50%; background: var(--accent); } /* MAIN */ .chroma-main { min-width: 0; padding: 40px; } .workspace-header { display: flex; justify-content: space-between; align-items: center; gap: 25px; margin-bottom: 32px; } .workspace-kicker { color: var(--accent); font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600; letter-spacing: 2px; } .workspace-header h1 { margin: 10px 0 5px; font-size: clamp(30px, 3vw, 48px); font-weight: 800; letter-spacing: -2px; line-height: 1.2; } .workspace-header h1 span { color: var(--accent); } .workspace-description { margin: 0; color: var(--text-muted); font-size: 13px; } .header-actions { display: flex; gap: 10px; } .action-btn { min-height: 46px; padding: 12px 19px; border-radius: 8px; font-size: 13px; font-weight: 700; white-space: nowrap; } .action-btn.secondary { border: 1px solid #a3b0c2; background: var(--surface); color: var(--text); } .action-btn.secondary:hover { background: var(--surface-hover); } .action-btn.primary { border: 2px solid var(--accent); background: var(--accent); color: var(--accent-text); } .action-btn.primary:hover { background: #e7ffad; } .action-btn span { margin-right: 6px; } /* TOOLBAR */ .workspace-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px; margin-bottom: 15px; } .toolbar-left, .toolbar-right { display: flex; align-items: center; gap: 13px; color: var(--text-secondary); font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600; letter-spacing: .4px; } .live-indicator { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 10px #d7ff7566; } .toolbar-divider { width: 1px; height: 16px; background: var(--border); } /* ACCESSIBLE TOGGLES */ .toggle-label { display: flex; align-items: center; gap: 9px; min-height: 44px; cursor: pointer; color: var(--text); font-size: 11px; } .toggle-label input { position: absolute; width: 1px; height: 1px; opacity: 0; } .toggle-track { position: relative; width: 40px; height: 23px; border: 2px solid #b8c3d1; border-radius: 20px; background: #354052; transition: background .2s; } .toggle-track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 13px; height: 13px; border-radius: 50%; background: #ffffff; transition: transform .2s; } .toggle-label input:checked + .toggle-track { background: var(--accent); border-color: var(--accent); } .toggle-label input:checked + .toggle-track::after { transform: translateX(17px); background: #172016; } .toggle-label input:focus-visible + .toggle-track { outline: 3px solid var(--focus); outline-offset: 4px; } .toggle-state { min-width: 23px; color: var(--text-secondary); } /* PREVIEW */ .preview-shell { padding: 9px; border: 1px solid var(--border-soft); border-radius: 18px; background: var(--surface); } .preview-canvas { position: relative; isolation: isolate; overflow: hidden; min-height: 480px; height: min(690px, 72vh); border-radius: 11px; background: #253447; color: #ffffff; } .background-layer { position: absolute; inset: -70px; z-index: -3; background-image: url('https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1600&q=85'); background-size: cover; background-position: center; transition: filter .25s ease; } .background-layer.gradient-active { background-size: 300% 300%; animation: chromaFlow 12s ease-in-out infinite alternate; } @keyframes chromaFlow { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 20% 100%; } } /* TEXT READABILITY OVERLAY */ .preview-overlay { position: absolute; inset: 0; z-index: -2; pointer-events: none; background: linear-gradient( 90deg, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .55) 45%, rgba(0, 0, 0, .22) 100% ); } .preview-grid { position: absolute; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(#ffffff0d 1px, transparent 1px), linear-gradient(90deg, #ffffff0d 1px, transparent 1px); background-size: 65px 65px; } /* PREVIEW CONTENT */ .preview-content { position: relative; z-index: 2; display: flex; flex-direction: column; justify-content: space-between; height: 100%; padding: 40px 6%; } .preview-topline, .preview-bottomline { display: flex; justify-content: space-between; gap: 20px; color: #ffffff; font-family: 'IBM Plex Mono', monospace; font-size: 10px; font-weight: 600; letter-spacing: 1.5px; text-shadow: 0 2px 10px #000; } .preview-center { max-width: 680px; } .preview-badge { display: inline-flex; align-items: center; gap: 12px; padding: 10px 15px; border: 1px solid #ffffff; border-radius: 30px; background: #000000a6; color: #ffffff; font-size: 11px; font-weight: 700; letter-spacing: .5px; } .badge-star { font-size: 20px; } .preview-center h2 { margin: 28px 0 20px; color: #ffffff; font-size: clamp(85px, 10vw, 170px); font-weight: 900; letter-spacing: -.09em; line-height: .85; text-shadow: 0 5px 30px #000b; } .preview-center h2 em { font-style: normal; color: #ffffff; -webkit-text-stroke: 0; } .preview-center p { max-width: 420px; color: #ffffff; font-size: 16px; font-weight: 500; line-height: 1.7; text-shadow: 0 2px 12px #000; } .preview-cta { min-height: 48px; margin-top: 20px; padding: 14px 22px; border: 2px solid #ffffff; border-radius: 6px; background: #ffffff; color: #101010; font-size: 12px; font-weight: 900; letter-spacing: .5px; } .preview-cta:hover { background: #e5f1ff; } .preview-cta span { margin-left: 20px; } /* GLASS CARD */ .glass-card { position: absolute; right: 5%; bottom: 18%; z-index: 3; display: none; flex-direction: column; width: 205px; min-height: 190px; padding: 22px; border: 1px solid #ffffffb3; border-radius: 15px; background: rgba(8, 14, 23, .78); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); color: #ffffff; box-shadow: 0 15px 40px #0005; } .glass-card.visible { display: flex; } .glass-card-icon { margin-bottom: 15px; font-size: 34px; } .glass-card > span:nth-child(2) { font-size: 10px; font-weight: 700; letter-spacing: 1px; } .glass-card strong { margin-top: 5px; font-size: 42px; letter-spacing: -3px; } .glass-card small { color: #ffffff; font-family: 'IBM Plex Mono', monospace; font-size: 9px; font-weight: 600; letter-spacing: .5px; } /* BOTTOM INFORMATION */ .workspace-bottom { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) 1.3fr; gap: 12px; margin-top: 18px; } .info-card, .workspace-note { min-width: 0; padding: 20px; border: 1px solid var(--border-soft); border-radius: 10px; background: var(--sidebar); } .info-card span { display: block; color: var(--text-muted); font-family: 'IBM Plex Mono', monospace; font-size: 10px; font-weight: 600; letter-spacing: .7px; } .info-card strong { display: block; margin-top: 10px; color: var(--text); font-size: 14px; font-weight: 700; } .workspace-note { display: flex; align-items: center; gap: 14px; color: var(--text-secondary); font-size: 13px; font-weight: 500; } .workspace-note span { color: var(--accent); font-size: 30px; } /* TOAST */ .chroma-toast { position: fixed; bottom: 30px; left: 50%; z-index: 100; padding: 15px 25px; border: 2px solid var(--accent); border-radius: 8px; background: #24301e; color: #ffffff; font-size: 13px; font-weight: 700; opacity: 0; pointer-events: none; transform: translate(-50%, 20px); transition: opacity .2s, transform .2s; } .chroma-toast.show { opacity: 1; transform: translate(-50%, 0); } /* RESPONSIVE */ @media (max-width: 1200px) { .chroma-app { grid-template-columns: 280px minmax(0, 1fr); } .chroma-main { padding: 25px; } .workspace-bottom { grid-template-columns: repeat(3, 1fr); } .workspace-note { grid-column: 1 / -1; } } @media (max-width: 900px) { .chroma-app { grid-template-columns: 1fr; } .chroma-sidebar { position: relative; height: auto; border-right: 0; border-bottom: 1px solid var(--border-soft); } .sidebar-scroll { overflow: visible; } .preset-grid { grid-template-columns: repeat(4, 1fr); } } @media (max-width: 650px) { .chroma-main { padding: 16px; } .workspace-header { flex-direction: column; align-items: flex-start; } .workspace-header h1 { font-size: 32px; } .header-actions { width: 100%; } .action-btn { flex: 1; } .workspace-toolbar { align-items: flex-start; } .preview-canvas { min-height: 590px; height: 590px; } .preview-content { padding: 24px; } .preview-center h2 { font-size: clamp(62px, 15vw, 90px); } .preview-topline, .preview-bottomline { font-size: 9px; letter-spacing: .4px; } .glass-card { right: 18px; bottom: 70px; width: 145px; min-height: 130px; padding: 14px; } .glass-card strong { font-size: 30px; } .workspace-bottom { grid-template-columns: 1fr 1fr; } .workspace-note { grid-column: 1 / -1; } .preset-grid { grid-template-columns: repeat(2, 1fr); } } /* REDUCED MOTION */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; } }
(function () { var root = document.getElementById("chromaApp"); if (!root) return; var backgroundLayer = document.getElementById("backgroundLayer"); var previewCanvas = document.getElementById("previewCanvas"); var activePresetLabel = document.getElementById("activePresetLabel"); var effectName = document.getElementById("effectName"); var liveStatus = document.getElementById("liveStatus"); var toast = document.getElementById("chromaToast"); var angleRange = document.getElementById("angleRange"); var blurRange = document.getElementById("blurRange"); var saturationRange = document.getElementById("saturationRange"); var speedRange = document.getElementById("speedRange"); var colorOne = document.getElementById("colorOne"); var colorTwo = document.getElementById("colorTwo"); var colorThree = document.getElementById("colorThree"); var brightnessRange = document.getElementById("brightnessRange"); var contrastRange = document.getElementById("contrastRange"); var imageSaturationRange = document.getElementById("imageSaturationRange"); var imageBlurRange = document.getElementById("imageBlurRange"); var animateToggle = document.getElementById("animateToggle"); var glassToggle = document.getElementById("glassToggle"); var glassCard = document.getElementById("glassCard"); var currentTab = "images"; var currentPreset = "aurora"; var currentImage = "mountain"; var currentFilter = "normal"; var presets = { aurora: ["#7c3aed", "#06b6d4", "#f472b6"], sunset: ["#ff512f", "#f09819", "#ffcf71"], ocean: ["#020024", "#00c6ff", "#0072ff"], neon: ["#090909", "#b400ff", "#00ffd5"], mesh: ["#ff7eb3", "#7afcff", "#feff9c"], midnight: ["#0f0c29", "#302b63", "#24243e"], candy: ["#ff9a9e", "#fad0c4", "#fbc2eb"], forest: ["#134e5e", "#71b280", "#b6e3a0"] }; var images = { mountain: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1600&q=85", desert: "https://images.unsplash.com/photo-1509316785289-025f5b846b35?w=1600&q=85", architecture: "https://images.unsplash.com/photo-1487958449943-2429e8be8625?w=1600&q=85", forest: "https://images.unsplash.com/photo-1448375240586-882707db888b?w=1600&q=85" }; var filters = { normal: "none", mono: "grayscale(1)", vintage: "sepia(.65) saturate(.75)", cinematic: "contrast(1.3) saturate(.7) brightness(.85)", dream: "saturate(1.4) blur(2px) brightness(1.12)", dramatic: "contrast(1.6) saturate(1.4)" }; var reducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)" ); function titleCase(value) { return value.charAt(0).toUpperCase() + value.slice(1); } function announce(message) { liveStatus.textContent = ""; window.setTimeout(function () { liveStatus.textContent = message; }, 30); } function updateSelection(selector, attribute, selectedValue) { root.querySelectorAll(selector).forEach(function (button) { var active = button.getAttribute(attribute) === selectedValue; button.classList.toggle("active", active); button.setAttribute("aria-pressed", active ? "true" : "false"); }); } function getGradient() { return "linear-gradient(" + angleRange.value + "deg, " + colorOne.value + ", " + colorTwo.value + ", " + colorThree.value + ")"; } function getImageFilter() { var filter = filters[currentFilter]; if (filter === "none") filter = ""; return filter + " brightness(" + brightnessRange.value + "%)" + " contrast(" + contrastRange.value + "%)" + " saturate(" + imageSaturationRange.value + "%)" + " blur(" + imageBlurRange.value + "px)"; } function updateLabels() { document.getElementById("angleValue").textContent = angleRange.value + "\u00B0"; document.getElementById("blurValue").textContent = blurRange.value + "px"; document.getElementById("saturationValue").textContent = saturationRange.value + "%"; document.getElementById("speedValue").textContent = speedRange.value + "s"; document.getElementById("brightnessValue").textContent = brightnessRange.value + "%"; document.getElementById("contrastValue").textContent = contrastRange.value + "%"; document.getElementById("imageSaturationValue").textContent = imageSaturationRange.value + "%"; document.getElementById("imageBlurValue").textContent = imageBlurRange.value + "px"; document.getElementById("animateState").textContent = animateToggle.checked ? "On" : "Off"; document.getElementById("glassState").textContent = glassToggle.checked ? "On" : "Off"; } function updatePreview() { updateLabels(); if (currentTab === "gradients") { backgroundLayer.classList.add("gradient-active"); backgroundLayer.style.backgroundImage = getGradient(); backgroundLayer.style.backgroundSize = "300% 300%"; backgroundLayer.style.filter = "blur(" + blurRange.value + "px) " + "saturate(" + saturationRange.value + "%)"; backgroundLayer.style.animationDuration = speedRange.value + "s"; backgroundLayer.style.animationPlayState = animateToggle.checked && !reducedMotion.matches ? "running" : "paused"; activePresetLabel.textContent = currentPreset.toUpperCase() + " GRADIENT"; effectName.textContent = titleCase(currentPreset) + " Gradient"; previewCanvas.setAttribute( "aria-label", "Live visual preview showing the " + currentPreset + " gradient" ); } else { backgroundLayer.classList.remove("gradient-active"); backgroundLayer.style.backgroundImage = 'url("' + images[currentImage] + '")'; backgroundLayer.style.backgroundSize = "cover"; backgroundLayer.style.backgroundPosition = "center"; backgroundLayer.style.filter = getImageFilter(); backgroundLayer.style.animationPlayState = "paused"; activePresetLabel.textContent = currentImage.toUpperCase() + " / " + currentFilter.toUpperCase(); effectName.textContent = titleCase(currentFilter) + " Photo Effect"; previewCanvas.setAttribute( "aria-label", "Live visual preview showing the " + currentImage + " photograph with " + currentFilter + " filter" ); } glassCard.classList.toggle("visible", glassToggle.checked); glassCard.hidden = !glassToggle.checked; } // WORKSPACE SELECTION root.querySelectorAll(".side-tab").forEach(function (button) { button.addEventListener("click", function () { currentTab = button.getAttribute("data-tab"); updateSelection(".side-tab", "data-tab", currentTab); var imagesPanel = document.getElementById("imagesPanel"); var gradientsPanel = document.getElementById("gradientsPanel"); imagesPanel.hidden = currentTab !== "images"; gradientsPanel.hidden = currentTab !== "gradients"; imagesPanel.classList.toggle( "active", currentTab === "images" ); gradientsPanel.classList.toggle( "active", currentTab === "gradients" ); updatePreview(); announce( currentTab === "images" ? "Image Effects workspace selected" : "Gradient Studio workspace selected" ); }); }); // IMAGE SELECTION root.querySelectorAll(".image-choice").forEach(function (button) { button.addEventListener("click", function () { currentImage = button.getAttribute("data-image"); updateSelection( ".image-choice", "data-image", currentImage ); updatePreview(); announce(titleCase(currentImage) + " image selected"); }); }); // PHOTO FILTERS root.querySelectorAll(".filter-choice").forEach(function (button) { button.addEventListener("click", function () { currentFilter = button.getAttribute("data-filter"); updateSelection( ".filter-choice", "data-filter", currentFilter ); updatePreview(); announce(titleCase(currentFilter) + " filter selected"); }); }); // IMAGE SLIDERS [ brightnessRange, contrastRange, imageSaturationRange, imageBlurRange ].forEach(function (input) { input.addEventListener("input", updatePreview); }); // RESET IMAGE ADJUSTMENTS document.getElementById("resetImageButton").addEventListener( "click", function () { brightnessRange.value = 100; contrastRange.value = 100; imageSaturationRange.value = 100; imageBlurRange.value = 0; currentFilter = "normal"; updateSelection( ".filter-choice", "data-filter", currentFilter ); updatePreview(); announce("Image adjustments reset"); } ); // GRADIENT PRESETS root.querySelectorAll(".preset").forEach(function (button) { button.addEventListener("click", function () { currentPreset = button.getAttribute("data-preset"); var colors = presets[currentPreset]; colorOne.value = colors[0]; colorTwo.value = colors[1]; colorThree.value = colors[2]; updateSelection( ".preset", "data-preset", currentPreset ); updatePreview(); announce(titleCase(currentPreset) + " gradient selected"); }); }); // CUSTOM COLORS [colorOne, colorTwo, colorThree].forEach(function (input) { input.addEventListener("input", function () { currentPreset = "custom"; updateSelection( ".preset", "data-preset", currentPreset ); updatePreview(); }); }); // GRADIENT SLIDERS [ angleRange, blurRange, saturationRange, speedRange ].forEach(function (input) { input.addEventListener("input", updatePreview); }); // TOGGLES animateToggle.addEventListener("change", function () { updatePreview(); announce( animateToggle.checked ? "Animation enabled" : "Animation disabled" ); }); glassToggle.addEventListener("change", function () { updatePreview(); announce( glassToggle.checked ? "Glass overlay enabled" : "Glass overlay disabled" ); }); // RANDOMIZE document.getElementById("randomButton").addEventListener( "click", function () { if (currentTab === "gradients") { function randomColor() { return "#" + Math.floor(Math.random() * 16777215) .toString(16) .padStart(6, "0"); } colorOne.value = randomColor(); colorTwo.value = randomColor(); colorThree.value = randomColor(); angleRange.value = Math.floor(Math.random() * 361); currentPreset = "custom"; updateSelection( ".preset", "data-preset", currentPreset ); } else { var imageKeys = Object.keys(images); var filterKeys = Object.keys(filters); currentImage = imageKeys[ Math.floor(Math.random() * imageKeys.length) ]; currentFilter = filterKeys[ Math.floor(Math.random() * filterKeys.length) ]; updateSelection( ".image-choice", "data-image", currentImage ); updateSelection( ".filter-choice", "data-filter", currentFilter ); } updatePreview(); announce("New visual combination generated"); } ); // BUILD CSS function buildCSS() { var css = ".my-background {\n"; if (currentTab === "gradients") { css += " background: " + getGradient() + ";\n"; css += " background-size: 300% 300%;\n"; css += " filter: blur(" + blurRange.value + "px) "; css += "saturate(" + saturationRange.value + "%);\n"; if (animateToggle.checked) { css += " animation: chromaFlow " + speedRange.value + "s ease-in-out infinite alternate;\n"; } } else { css += ' background-image: url("' + images[currentImage] + '");\n'; css += " background-size: cover;\n"; css += " background-position: center;\n"; css += " filter: " + getImageFilter() + ";\n"; } css += "}\n"; if (currentTab === "gradients" && animateToggle.checked) { css += "\n@keyframes chromaFlow {\n"; css += " 0% { background-position: 0% 50%; }\n"; css += " 50% { background-position: 100% 50%; }\n"; css += " 100% { background-position: 20% 100%; }\n"; css += "}\n"; } return css; } // TOAST var toastTimer; function showToast(message) { toast.textContent = message; toast.classList.add("show"); clearTimeout(toastTimer); toastTimer = setTimeout(function () { toast.classList.remove("show"); }, 2500); announce(message); } // COPY CSS document.getElementById("copyButton").addEventListener( "click", function () { var css = buildCSS(); if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(css).then(function () { showToast("CSS copied to clipboard"); }).catch(function () { showToast("Clipboard unavailable"); }); } else { var textArea = document.createElement("textarea"); textArea.value = css; textArea.style.position = "fixed"; textArea.style.opacity = "0"; document.body.appendChild(textArea); textArea.select(); var success = document.execCommand("copy"); textArea.remove(); showToast( success ? "CSS copied to clipboard" : "Clipboard unavailable" ); } } ); // EXPLORE BUTTON document.getElementById("previewExplore").addEventListener( "click", function () { document.getElementById("randomButton").click(); } ); // FOLLOW SYSTEM MOTION PREFERENCE if (reducedMotion.addEventListener) { reducedMotion.addEventListener("change", updatePreview); } // INITIALIZE updatePreview(); })();
terminal
JavaScript Console
Preview
Clear
close
›
Run