chengzeyi commited on
Commit
eecfc6d
·
1 Parent(s): f81b395

Rewrite as a model reference page; drop auto-redirect and ad copy

Browse files
Files changed (4) hide show
  1. README.md +14 -5
  2. index.html +235 -215
  3. style.css +424 -550
  4. tabs.js +15 -0
README.md CHANGED
@@ -1,15 +1,24 @@
1
  ---
2
  title: Qwen-Image-Edit
3
  emoji: 🖼️
4
- colorFrom: blue
5
- colorTo: gray
6
  sdk: static
7
  pinned: false
8
- short_description: Advanced image editing foundation model by Alibaba Cloud
 
9
  ---
10
 
11
  # Qwen-Image-Edit
12
 
13
- Qwen-Image-Edit is a powerful image editing foundation model in the Qwen series that achieves significant advances in transforming existing images with precise control. Experiments show strong capabilities in image-to-image generation, with exceptional performance in maintaining original image structure while applying creative transformations.
 
 
 
14
 
15
- Check out the model on Hugging Face: https://huggingface.co/Qwen/Qwen-Image-Edit
 
 
 
 
 
 
1
  ---
2
  title: Qwen-Image-Edit
3
  emoji: 🖼️
4
+ colorFrom: gray
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ license: apache-2.0
9
+ short_description: Reference for Qwen-Image-Edit, instruction-based editing
10
  ---
11
 
12
  # Qwen-Image-Edit
13
 
14
+ A reference page for **Qwen-Image-Edit**, the instruction-driven image editing model from
15
+ Alibaba Cloud's Qwen team. It applies a written instruction to an existing image while
16
+ preserving identity, layout and unedited regions — including editing text already present
17
+ in a photograph.
18
 
19
+ - Weights: [Qwen/Qwen-Image-Edit](https://huggingface.co/Qwen/Qwen-Image-Edit) (Apache-2.0)
20
+ - Code: [QwenLM/Qwen-Image](https://github.com/QwenLM/Qwen-Image)
21
+ - Hosted inference: [qwen-image/edit](https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit)
22
+
23
+ Qwen-Image-Edit is developed and released by the Alibaba Cloud Qwen team. This Space is
24
+ maintained by WaveSpeed AI, which provides hosted inference for the model.
index.html CHANGED
@@ -1,224 +1,244 @@
1
- <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Qwen-Image Edit - Advanced Image-to-Image Generation by Alibaba Cloud</title>
7
- <meta name="description" content="Qwen-Image Edit: Part of the Qwen (Tongyi Qianwen) model series by Alibaba Cloud. A powerful image-to-image generative model that transforms existing images with high-quality rendering, artistic style control, and exceptional detail." />
8
- <meta name="keywords" content="Qwen-Image Edit, Qwen, Tongyi Qianwen, Alibaba Cloud, Image-to-Image, AI Models, Image Editing, Image Generation, AI Art, Generative AI, Image Synthesis, Multimodal AI" />
9
-
10
- <!-- Open Graph / Social Media Meta Tags -->
11
- <meta property="og:title" content="Qwen-Image Edit - Advanced Image-to-Image Generation by Alibaba Cloud" />
12
- <meta property="og:description" content="Transform your existing images into stunning new creations with Qwen-Image Edit, part of the Tongyi Qianwen model series developed by Alibaba Cloud" />
13
- <meta property="og:type" content="website" />
14
- <meta property="og:url" content="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" />
15
- <meta property="og:image" content="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/merge3.jpg" />
16
-
17
- <!-- Additional Meta Information -->
18
- <meta name="author" content="Alibaba Cloud Qwen Team" />
19
- <meta name="robots" content="index, follow" />
20
- <link rel="canonical" href="https://huggingface.co/Qwen/Qwen-Image-Edit" />
21
-
22
- <link rel="stylesheet" href="style.css" />
23
  </head>
24
  <body>
25
- <nav class="top-nav">
26
- <div class="nav-content">
27
- <div class="nav-logo">QWEN</div>
28
- <div class="nav-links">
29
- <a href="https://wavespeed.ai/" class="nav-link" target="_blank" rel="noopener noreferrer">Home</a>
30
- <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image" class="nav-link" target="_blank" rel="noopener noreferrer">Documentation</a>
31
- <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image" class="nav-link" target="_blank" rel="noopener noreferrer">Blog</a>
32
- <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" class="nav-button" target="_blank" rel="noopener noreferrer">Try on WaveSpeed →</a>
33
- </div>
34
- </div>
35
- </nav>
36
-
37
- <div class="container">
38
- <div class="content">
39
- <div class="logo-section">
40
- <h1>Qwen-Image Edit</h1>
41
- <p class="subtitle">By Alibaba Cloud Qwen Team</p>
42
- </div>
43
-
44
- <div class="announcement-section">
45
- <p class="announcement">Qwen-Image Edit is now open-source!</p>
46
- <div class="divider"></div>
47
- <p class="description">Advanced Image-to-Image Generative Model for Precise Editing</p>
48
- </div>
49
-
50
- <div class="hero-image">
51
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/merge3.jpg" alt="Qwen-Image Examples" class="full-width-img">
52
- </div>
53
-
54
- <section class="intro-section">
55
- <h2>Introduction</h2>
56
- <p>We are thrilled to release Qwen-Image Edit, an image editing foundation model in the Qwen series that achieves significant advances in transforming existing images with precise control. Experiments show strong capabilities in image-to-image generation, with exceptional performance in maintaining original image structure while applying creative transformations. Qwen-Image Edit is now available on Hugging Face and can be used locally with the diffusers library.</p>
57
- <div class="benchmark-image">
58
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/bench.png" alt="Qwen-Image Benchmark" class="full-width-img">
59
- </div>
60
- </section>
61
-
62
- <div class="features-section">
63
- <div class="feature">
64
- <h3>🚀 Multimodal AI Capabilities</h3>
65
- <p>Part of the Qwen (Tongyi Qianwen) model series, offering powerful image-to-image generation with exceptional understanding of complex editing requirements</p>
66
- </div>
67
-
68
- <div class="feature">
69
- <h3>🌟 Open Source Innovation</h3>
70
- <p>Part of Alibaba's commitment to open-source AI development, allowing researchers and developers to build upon and extend its capabilities</p>
71
- </div>
72
- <div class="feature">
73
- <h3>🔍 Comprehensive Model Family</h3>
74
- <p>Works alongside other Qwen models for text, vision, and multimodal applications, providing a complete ecosystem for AI development</p>
75
- </div>
76
- </div>
77
-
78
- <section class="quickstart-section">
79
- <h2>Quick Start</h2>
80
- <p>Choose your preferred Qwen image model:</p>
81
-
82
- <h3>Option 1: Using Qwen-Image-Edit with diffusers</h3>
83
- <p>Install the latest version of diffusers</p>
84
- <div class="code-block">
85
- <pre><code>pip install git+https://github.com/huggingface/diffusers</code></pre>
86
- </div>
87
- <div class="code-block">
88
- <pre><code>import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  from PIL import Image
90
- import torch
91
  from diffusers import QwenImageEditPipeline
92
 
93
- pipeline = QwenImageEditPipeline.from_pretrained("Qwen/Qwen-Image-Edit")
94
- print("pipeline loaded")
95
- pipeline.to(torch.bfloat16)
96
- pipeline.to("cuda")
97
- pipeline.set_progress_bar_config(disable=None)
98
-
99
- image = Image.open("./input.png").convert("RGB")
100
- prompt = "Change the rabbit's color to purple, with a flash light background."
101
-
102
- inputs = {
103
- "image": image,
104
- "prompt": prompt,
105
- "generator": torch.manual_seed(0),
106
- "true_cfg_scale": 4.0,
107
- "negative_prompt": " ",
108
- "num_inference_steps": 50,
109
- }
110
-
111
- with torch.inference_mode():
112
- output = pipeline(**inputs)
113
-
114
- output_image = output.images[0]
115
- output_image.save("output_image_edit.png")
116
- print("image saved at", os.path.abspath("output_image_edit.png"))</code></pre>
117
- </div>
118
-
119
- <h3>Option 2: Using the latest Qwen VLo model</h3>
120
- <p>The new Qwen VLo model specializes in image-to-image generation with progressive editing features.</p>
121
- <div class="code-block">
122
- <pre><code>pip install dashscope>=1.20.7</code></pre>
123
- </div>
124
- <div class="code-block">
125
- <pre><code>import dashscope
126
- from dashscope import ImageSynthesis
127
-
128
- # Set your API key
129
- dashscope.api_key = "YOUR_API_KEY"
130
-
131
- # Image-to-image generation
132
- response = ImageSynthesis.call(
133
- model='qwen-vlo',
134
- prompt='Transform this coffee shop into a futuristic cyber cafe with neon lights',
135
- negative_prompt='blurry, low quality',
136
- n=1, # Number of images to generate
137
- size='1024*1024', # Image size
138
- steps=50, # Diffusion steps
139
- image='path/to/input_image.jpg' # Input image for editing
140
- )
141
-
142
- # Save the generated image
143
- if response.status_code == 200:
144
- with open('qwen_vlo_result.png', 'wb') as f:
145
- f.write(response.output.images[0].image)
146
- print('Image saved successfully!')
147
- else:
148
- print(f'Failed to generate image: {response.message}')</code></pre>
149
- </div>
150
- </section>
151
-
152
- <section class="showcase-section">
153
- <h2>Show Cases</h2>
154
-
155
- <div class="showcase-item-full">
156
- <div class="showcase-description-full">
157
- <h3>Semantic Editing</h3>
158
- <p>One of the highlights of Qwen-Image Edit lies in its powerful capabilities for semantic editing. It can modify image content while perfectly preserving the original visual semantics. For example, when editing character images like Qwen's mascot Capybara, the model maintains character consistency even when most pixels in the image are changed. This enables effortless and diverse creation of original IP content, such as MBTI-themed emoji packs based on mascot characters.</p>
159
- </div>
160
- <div class="showcase-image-full">
161
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/s1.jpg" alt="Semantic Editing Example" class="showcase-img-full">
162
- </div>
163
- </div>
164
-
165
- <div class="showcase-item-full">
166
- <div class="showcase-description-full">
167
- <h3>Novel View Synthesis</h3>
168
- <p>Qwen-Image Edit excels at novel view synthesis, a key application in semantic editing. The model can rotate objects by various angles, including 90-degree and even full 180-degree rotations, allowing users to see different sides of objects. This capability is particularly valuable for product visualization, architectural rendering, and creative content production where multiple perspectives are needed.</p>
169
- </div>
170
- <div class="showcase-image-full">
171
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/s2.jpg" alt="Novel View Synthesis Example" class="showcase-img-full">
172
- </div>
173
- </div>
174
-
175
- <div class="showcase-item-full">
176
- <div class="showcase-description-full">
177
- <h3>Appearance Editing</h3>
178
- <p>Appearance editing is another powerful capability of Qwen-Image Edit. The model can keep certain regions of an image completely unchanged while adding, removing, or modifying specific elements. For example, it can insert signboards into scenes with corresponding reflections, remove fine details like hair strands, change the color of specific elements, or adjust backgrounds and clothing in portraits—all with exceptional attention to detail and realism.</p>
179
- </div>
180
- <div class="showcase-image-full">
181
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/s3.jpg" alt="Appearance Editing Example" class="showcase-img-full">
182
- </div>
183
- </div>
184
-
185
- <div class="showcase-item-full">
186
- <div class="showcase-description-full">
187
- <h3>Text Editing Excellence</h3>
188
- <p>A standout feature of Qwen-Image Edit is its accurate text editing capability, which stems from Qwen-Image's deep expertise in text rendering. The model excels at editing both English and Chinese text in images, enabling modifications to large headline text as well as precise adjustments to small and intricate text elements. This makes it particularly valuable for poster design, advertisement creation, and multilingual content production.</p>
189
- </div>
190
- <div class="showcase-image-full">
191
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/s4.jpg" alt="Text Editing Example" class="showcase-img-full">
192
- </div>
193
- </div>
194
-
195
- <div class="showcase-item-full">
196
- <div class="showcase-description-full">
197
- <h3>Progressive Editing</h3>
198
- <p>Qwen-Image Edit supports chained, step-by-step editing approaches that allow users to progressively refine and correct images. For example, when editing complex calligraphy artwork, users can draw bounding boxes to mark specific regions that need correction and instruct the model to fix these areas one by one. This iterative approach enables precise control over the editing process, ensuring the desired final result is achieved even for challenging edits.</p>
199
- </div>
200
- <div class="showcase-image-full">
201
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/bench.png" alt="Progressive Editing Example" class="showcase-img-full">
202
- </div>
203
- </div>
204
-
205
- <div class="showcase-conclusion">
206
- <p>Together, these features make Qwen-Image Edit not just a tool for basic image editing, but a comprehensive foundation model for intelligent visual transformation—where existing images become the canvas for sophisticated artistic and creative manipulation.</p>
207
- </div>
208
- </section>
209
-
210
- <div class="resource-links-section">
211
- <h2>Resources</h2>
212
- <div class="resource-links">
213
- <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" target="_blank" rel="noopener noreferrer" class="resource-link">Qwen-Image Edit on WaveSpeed</a>
214
- <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image" target="_blank" rel="noopener noreferrer" class="resource-link">Qwen-Image on WaveSpeed</a>
215
- <a href="https://wavespeed.ai/" target="_blank" rel="noopener noreferrer" class="resource-link">WaveSpeed AI</a>
216
- <a href="https://huggingface.co/Qwen/Qwen-Image-Edit" target="_blank" rel="noopener noreferrer" class="resource-link">Hugging Face</a>
217
- <a href="https://modelscope.cn/models/qwen/Qwen-Image-Edit" target="_blank" rel="noopener noreferrer" class="resource-link">ModelScope</a>
218
- <a href="https://chat.qwen.ai/" target="_blank" rel="noopener noreferrer" class="resource-link">Qwen Chat</a>
219
- </div>
220
- </div>
221
- </div>
222
- </div>
223
  </body>
224
  </html>
 
1
+ <!doctype html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Qwen-Image-Edit — instruction-based image editing</title>
7
+ <meta name="description" content="Reference for Qwen-Image-Edit, Alibaba&#x27;s open instruction-driven image editing model, with hosted API usage and local diffusers setup." />
8
+ <link rel="canonical" href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" />
9
+
10
+ <meta property="og:type" content="website" />
11
+ <meta property="og:title" content="Qwen-Image-Edit — instruction-based image editing" />
12
+ <meta property="og:description" content="Reference for Qwen-Image-Edit, Alibaba&#x27;s open instruction-driven image editing model, with hosted API usage and local diffusers setup." />
13
+ <meta property="og:url" content="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" />
14
+ <meta property="og:image" content="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/merge3.jpg" />
15
+ <meta name="twitter:card" content="summary_large_image" />
16
+
17
+ <link rel="stylesheet" href="style.css" />
 
 
 
 
 
18
  </head>
19
  <body>
20
+ <header class="site-header">
21
+ <div class="wrap">
22
+ <a class="brand" href="https://wavespeed.ai" target="_blank" rel="noopener">
23
+ <span class="brand-mark" aria-hidden="true"></span>
24
+ <span>WaveSpeed AI</span>
25
+ </a>
26
+ <nav class="header-nav">
27
+ <a class="jump opt" href="#overview">Overview</a>
28
+ <a class="jump opt" href="#edits">Edit types</a>
29
+ <a class="jump" href="#run">Run it</a>
30
+ <a class="jump opt" href="#local">Local</a>
31
+ <a class="jump" href="#resources">Resources</a>
32
+ <a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" target="_blank" rel="noopener">wavespeed.ai &#8599;</a>
33
+ </nav>
34
+ </div>
35
+ </header>
36
+
37
+ <main class="wrap">
38
+ <div class="hero">
39
+ <p class="eyebrow">Alibaba Cloud · Qwen Team</p>
40
+ <h1>Qwen-Image-Edit</h1>
41
+ <p class="lede">The editing counterpart to Qwen-Image. It takes an existing image plus a written instruction and applies the change while leaving the rest of the frame — including identity and layout — intact.</p>
42
+ <ul class="meta">
43
+ <li><b>Developer</b> Alibaba Cloud Qwen Team</li>
44
+ <li><b>Task</b> instruction-based image editing</li>
45
+ <li><b>License</b> Apache-2.0</li>
46
+ <li><b>Weights</b> open</li>
47
+ </ul>
48
+ </div>
49
+
50
+ <section id="overview">
51
+ <h2>Overview</h2>
52
+ <p class="section-note">Editing is expressed as an instruction rather than a mask. The model inherits Qwen-Image's text rendering, which is what makes editing text already present in a photograph practical.</p>
53
+ <div class="figure-single">
54
+ <figure>
55
+ <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/merge3.jpg" alt="Qwen-Image sample outputs" loading="lazy" />
56
+ <figcaption>Sample outputs from the Qwen-Image release.</figcaption>
57
+ </figure>
58
+ </div>
59
+ </section>
60
+ <section id="edits">
61
+ <h2>Edit types</h2>
62
+ <div class="grid">
63
+ <div class="card">
64
+ <h3>Semantic edits</h3>
65
+ <p>Change what is in the scene — add, remove or replace an object — while lighting and perspective stay consistent with the original.</p>
66
+ </div>
67
+ <div class="card">
68
+ <h3>Appearance edits</h3>
69
+ <p>Restyle or recolour without moving anything, so composition and structure survive the edit unchanged.</p>
70
+ </div>
71
+ <div class="card">
72
+ <h3>Text editing</h3>
73
+ <p>Replace words rendered inside the image while matching the existing font, perspective and surface — the capability inherited from Qwen-Image.</p>
74
+ </div>
75
+ <div class="card">
76
+ <h3>Identity preservation</h3>
77
+ <p>Faces and distinctive objects are held stable across the edit, which is what makes chained edits usable.</p>
78
+ </div>
79
+ </div>
80
+ </section>
81
+ <section id="variants">
82
+ <h2>Hosted variants</h2>
83
+ <div class="table-scroll">
84
+ <table>
85
+ <thead><tr><th>Endpoint</th><th>Notes</th></tr></thead>
86
+ <tbody>
87
+ <tr><td><code>wavespeed-ai/qwen-image/edit</code></td><td>Base instruction-driven editing.</td></tr>
88
+ <tr><td><code>wavespeed-ai/qwen-image/edit-plus</code></td><td>Updated editing checkpoint.</td></tr>
89
+ <tr><td><code>wavespeed-ai/qwen-image/edit-plus-lora</code></td><td>Editing with LoRA adapters applied.</td></tr>
90
+ </tbody>
91
+ </table>
92
+ </div>
93
+ </section>
94
+ <section id="run">
95
+ <h2>Run it</h2>
96
+ <p class="section-note">Pass a publicly reachable image URL, or upload first via <code>POST /media/upload/binary</code> and use the returned URL.</p>
97
+ <div class="code">
98
+ <div class="code-tabs" role="tablist">
99
+ <button type="button" role="tab" aria-selected="true" data-panel="run-0">cURL</button>
100
+ <button type="button" role="tab" aria-selected="false" data-panel="run-1">Python</button>
101
+ <button type="button" role="tab" aria-selected="false" data-panel="run-2">JavaScript</button>
102
+ </div>
103
+ <pre id="run-0" role="tabpanel"><code># 1. submit the job
104
+ curl -X POST &quot;https://api.wavespeed.ai/api/v3/wavespeed-ai/qwen-image/edit&quot; \
105
+ -H &quot;Authorization: Bearer $WAVESPEED_API_KEY&quot; \
106
+ -H &quot;Content-Type: application/json&quot; \
107
+ -d &#x27;{
108
+ &quot;image&quot;: &quot;https://example.com/input.jpg&quot;,
109
+ &quot;prompt&quot;: &quot;Replace the text on the sign with \&quot;Open until 9pm\&quot;, keep the original font and perspective&quot;,
110
+ &quot;enable_sync_mode&quot;: false
111
+ }&#x27;
112
+
113
+ # -&gt; {&quot;code&quot;: 200, &quot;data&quot;: {&quot;id&quot;: &quot;&lt;request-id&gt;&quot;, &quot;status&quot;: &quot;created&quot;, ...}}
114
+
115
+ # 2. poll until status is &quot;completed&quot;
116
+ curl &quot;https://api.wavespeed.ai/api/v3/predictions/&lt;request-id&gt;/result&quot; \
117
+ -H &quot;Authorization: Bearer $WAVESPEED_API_KEY&quot;
118
+
119
+ # -&gt; {&quot;code&quot;: 200, &quot;data&quot;: {&quot;status&quot;: &quot;completed&quot;, &quot;outputs&quot;: [&quot;https://...&quot;]}}</code></pre>
120
+ <pre id="run-1" role="tabpanel" hidden><code>import os, time, requests
121
+
122
+ API = &quot;https://api.wavespeed.ai/api/v3&quot;
123
+ KEY = os.environ[&quot;WAVESPEED_API_KEY&quot;]
124
+ HEADERS = {&quot;Authorization&quot;: f&quot;Bearer {KEY}&quot;}
125
+
126
+ # submit
127
+ res = requests.post(
128
+ f&quot;{API}/wavespeed-ai/qwen-image/edit&quot;,
129
+ headers={**HEADERS, &quot;Content-Type&quot;: &quot;application/json&quot;},
130
+ json={
131
+ &quot;image&quot;: &quot;https://example.com/input.jpg&quot;,
132
+ &quot;prompt&quot;: &quot;Replace the text on the sign with \&quot;Open until 9pm\&quot;, keep the original font and perspective&quot;,
133
+ &quot;enable_sync_mode&quot;: false
134
+ },
135
+ timeout=30,
136
+ )
137
+ res.raise_for_status()
138
+ request_id = res.json()[&quot;data&quot;][&quot;id&quot;]
139
+
140
+ # poll
141
+ while True:
142
+ data = requests.get(
143
+ f&quot;{API}/predictions/{request_id}/result&quot;,
144
+ headers=HEADERS,
145
+ timeout=30,
146
+ ).json()[&quot;data&quot;]
147
+
148
+ if data[&quot;status&quot;] == &quot;completed&quot;:
149
+ print(data[&quot;outputs&quot;][0])
150
+ break
151
+ if data[&quot;status&quot;] == &quot;failed&quot;:
152
+ raise RuntimeError(data.get(&quot;error&quot;, &quot;generation failed&quot;))
153
+ time.sleep(1.5)</code></pre>
154
+ <pre id="run-2" role="tabpanel" hidden><code>const API = &quot;https://api.wavespeed.ai/api/v3&quot;;
155
+ const KEY = process.env.WAVESPEED_API_KEY;
156
+ const headers = { Authorization: `Bearer ${KEY}` };
157
+
158
+ // submit
159
+ const submit = await fetch(`${API}/wavespeed-ai/qwen-image/edit`, {
160
+ method: &quot;POST&quot;,
161
+ headers: { ...headers, &quot;Content-Type&quot;: &quot;application/json&quot; },
162
+ body: JSON.stringify({
163
+ &quot;image&quot;: &quot;https://example.com/input.jpg&quot;,
164
+ &quot;prompt&quot;: &quot;Replace the text on the sign with \&quot;Open until 9pm\&quot;, keep the original font and perspective&quot;,
165
+ &quot;enable_sync_mode&quot;: false
166
+ }),
167
+ });
168
+ const { data: { id } } = await submit.json();
169
+
170
+ // poll
171
+ for (;;) {
172
+ const res = await fetch(`${API}/predictions/${id}/result`, { headers });
173
+ const { data } = await res.json();
174
+
175
+ if (data.status === &quot;completed&quot;) {
176
+ console.log(data.outputs[0]);
177
+ break;
178
+ }
179
+ if (data.status === &quot;failed&quot;) throw new Error(data.error ?? &quot;generation failed&quot;);
180
+ await new Promise((r) =&gt; setTimeout(r, 1500));
181
+ }</code></pre>
182
+ </div>
183
+ <div class="callout"><p>Requests are asynchronous: <code>POST</code> returns a request id, then you poll <code>/predictions/&lt;id&gt;/result</code> until <code>status</code> is <code>completed</code>. Set <code>enable_sync_mode: true</code> to have the call block and return outputs directly.</p><p>API keys are created in the <a href="https://wavespeed.ai/dashboard" target="_blank" rel="noopener">WaveSpeed dashboard</a>.</p></div>
184
+ <div class="btn-row">
185
+ <a class="btn" href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" target="_blank" rel="noopener">Open on WaveSpeed</a>
186
+ <a class="btn secondary" href="https://wavespeed.ai/docs" target="_blank" rel="noopener">API reference</a>
187
+ </div>
188
+ </section>
189
+ <section id="local">
190
+ <h2>Running locally</h2>
191
+ <p class="section-note">Weights are Apache-2.0 and load through <code>diffusers</code>.</p>
192
+ <div class="code">
193
+ <div class="code-tabs" role="tablist">
194
+ <button type="button" role="tab" aria-selected="true" data-panel="local-0">Python</button>
195
+ </div>
196
+ <pre id="local-0" role="tabpanel"><code>import torch
197
  from PIL import Image
 
198
  from diffusers import QwenImageEditPipeline
199
 
200
+ pipe = QwenImageEditPipeline.from_pretrained(
201
+ &quot;Qwen/Qwen-Image-Edit&quot;,
202
+ torch_dtype=torch.bfloat16,
203
+ ).to(&quot;cuda&quot;)
204
+
205
+ image = Image.open(&quot;input.jpg&quot;).convert(&quot;RGB&quot;)
206
+
207
+ out = pipe(
208
+ image=image,
209
+ prompt=&#x27;Replace the text on the sign with &quot;Open until 9pm&quot;, &#x27;
210
+ &quot;keep the original font and perspective&quot;,
211
+ negative_prompt=&quot; &quot;,
212
+ num_inference_steps=50,
213
+ true_cfg_scale=4.0,
214
+ generator=torch.Generator(device=&quot;cuda&quot;).manual_seed(42),
215
+ ).images[0]
216
+
217
+ out.save(&quot;edited.png&quot;)</code></pre>
218
+ </div>
219
+ </section>
220
+ <section id="resources">
221
+ <h2>Resources</h2>
222
+ <ul class="links">
223
+ <li><a href="https://huggingface.co/Qwen/Qwen-Image-Edit" target="_blank" rel="noopener"><span>Qwen/Qwen-Image-Edit weights</span><span class="host">huggingface.co</span></a></li>
224
+ <li><a href="https://github.com/QwenLM/Qwen-Image" target="_blank" rel="noopener"><span>Qwen-Image on GitHub</span><span class="host">github.com</span></a></li>
225
+ <li><a href="https://wavespeed.ai/models/wavespeed-ai/qwen-image/edit" target="_blank" rel="noopener"><span>Hosted endpoint</span><span class="host">wavespeed.ai</span></a></li>
226
+ <li><a href="https://huggingface.co/spaces/wavespeed/qwen-image" target="_blank" rel="noopener"><span>Text-to-image variant</span><span class="host">huggingface.co</span></a></li>
227
+ </ul>
228
+ </section>
229
+ </main>
230
+
231
+ <footer class="site-footer">
232
+ <div class="wrap">
233
+ <p>This page is a model reference maintained by WaveSpeed AI. The model itself is developed and released by its respective authors; trademarks belong to them. WaveSpeed AI provides hosted inference for it.</p>
234
+ <div class="footer-links">
235
+ <a href="https://wavespeed.ai" target="_blank" rel="noopener">WaveSpeed AI</a>
236
+ <a href="https://wavespeed.ai/docs" target="_blank" rel="noopener">Docs</a>
237
+ <a href="https://huggingface.co/wavespeed" target="_blank" rel="noopener">Hugging Face</a>
238
+ </div>
239
+ </div>
240
+ </footer>
241
+
242
+ <script src="tabs.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  </body>
244
  </html>
style.css CHANGED
@@ -1,701 +1,575 @@
1
- /* Navigation Styles */
2
- .top-nav {
3
- position: fixed;
4
- top: 0;
5
- left: 0;
6
- right: 0;
7
- background: rgba(26, 26, 26, 0.95);
8
- backdrop-filter: blur(10px);
9
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
10
- z-index: 1000;
11
- padding: 1rem 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
- .nav-content {
15
- max-width: 1200px;
16
- margin: 0 auto;
17
- padding: 0 2rem;
18
- display: flex;
19
- justify-content: space-between;
20
- align-items: center;
 
21
  }
22
 
23
- .nav-logo {
24
- font-size: 1.5rem;
25
- font-weight: bold;
26
- color: white;
27
- letter-spacing: 2px;
28
  }
29
 
30
- .nav-links {
31
- display: flex;
32
- gap: 2rem;
33
- align-items: center;
34
  }
35
 
36
- .nav-link {
37
- color: #aaa;
38
- text-decoration: none;
39
- font-size: 0.95rem;
40
- transition: color 0.3s ease;
41
  }
42
 
43
- .nav-link:hover {
44
- color: white;
 
 
45
  }
46
 
47
- .nav-button {
48
- background: #2196F3;
49
- color: white;
50
- padding: 0.5rem 1.2rem;
51
- border-radius: 20px;
52
- text-decoration: none;
53
- font-size: 0.95rem;
54
- font-weight: 500;
55
- transition: all 0.3s ease;
56
  }
57
 
58
- .nav-button:hover {
59
- background: #1976D2;
60
- transform: translateY(-1px);
61
- }
62
 
63
- /* Content Styles */
64
- body {
65
- margin: 0;
66
- padding: 0;
67
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
68
- background: linear-gradient(135deg, #1a1a1a, #2a2a2a);
69
- color: white;
70
- min-height: 100vh;
71
- display: flex;
72
- align-items: center;
73
- justify-content: center;
74
  }
75
 
76
- .container {
77
- text-align: center;
78
- padding: 2rem;
79
- max-width: 800px;
80
- width: 100%;
81
- margin-top: 4rem;
82
  }
83
 
84
- .content {
85
- animation: fadeIn 1s ease-in;
 
 
 
 
 
 
86
  }
87
 
88
- .logo-section {
89
- margin-bottom: 2rem;
90
  }
91
 
92
- h1 {
93
- margin: 0.5rem 0;
94
- font-size: 3.5rem;
95
- font-weight: bold;
96
- background: linear-gradient(45deg, #fff, #e0e0e0);
97
- -webkit-background-clip: text;
98
- background-clip: text;
99
- -webkit-text-fill-color: transparent;
100
- text-shadow: 0 0 30px rgba(255,255,255,0.1);
101
  }
102
 
103
- h2 {
104
- margin: 1.5rem 0 1rem;
105
- font-size: 2.2rem;
106
- font-weight: bold;
107
- color: #2196F3;
108
- text-shadow: 0 0 15px rgba(33,150,243,0.2);
 
109
  }
110
 
111
- .announcement-section {
112
- margin: 2rem 0;
 
 
 
113
  }
114
 
115
- .announcement {
116
- font-size: 2rem;
117
- color: #2196F3;
118
- margin: 1rem 0;
119
- font-weight: bold;
120
- text-shadow: 0 0 10px rgba(33,150,243,0.3);
121
  }
122
 
123
- .divider {
124
- height: 2px;
125
- background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
126
- margin: 2rem auto;
127
- width: 60%;
128
  }
129
 
130
- .features-section {
131
- display: grid;
132
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
133
- gap: 2rem;
134
- margin: 3rem 0;
135
  }
136
 
137
- .feature {
138
- padding: 1.5rem;
139
- background: rgba(255,255,255,0.05);
140
- border-radius: 12px;
141
- transition: transform 0.3s ease;
142
  }
143
 
144
- .feature:hover {
145
- transform: translateY(-5px);
146
- background: rgba(255,255,255,0.08);
 
 
 
147
  }
148
 
149
- .feature h3 {
150
- font-size: 1.2rem;
151
- margin: 0 0 1rem 0;
152
- color: #fff;
153
- }
154
 
155
- .feature p {
156
- color: #aaa;
157
- font-size: 0.95rem;
158
- line-height: 1.5;
159
- margin: 0;
160
  }
161
 
162
- .models-section {
163
- margin: 3rem 0;
164
- padding: 2rem;
165
- background: rgba(255,255,255,0.03);
166
- border-radius: 16px;
 
 
167
  }
168
 
169
- .models-title {
170
- font-size: 1.5rem;
171
- color: #fff;
172
- margin-bottom: 2rem;
173
- text-align: center;
 
174
  }
175
 
176
- .models-grid {
177
- display: grid;
178
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
179
- gap: 2rem;
 
180
  }
181
 
182
- .model-category {
183
- text-align: left;
 
 
 
 
 
184
  }
185
 
186
- .model-category h4 {
187
- color: #aaa;
188
- font-size: 1.1rem;
189
- margin-bottom: 1rem;
190
- padding-bottom: 0.5rem;
191
- border-bottom: 1px solid rgba(255,255,255,0.1);
 
 
192
  }
193
 
194
- .model-links {
195
- display: flex;
196
- flex-direction: column;
197
- gap: 1rem;
 
 
 
 
198
  }
199
 
200
- .model-link {
201
- display: flex;
202
- justify-content: space-between;
203
- align-items: center;
204
- padding: 1rem;
205
- background: rgba(255,255,255,0.05);
206
- border-radius: 8px;
207
- text-decoration: none;
208
- transition: all 0.3s ease;
209
  }
210
 
211
- .model-link:hover {
212
- background: rgba(255,255,255,0.1);
213
- transform: translateY(-2px);
 
214
  }
215
 
216
- .model-name {
217
- color: #fff;
218
- font-weight: 500;
 
 
 
219
  }
220
 
221
- .model-tag {
222
- font-size: 0.8rem;
223
- padding: 0.2rem 0.6rem;
224
- background: #2196F3;
225
- color: white;
226
- border-radius: 12px;
227
- font-weight: 500;
228
  }
229
 
230
- .model-highlight {
231
- margin-top: 2rem;
232
- padding: 1.5rem;
233
- background: linear-gradient(135deg, rgba(33,150,243,0.1), rgba(33,150,243,0.05));
234
- border-radius: 12px;
235
- border: 1px solid rgba(33,150,243,0.2);
236
  }
237
 
238
- .model-highlight h4 {
239
- color: #2196F3;
240
- font-size: 1.2rem;
241
- margin: 0 0 1rem 0;
242
  }
243
 
244
- .model-highlight p {
245
- color: #aaa;
246
- font-size: 0.95rem;
247
- line-height: 1.6;
248
- margin: 0;
 
 
249
  }
250
 
251
- .redirect-section {
252
- margin-top: 3rem;
 
 
 
253
  }
254
 
255
- .redirect-text {
256
- color: #888;
257
- font-size: 1rem;
258
- margin: 1rem 0;
259
- animation: pulse 2s infinite;
260
  }
261
 
262
- .progress-bar {
263
- width: 200px;
264
- height: 4px;
265
- background: rgba(255,255,255,0.1);
266
- border-radius: 2px;
267
- margin: 1rem auto;
268
- overflow: hidden;
269
  }
270
 
271
- .progress {
272
- height: 100%;
273
- background: #2196F3;
274
- animation: progress 30s linear;
 
 
 
 
275
  }
276
 
277
- .cta-button {
278
- display: inline-block;
279
- padding: 0.8rem 1.5rem;
280
- background: #2196F3;
281
- color: white;
282
- text-decoration: none;
283
- border-radius: 25px;
284
- font-weight: bold;
285
- margin-top: 1rem;
286
- transition: all 0.3s ease;
287
  }
288
 
289
- .cta-button:hover {
290
- background: #1976D2;
291
- transform: scale(1.05);
 
 
 
292
  }
293
 
294
- .resource-links-section {
295
- margin: 3rem 0 1rem;
296
- padding: 1rem;
297
- background: rgba(255,255,255,0.03);
298
- border-radius: 16px;
299
  }
300
 
301
- .resource-links {
302
- margin-top: 1rem;
303
- font-size: 0.9rem;
304
- color: #888;
305
- display: flex;
306
- flex-wrap: wrap;
307
- justify-content: center;
308
- gap: 1rem;
309
- align-items: center;
310
  }
311
 
312
- .resource-links p {
313
- margin: 0;
314
- margin-right: 0.5rem;
315
  }
316
 
317
- .resource-link {
318
- color: #2196F3;
319
- text-decoration: none;
320
- transition: all 0.3s ease;
321
- padding: 0.4rem 1rem;
322
- background: rgba(33, 150, 243, 0.1);
323
- border-radius: 20px;
324
- font-weight: 500;
325
  }
326
 
327
- .resource-link:hover {
328
- color: white;
329
- background: #2196F3;
330
- transform: translateY(-2px);
 
331
  }
332
 
333
- .highlight-links {
334
- display: flex;
335
- gap: 1rem;
336
- margin-top: 1.5rem;
337
- justify-content: center;
338
  }
339
 
340
- /* Introduction Section */
341
- .intro-section {
342
- margin: 2rem 0;
343
- padding: 1.5rem;
344
- background: rgba(255,255,255,0.03);
345
- border-radius: 16px;
346
- text-align: left;
347
- line-height: 1.6;
348
  }
349
 
350
- .intro-section p {
351
- color: #ddd;
352
- line-height: 1.6;
353
- font-size: 1.1rem;
354
  }
355
 
356
- .hero-image {
357
- width: 100%;
358
- margin: 30px 0;
359
- border-radius: 12px;
360
- overflow: hidden;
361
- box-shadow: 0 10px 30px rgba(0,0,0,0.15);
362
  }
363
 
364
- .benchmark-image {
365
- width: 100%;
366
- margin: 30px 0;
367
- border-radius: 12px;
368
- overflow: hidden;
369
- box-shadow: 0 5px 20px rgba(0,0,0,0.1);
 
 
370
  }
371
 
372
- .full-width-img {
373
- width: 100%;
374
- height: auto;
375
- display: block;
 
 
376
  }
377
 
378
- /* News Section */
379
- .news-section {
380
- margin: 2rem 0;
381
- padding: 1.5rem;
382
- background: rgba(255,255,255,0.03);
383
- border-radius: 16px;
384
- text-align: left;
 
 
 
 
385
  }
386
 
387
- .news-items {
388
- display: flex;
389
- flex-direction: column;
390
- gap: 1rem;
391
  }
392
 
393
- .news-item {
394
- display: flex;
395
- align-items: baseline;
396
- gap: 0.5rem;
397
- padding-bottom: 0.5rem;
398
- border-bottom: 1px solid rgba(255,255,255,0.1);
399
  }
400
 
401
- .news-date {
402
- color: #2196F3;
403
- font-weight: 500;
404
- white-space: nowrap;
 
 
 
 
405
  }
406
 
407
- .news-content {
408
- color: #ddd;
409
  }
410
 
411
- .news-content a {
412
- color: #2196F3;
413
- text-decoration: none;
414
- transition: color 0.3s ease;
415
  }
416
 
417
- .news-content a:hover {
418
- color: #64B5F6;
419
- text-decoration: underline;
 
 
 
420
  }
421
 
422
- /* Quick Start Section */
423
- .quickstart-section {
424
- margin: 3rem 0;
425
- padding: 1.5rem;
426
- background: rgba(255,255,255,0.03);
427
- border-radius: 16px;
428
- text-align: left;
 
 
429
  }
430
 
431
- .quickstart-section p {
432
- color: #ddd;
433
- line-height: 1.6;
 
 
 
 
 
 
 
 
434
  }
435
 
436
- .code-block {
437
- margin: 1rem 0;
438
- padding: 1rem;
439
- background: rgba(0,0,0,0.3);
440
- border-radius: 8px;
441
- overflow-x: auto;
442
  }
443
 
444
- .code-block pre {
445
- margin: 0;
 
 
 
446
  }
447
 
448
- .code-block code {
449
- color: #E0E0E0;
450
- font-family: 'Courier New', Courier, monospace;
451
- font-size: 0.9rem;
452
- line-height: 1.5;
 
 
 
 
 
453
  }
454
 
455
- /* Showcase Section */
456
- .showcase-section {
457
- margin: 3rem 0;
458
- padding: 1.5rem;
459
- background: rgba(255,255,255,0.03);
460
- border-radius: 16px;
461
- text-align: left;
462
  }
463
 
464
- .showcase-item {
465
- margin-bottom: 2rem;
466
- display: grid;
467
  }
468
 
469
- .showcase-description {
470
- flex: 1;
 
 
 
471
  }
472
 
473
- .showcase-image {
474
- height: auto;
475
- background: rgba(0,0,0,0.2);
476
- border-radius: 8px;
477
- display: flex;
478
- align-items: center;
479
- justify-content: center;
480
- color: #888;
481
- font-style: italic;
482
- border: 1px dashed rgba(255,255,255,0.2);
483
- overflow: hidden;
 
484
  }
485
 
486
- .showcase-img {
487
- width: 100%;
488
- height: auto;
489
- object-fit: cover;
490
- border-radius: 8px;
491
- transition: transform 0.3s ease;
492
  }
493
 
494
- .showcase-img:hover {
495
- transform: scale(1.02);
 
 
496
  }
497
 
498
- .showcase-item-full {
499
- display: flex;
500
- flex-direction: column;
501
- margin-bottom: 80px;
502
- width: 100%;
503
  }
504
 
505
- .showcase-description-full {
506
- margin-bottom: 30px;
507
- text-align: center;
508
- max-width: 900px;
509
- margin-left: auto;
510
- margin-right: auto;
511
- padding: 0 20px;
512
  }
513
 
514
- .showcase-description-full h3 {
515
- font-size: 24px;
516
- margin-bottom: 15px;
517
- color: #4a9eff;
 
 
 
 
518
  }
519
 
520
- .showcase-image-full {
521
- width: 100%;
522
- height: auto;
523
- border-radius: 12px;
524
- overflow: hidden;
525
- box-shadow: 0 10px 30px rgba(0,0,0,0.2);
526
  }
527
 
528
- .showcase-img-full {
529
- width: 100%;
530
- height: auto;
531
- object-fit: cover;
532
- display: block;
533
- transition: transform 0.5s ease;
534
  }
535
 
536
- .showcase-img-full:hover {
537
- transform: scale(1.01);
 
538
  }
539
 
540
- .showcase-conclusion {
541
- margin-top: 2rem;
542
- padding: 1rem;
543
- background: rgba(33,150,243,0.1);
544
- border-radius: 8px;
545
- border-left: 4px solid #2196F3;
546
- }
547
-
548
- .showcase-conclusion p {
549
- color: #fff;
550
- font-size: 1.1rem;
551
- line-height: 1.6;
552
- margin: 0;
553
- }
554
-
555
- .highlight-link {
556
- display: inline-block;
557
- padding: 0.6rem 1.2rem;
558
- background: rgba(33,150,243,0.1);
559
- border: 1px solid rgba(33,150,243,0.3);
560
- border-radius: 8px;
561
- color: #2196F3;
562
- text-decoration: none;
563
- font-size: 0.9rem;
564
- font-weight: 500;
565
- transition: all 0.3s ease;
566
- }
567
-
568
- .highlight-link:hover {
569
- background: rgba(33,150,243,0.2);
570
- transform: translateY(-2px);
571
- }
572
-
573
- @keyframes fadeIn {
574
- from { opacity: 0; transform: translateY(-20px); }
575
- to { opacity: 1; transform: translateY(0); }
576
- }
577
-
578
- @keyframes pulse {
579
- 0% { opacity: 0.6; }
580
- 50% { opacity: 1; }
581
- 100% { opacity: 0.6; }
582
- }
583
-
584
- @keyframes progress {
585
- from { width: 0; }
586
- to { width: 100%; }
587
- }
588
-
589
- @media (max-width: 768px) {
590
- .nav-content {
591
- padding: 0 1rem;
592
- }
593
-
594
- .nav-links {
595
- gap: 1rem;
596
- }
597
-
598
- .nav-link {
599
- display: none;
600
- }
601
-
602
- .nav-button {
603
- display: block;
604
- }
605
- }
606
-
607
- @media (max-width: 600px) {
608
- h1 {
609
- font-size: 2.5rem;
610
- }
611
-
612
- h2 {
613
- font-size: 1.8rem;
614
- }
615
-
616
- .announcement {
617
- font-size: 1.5rem;
618
- }
619
-
620
- .features-section {
621
- grid-template-columns: 1fr;
622
- gap: 1rem;
623
- }
624
-
625
- .container {
626
- padding: 1rem;
627
- }
628
-
629
- .models-section {
630
- padding: 1rem;
631
- }
632
-
633
- .models-grid {
634
- grid-template-columns: 1fr;
635
- gap: 1rem;
636
- }
637
-
638
- .model-link {
639
- padding: 0.8rem;
640
- }
641
-
642
- .model-highlight {
643
- margin-top: 1.5rem;
644
- padding: 1rem;
645
- }
646
-
647
- .highlight-links {
648
- flex-direction: column;
649
- gap: 0.8rem;
650
- }
651
-
652
- .intro-section,
653
- .news-section,
654
- .quickstart-section,
655
- .showcase-section,
656
- .resource-links-section {
657
- padding: 1rem;
658
- margin: 1.5rem 0;
659
- }
660
-
661
- .code-block {
662
- padding: 0.5rem;
663
- }
664
-
665
- .showcase-image {
666
- height: auto;
667
- max-height: 300px;
668
- }
669
-
670
- .showcase-description-full {
671
- padding: 0 15px;
672
- margin-bottom: 20px;
673
- }
674
-
675
- .showcase-image-full {
676
- border-radius: 8px;
677
- }
678
-
679
- .showcase-item-full {
680
- margin-bottom: 50px;
681
- }
682
-
683
- .hero-image img,
684
- .benchmark-image img {
685
- border-radius: 8px;
686
- }
687
-
688
- .news-item {
689
- flex-direction: column;
690
- gap: 0.3rem;
691
- }
692
-
693
- .resource-links {
694
- flex-direction: column;
695
- gap: 0.8rem;
696
- }
697
-
698
- .highlight-link {
699
- text-align: center;
700
- }
701
  }
 
1
+ /* ==========================================================================
2
+ Shared stylesheet for wavespeed model reference pages.
3
+ Edit here, then run _shared/sync.sh to copy into each Space.
4
+ ========================================================================== */
5
+
6
+ :root {
7
+ --bg: #ffffff;
8
+ --bg-soft: #f7f8fa;
9
+ --bg-code: #f4f5f7;
10
+ --fg: #14161a;
11
+ --fg-muted: #5b6270;
12
+ --fg-faint: #868d9b;
13
+ --line: #e4e6eb;
14
+ --line-strong: #d2d6de;
15
+ --accent: #2f5bd7;
16
+ --accent-soft: #eef2fd;
17
+ --radius: 10px;
18
+ --radius-sm: 6px;
19
+ --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
20
+ --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
21
+ "Noto Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
22
+ --maxw: 880px;
23
+ }
24
+
25
+ @media (prefers-color-scheme: dark) {
26
+ :root {
27
+ --bg: #0e1014;
28
+ --bg-soft: #161920;
29
+ --bg-code: #14171d;
30
+ --fg: #e7e9ee;
31
+ --fg-muted: #99a1b0;
32
+ --fg-faint: #6f7788;
33
+ --line: #252a33;
34
+ --line-strong: #333a46;
35
+ --accent: #7ba1ff;
36
+ --accent-soft: #172136;
37
+ }
38
+ }
39
+
40
+ *,
41
+ *::before,
42
+ *::after {
43
+ box-sizing: border-box;
44
+ }
45
+
46
+ html {
47
+ -webkit-text-size-adjust: 100%;
48
+ scroll-behavior: smooth;
49
  }
50
 
51
+ body {
52
+ margin: 0;
53
+ background: var(--bg);
54
+ color: var(--fg);
55
+ font-family: var(--sans);
56
+ font-size: 16px;
57
+ line-height: 1.65;
58
+ -webkit-font-smoothing: antialiased;
59
  }
60
 
61
+ a {
62
+ color: var(--accent);
63
+ text-decoration: none;
 
 
64
  }
65
 
66
+ a:hover {
67
+ text-decoration: underline;
 
 
68
  }
69
 
70
+ img,
71
+ video {
72
+ max-width: 100%;
73
+ height: auto;
74
+ display: block;
75
  }
76
 
77
+ hr {
78
+ border: 0;
79
+ border-top: 1px solid var(--line);
80
+ margin: 3rem 0;
81
  }
82
 
83
+ .wrap {
84
+ max-width: var(--maxw);
85
+ margin: 0 auto;
86
+ padding: 0 20px;
 
 
 
 
 
87
  }
88
 
89
+ /* --- header ------------------------------------------------------------- */
 
 
 
90
 
91
+ .site-header {
92
+ border-bottom: 1px solid var(--line);
93
+ background: var(--bg);
94
+ position: sticky;
95
+ top: 0;
96
+ z-index: 20;
 
 
 
 
 
97
  }
98
 
99
+ .site-header .wrap {
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: space-between;
103
+ gap: 16px;
104
+ height: 56px;
105
  }
106
 
107
+ .brand {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 9px;
111
+ font-weight: 600;
112
+ font-size: 0.9rem;
113
+ color: var(--fg);
114
+ letter-spacing: -0.01em;
115
  }
116
 
117
+ .brand:hover {
118
+ text-decoration: none;
119
  }
120
 
121
+ .brand-mark {
122
+ width: 20px;
123
+ height: 20px;
124
+ border-radius: 5px;
125
+ background: var(--accent);
126
+ flex: 0 0 auto;
127
+ position: relative;
 
 
128
  }
129
 
130
+ .brand-mark::after {
131
+ content: "";
132
+ position: absolute;
133
+ inset: 6px 4px;
134
+ border-left: 2px solid var(--bg);
135
+ border-right: 2px solid var(--bg);
136
+ opacity: 0.85;
137
  }
138
 
139
+ .header-nav {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 20px;
143
+ font-size: 0.86rem;
144
  }
145
 
146
+ .header-nav a {
147
+ color: var(--fg-muted);
 
 
 
 
148
  }
149
 
150
+ .header-nav a:hover {
151
+ color: var(--fg);
152
+ text-decoration: none;
 
 
153
  }
154
 
155
+ .brand span:last-child {
156
+ white-space: nowrap;
 
 
 
157
  }
158
 
159
+ @media (max-width: 760px) {
160
+ .header-nav a.opt {
161
+ display: none;
162
+ }
 
163
  }
164
 
165
+ /* On phones the in-page anchors aren't worth the crowding — the page is short
166
+ enough to scroll, and the one outbound link needs the room. */
167
+ @media (max-width: 560px) {
168
+ .header-nav a.jump {
169
+ display: none;
170
+ }
171
  }
172
 
173
+ /* --- hero --------------------------------------------------------------- */
 
 
 
 
174
 
175
+ .hero {
176
+ padding: 56px 0 12px;
 
 
 
177
  }
178
 
179
+ .eyebrow {
180
+ font-size: 0.72rem;
181
+ font-weight: 600;
182
+ letter-spacing: 0.08em;
183
+ text-transform: uppercase;
184
+ color: var(--fg-faint);
185
+ margin: 0 0 14px;
186
  }
187
 
188
+ h1 {
189
+ font-size: 2.6rem;
190
+ line-height: 1.15;
191
+ letter-spacing: -0.025em;
192
+ font-weight: 700;
193
+ margin: 0 0 14px;
194
  }
195
 
196
+ .lede {
197
+ font-size: 1.12rem;
198
+ color: var(--fg-muted);
199
+ margin: 0;
200
+ max-width: 68ch;
201
  }
202
 
203
+ @media (max-width: 620px) {
204
+ h1 {
205
+ font-size: 2rem;
206
+ }
207
+ .hero {
208
+ padding-top: 36px;
209
+ }
210
  }
211
 
212
+ /* metadata strip under the title */
213
+ .meta {
214
+ display: flex;
215
+ flex-wrap: wrap;
216
+ gap: 8px 10px;
217
+ margin: 26px 0 0;
218
+ padding: 0;
219
+ list-style: none;
220
  }
221
 
222
+ .meta li {
223
+ font-size: 0.78rem;
224
+ font-family: var(--mono);
225
+ color: var(--fg-muted);
226
+ border: 1px solid var(--line);
227
+ border-radius: 999px;
228
+ padding: 3px 11px;
229
+ white-space: nowrap;
230
  }
231
 
232
+ .meta li b {
233
+ font-weight: 500;
234
+ color: var(--fg-faint);
 
 
 
 
 
 
235
  }
236
 
237
+ /* --- sections ----------------------------------------------------------- */
238
+
239
+ section {
240
+ padding: 44px 0 0;
241
  }
242
 
243
+ h2 {
244
+ font-size: 1.35rem;
245
+ letter-spacing: -0.015em;
246
+ font-weight: 650;
247
+ margin: 0 0 6px;
248
+ scroll-margin-top: 76px;
249
  }
250
 
251
+ .section-note {
252
+ color: var(--fg-muted);
253
+ margin: 0 0 22px;
254
+ font-size: 0.95rem;
255
+ max-width: 70ch;
 
 
256
  }
257
 
258
+ h3 {
259
+ font-size: 1rem;
260
+ font-weight: 620;
261
+ margin: 0 0 6px;
262
+ letter-spacing: -0.005em;
 
263
  }
264
 
265
+ p {
266
+ margin: 0 0 1rem;
 
 
267
  }
268
 
269
+ /* --- cards -------------------------------------------------------------- */
270
+
271
+ .grid {
272
+ display: grid;
273
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
274
+ gap: 14px;
275
+ margin: 0;
276
  }
277
 
278
+ .card {
279
+ border: 1px solid var(--line);
280
+ border-radius: var(--radius);
281
+ padding: 18px 18px 16px;
282
+ background: var(--bg);
283
  }
284
 
285
+ .card p {
286
+ margin: 0;
287
+ color: var(--fg-muted);
288
+ font-size: 0.9rem;
289
+ line-height: 1.6;
290
  }
291
 
292
+ .card p + p {
293
+ margin-top: 0.6rem;
 
 
 
 
 
294
  }
295
 
296
+ /* --- figures ------------------------------------------------------------ */
297
+
298
+ figure {
299
+ margin: 0 0 18px;
300
+ border: 1px solid var(--line);
301
+ border-radius: var(--radius);
302
+ overflow: hidden;
303
+ background: var(--bg-soft);
304
  }
305
 
306
+ figure img,
307
+ figure video {
308
+ width: 100%;
309
+ display: block;
 
 
 
 
 
 
310
  }
311
 
312
+ figcaption {
313
+ font-size: 0.82rem;
314
+ color: var(--fg-muted);
315
+ padding: 10px 14px;
316
+ border-top: 1px solid var(--line);
317
+ background: var(--bg);
318
  }
319
 
320
+ figcaption b {
321
+ color: var(--fg);
322
+ font-weight: 600;
 
 
323
  }
324
 
325
+ .figure-grid {
326
+ display: grid;
327
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
328
+ gap: 14px;
 
 
 
 
 
329
  }
330
 
331
+ .figure-grid figure {
332
+ margin: 0;
 
333
  }
334
 
335
+ /* --- tables ------------------------------------------------------------- */
336
+
337
+ .table-scroll {
338
+ overflow-x: auto;
339
+ border: 1px solid var(--line);
340
+ border-radius: var(--radius);
 
 
341
  }
342
 
343
+ table {
344
+ border-collapse: collapse;
345
+ width: 100%;
346
+ font-size: 0.88rem;
347
+ min-width: 480px;
348
  }
349
 
350
+ th,
351
+ td {
352
+ text-align: left;
353
+ padding: 10px 14px;
354
+ border-bottom: 1px solid var(--line);
355
  }
356
 
357
+ th {
358
+ font-weight: 600;
359
+ font-size: 0.76rem;
360
+ letter-spacing: 0.05em;
361
+ text-transform: uppercase;
362
+ color: var(--fg-faint);
363
+ background: var(--bg-soft);
364
+ white-space: nowrap;
365
  }
366
 
367
+ tbody tr:last-child td {
368
+ border-bottom: 0;
 
 
369
  }
370
 
371
+ td code {
372
+ font-size: 0.85em;
 
 
 
 
373
  }
374
 
375
+ /* --- code --------------------------------------------------------------- */
376
+
377
+ .code {
378
+ border: 1px solid var(--line);
379
+ border-radius: var(--radius);
380
+ overflow: hidden;
381
+ background: var(--bg-code);
382
+ margin: 0 0 14px;
383
  }
384
 
385
+ .code-tabs {
386
+ display: flex;
387
+ gap: 2px;
388
+ padding: 6px 6px 0;
389
+ border-bottom: 1px solid var(--line);
390
+ background: var(--bg-soft);
391
  }
392
 
393
+ .code-tabs button {
394
+ appearance: none;
395
+ border: 0;
396
+ background: transparent;
397
+ font-family: var(--mono);
398
+ font-size: 0.78rem;
399
+ color: var(--fg-muted);
400
+ padding: 7px 12px;
401
+ border-radius: var(--radius-sm) var(--radius-sm) 0 0;
402
+ cursor: pointer;
403
+ line-height: 1;
404
  }
405
 
406
+ .code-tabs button:hover {
407
+ color: var(--fg);
 
 
408
  }
409
 
410
+ .code-tabs button[aria-selected="true"] {
411
+ background: var(--bg-code);
412
+ color: var(--fg);
413
+ font-weight: 600;
414
+ box-shadow: inset 0 -1px 0 var(--bg-code);
 
415
  }
416
 
417
+ .code pre {
418
+ margin: 0;
419
+ padding: 16px 18px;
420
+ overflow-x: auto;
421
+ font-family: var(--mono);
422
+ font-size: 0.815rem;
423
+ line-height: 1.65;
424
+ tab-size: 2;
425
  }
426
 
427
+ .code pre[hidden] {
428
+ display: none;
429
  }
430
 
431
+ code {
432
+ font-family: var(--mono);
433
+ font-size: 0.88em;
 
434
  }
435
 
436
+ p code,
437
+ li code {
438
+ background: var(--bg-code);
439
+ border: 1px solid var(--line);
440
+ border-radius: 4px;
441
+ padding: 1px 5px;
442
  }
443
 
444
+ /* --- links list --------------------------------------------------------- */
445
+
446
+ .links {
447
+ display: grid;
448
+ grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
449
+ gap: 10px;
450
+ list-style: none;
451
+ padding: 0;
452
+ margin: 0;
453
  }
454
 
455
+ .links a {
456
+ display: flex;
457
+ align-items: baseline;
458
+ justify-content: space-between;
459
+ gap: 10px;
460
+ border: 1px solid var(--line);
461
+ border-radius: var(--radius-sm);
462
+ padding: 11px 14px;
463
+ color: var(--fg);
464
+ font-size: 0.9rem;
465
+ font-weight: 500;
466
  }
467
 
468
+ .links a:hover {
469
+ border-color: var(--line-strong);
470
+ background: var(--bg-soft);
471
+ text-decoration: none;
 
 
472
  }
473
 
474
+ .links .host {
475
+ font-family: var(--mono);
476
+ font-size: 0.72rem;
477
+ color: var(--fg-faint);
478
+ font-weight: 400;
479
  }
480
 
481
+ /* --- run-it callout (the one place we ask for a click) ------------------- */
482
+
483
+ .callout {
484
+ border: 1px solid var(--line);
485
+ border-left: 3px solid var(--accent);
486
+ background: var(--bg-soft);
487
+ border-radius: var(--radius-sm);
488
+ padding: 16px 18px;
489
+ font-size: 0.92rem;
490
+ color: var(--fg-muted);
491
  }
492
 
493
+ .callout p {
494
+ margin: 0;
 
 
 
 
 
495
  }
496
 
497
+ .callout p + p {
498
+ margin-top: 0.5rem;
 
499
  }
500
 
501
+ .btn-row {
502
+ display: flex;
503
+ flex-wrap: wrap;
504
+ gap: 10px;
505
+ margin-top: 18px;
506
  }
507
 
508
+ .btn {
509
+ display: inline-flex;
510
+ align-items: center;
511
+ gap: 7px;
512
+ border-radius: var(--radius-sm);
513
+ padding: 9px 16px;
514
+ font-size: 0.89rem;
515
+ font-weight: 550;
516
+ border: 1px solid var(--accent);
517
+ background: var(--accent);
518
+ color: #fff;
519
+ line-height: 1.4;
520
  }
521
 
522
+ .btn:hover {
523
+ text-decoration: none;
524
+ filter: brightness(1.08);
 
 
 
525
  }
526
 
527
+ .btn.secondary {
528
+ background: transparent;
529
+ color: var(--fg);
530
+ border-color: var(--line-strong);
531
  }
532
 
533
+ .btn.secondary:hover {
534
+ background: var(--bg-soft);
535
+ filter: none;
 
 
536
  }
537
 
538
+ @media (prefers-color-scheme: dark) {
539
+ .btn {
540
+ color: #0e1014;
541
+ }
 
 
 
542
  }
543
 
544
+ /* --- footer ------------------------------------------------------------- */
545
+
546
+ .site-footer {
547
+ margin-top: 64px;
548
+ border-top: 1px solid var(--line);
549
+ padding: 26px 0 44px;
550
+ font-size: 0.83rem;
551
+ color: var(--fg-faint);
552
  }
553
 
554
+ .site-footer .wrap {
555
+ display: flex;
556
+ flex-wrap: wrap;
557
+ gap: 10px 24px;
558
+ align-items: baseline;
559
+ justify-content: space-between;
560
  }
561
 
562
+ .site-footer a {
563
+ color: var(--fg-muted);
 
 
 
 
564
  }
565
 
566
+ .site-footer p {
567
+ margin: 0;
568
+ max-width: 60ch;
569
  }
570
 
571
+ .footer-links {
572
+ display: flex;
573
+ gap: 16px;
574
+ flex-wrap: wrap;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
tabs.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Code-sample tab switcher. Progressive enhancement: with JS disabled every
2
+ // panel except the first stays hidden via the `hidden` attribute in the markup,
3
+ // so the page still shows one working example.
4
+ document.querySelectorAll(".code-tabs").forEach((tabs) => {
5
+ const buttons = [...tabs.querySelectorAll("button")];
6
+ const panels = buttons.map((b) => document.getElementById(b.dataset.panel));
7
+
8
+ const select = (i) => {
9
+ buttons.forEach((b, j) => b.setAttribute("aria-selected", String(i === j)));
10
+ panels.forEach((p, j) => p && (p.hidden = i !== j));
11
+ };
12
+
13
+ buttons.forEach((b, i) => b.addEventListener("click", () => select(i)));
14
+ select(0);
15
+ });