PluginProbe
AI Builder – Generate pages, blocks, images & translate with AI / trunk
AI Builder – Generate pages, blocks, images & translate with AI vtrunk
2.7.9 2.7.8 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.3.10 2.3.11 All 121 releases
ai-builder / admin / pages / credits.php

credits.php in AI Builder – Generate pages, blocks, images & translate with AI trunk, at admin/pages/credits.php

1,277 lines 45.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH'))
3 exit; // Exit if accessed directly
4
5 // Vérifier si l'utilisateur a un token JWT
6 $jwt_token = get_option('aibui_jwt_token', '');
7 if (empty($jwt_token)) {
8 echo '<div class="ai-auth-container"><div class="ai-message error">' . esc_html__('Please sign in to access your credits.', 'ai-builder') . '</div></div>';
9 return;
10 }
11 ?>
12
13 <?php if (function_exists('aibui_render_onboarding_blocks')) { aibui_render_onboarding_blocks(); } ?>
14
15 <div class="ai-credits-container ai-fade-in">
16 <!-- Header -->
17 <div class="ai-credits-header">
18 <h1>AI Credits & Subscription</h1>
19 <p>Manage your AI credits and subscription plan</p>
20 </div>
21
22 <!-- Current Status -->
23 <div class="ai-status-section">
24 <div class="ai-status-card">
25 <div class="ai-status-icon">
26 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
27 <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" />
28 <path d="M12 6V12L16 14" stroke="currentColor" stroke-width="2" stroke-linecap="round"
29 stroke-linejoin="round" />
30 </svg>
31 </div>
32 <div class="ai-status-content">
33 <h3>Current Credits</h3>
34 <div class="ai-credits-display" id="current-credits">
35 <span class="ai-loading" style="display: none;"></span>
36 Loading...
37 </div>
38 </div>
39 </div>
40
41 <div class="ai-status-card">
42 <div class="ai-status-icon">
43 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
44 <path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="currentColor" stroke-width="2"
45 stroke-linejoin="round" />
46 <path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
47 <path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
48 </svg>
49 </div>
50 <div class="ai-status-content">
51 <h3>Subscription Plan</h3>
52 <div class="ai-plan-display" id="current-plan">
53 <span class="ai-loading" style="display: none;"></span>
54 Loading...
55 </div>
56 </div>
57 </div>
58 </div>
59
60 <!-- Subscription Management -->
61 <div class="ai-section">
62 <div class="ai-section-header">
63 <h2>Subscription Management</h2>
64 <p>Choose the perfect plan for your AI needs</p>
65 </div>
66
67 <div class="ai-subscription-note">
68 Cancel anytime your generated content stays on your site.
69 </div>
70
71 <!-- Monthly / Yearly billing toggle -->
72 <div class="ai-billing-toggle" role="tablist" aria-label="Billing period">
73 <button type="button" class="ai-billing-option is-active" data-billing="monthly" role="tab" aria-selected="true">
74 Monthly
75 </button>
76 <button type="button" class="ai-billing-option" data-billing="yearly" role="tab" aria-selected="false">
77 Yearly
78 <span class="ai-billing-save">Save up to 17%</span>
79 </button>
80 </div>
81
82 <div class="ai-subscription-actions" id="subscription-plans-container">
83 <!-- Plan Essential -->
84 <div class="ai-plan-card-wrapper"
85 data-plan="essential"
86 data-monthly-price="9"
87 data-yearly-price="90"
88 data-monthly-type="essential"
89 data-yearly-type="essential_year"
90 data-monthly-credits="750">
91 <div class="ai-plan-card ai-plan-essential">
92 <div class="ai-plan-header">
93 <div class="ai-plan-title">
94 <h3>Starter</h3>
95 <p class="ai-plan-persona">Best for discovering AI Builder and creating your first pages.</p>
96 </div>
97 </div>
98
99 <div class="ai-plan-features">
100 <div class="ai-feature-item">
101 <div class="ai-feature-icon">
102 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
103 xmlns="http://www.w3.org/2000/svg">
104 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
105 stroke-linecap="round" stroke-linejoin="round" />
106 </svg>
107 </div>
108 <span class="ai-feature-text">750 credits every month</span>
109 </div>
110
111 <div class="ai-feature-item">
112 <div class="ai-feature-icon">
113 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
114 xmlns="http://www.w3.org/2000/svg">
115 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
116 stroke-linecap="round" stroke-linejoin="round" />
117 </svg>
118 </div>
119 <span class="ai-feature-text">Generation of pages, blocks, images & texts</span>
120 </div>
121
122
123 <div class="ai-feature-item">
124 <div class="ai-feature-icon">
125 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
126 xmlns="http://www.w3.org/2000/svg">
127 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
128 stroke-linecap="round" stroke-linejoin="round" />
129 </svg>
130 </div>
131 <span class="ai-feature-text">Extra credits available on demand</span>
132 </div>
133 </div>
134
135 <div class="ai-plan-header">
136 <div class="ai-plan-title">
137 <div class="ai-plan-price">
138 <span class="ai-price-old" hidden>$9</span>
139 <span class="ai-price-amount">$9</span>
140 <span class="ai-price-period">/month</span>
141 </div>
142 <span class="ai-price-credit">$0.012 per credit</span>
143 <span class="ai-price-billed" hidden>Billed annually at $90/year</span>
144 </div>
145 </div>
146
147 <div class="ai-plan-cta">
148 <button type="button" class="ai-cta-btn ai-plan-btn" data-subscription-type="essential">
149 <span class="ai-loading" style="display: none;"></span>
150 <span class="btn-text">Choose Starter</span>
151 </button>
152 </div>
153 </div>
154 </div>
155
156 <!-- Plan Premium -->
157 <div class="ai-plan-card-wrapper"
158 data-plan="premium"
159 data-monthly-price="19"
160 data-yearly-price="190"
161 data-monthly-type="premium"
162 data-yearly-type="premium_year"
163 data-monthly-credits="2000">
164 <div class="ai-plan-card ai-plan-premium ai-plan-popular">
165 <div class="ai-plan-badge ai-plan-badge-popular">Most Popular</div>
166 <div class="ai-plan-header">
167 <div class="ai-plan-title">
168 <h3>Pro</h3>
169 <p class="ai-plan-persona">Best for creators who need more credits and advanced features to build faster.</p>
170 </div>
171 </div>
172
173 <div class="ai-plan-features">
174 <div class="ai-feature-item">
175 <div class="ai-feature-icon">
176 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
177 xmlns="http://www.w3.org/2000/svg">
178 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
179 stroke-linecap="round" stroke-linejoin="round" />
180 </svg>
181 </div>
182 <span class="ai-feature-text">2000 credits every month</span>
183 </div>
184
185 <div class="ai-feature-item">
186 <div class="ai-feature-icon">
187 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
188 xmlns="http://www.w3.org/2000/svg">
189 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
190 stroke-linecap="round" stroke-linejoin="round" />
191 </svg>
192 </div>
193 <span class="ai-feature-text">Generation of pages, blocks, images & texts</span>
194 </div>
195
196
197 <div class="ai-feature-item">
198 <div class="ai-feature-icon">
199 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
200 xmlns="http://www.w3.org/2000/svg">
201 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
202 stroke-linecap="round" stroke-linejoin="round" />
203 </svg>
204 </div>
205 <span class="ai-feature-text">Multi Page Generator</span>
206 </div>
207
208 <div class="ai-feature-item">
209 <div class="ai-feature-icon">
210 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
211 xmlns="http://www.w3.org/2000/svg">
212 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
213 stroke-linecap="round" stroke-linejoin="round" />
214 </svg>
215 </div>
216 <span class="ai-feature-text">Extra credits available on demand</span>
217 </div>
218 </div>
219
220 <div class="ai-plan-header">
221 <div class="ai-plan-title">
222 <div class="ai-plan-price">
223 <span class="ai-price-old" hidden>$19</span>
224 <span class="ai-price-amount">$19</span>
225 <span class="ai-price-period">/month</span>
226 </div>
227 <span class="ai-price-credit">$0.009 per credit</span>
228 <span class="ai-price-billed" hidden>Billed annually at $190/year</span>
229 </div>
230 </div>
231
232 <div class="ai-plan-cta">
233 <button type="button" class="ai-cta-btn ai-plan-btn" data-subscription-type="premium">
234 <span class="ai-loading" style="display: none;"></span>
235 <span class="btn-text">Choose Pro</span>
236 </button>
237 </div>
238 </div>
239 </div>
240
241 <!-- Plan Creator -->
242 <div class="ai-plan-card-wrapper"
243 data-plan="creator"
244 data-monthly-price="49"
245 data-yearly-price="490"
246 data-monthly-type="creator"
247 data-yearly-type="creator_year"
248 data-monthly-credits="6000">
249 <div class="ai-plan-card ai-plan-creator">
250 <div class="ai-plan-header">
251 <div class="ai-plan-title">
252 <h3>Agency</h3>
253 <p class="ai-plan-persona">Best for agencies and teams scaling production across many projects.</p>
254 </div>
255 </div>
256
257 <div class="ai-plan-features">
258 <div class="ai-feature-item">
259 <div class="ai-feature-icon">
260 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
261 xmlns="http://www.w3.org/2000/svg">
262 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
263 stroke-linecap="round" stroke-linejoin="round" />
264 </svg>
265 </div>
266 <span class="ai-feature-text">6000 credits every month</span>
267 </div>
268
269 <div class="ai-feature-item">
270 <div class="ai-feature-icon">
271 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
272 xmlns="http://www.w3.org/2000/svg">
273 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
274 stroke-linecap="round" stroke-linejoin="round" />
275 </svg>
276 </div>
277 <span class="ai-feature-text">Generation of pages, blocks, images & texts</span>
278 </div>
279
280
281 <div class="ai-feature-item">
282 <div class="ai-feature-icon">
283 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
284 xmlns="http://www.w3.org/2000/svg">
285 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
286 stroke-linecap="round" stroke-linejoin="round" />
287 </svg>
288 </div>
289 <span class="ai-feature-text">Multi Page Generator</span>
290 </div>
291
292 <div class="ai-feature-item">
293 <div class="ai-feature-icon">
294 <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
295 xmlns="http://www.w3.org/2000/svg">
296 <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2.5"
297 stroke-linecap="round" stroke-linejoin="round" />
298 </svg>
299 </div>
300 <span class="ai-feature-text">Extra credits available on demand</span>
301 </div>
302 </div>
303
304 <div class="ai-plan-header">
305 <div class="ai-plan-title">
306 <div class="ai-plan-price">
307 <span class="ai-price-old" hidden>$49</span>
308 <span class="ai-price-amount">$49</span>
309 <span class="ai-price-period">/month</span>
310 </div>
311 <span class="ai-price-credit">$0.008 per credit</span>
312 <span class="ai-price-billed" hidden>Billed annually at $490/year</span>
313 </div>
314 </div>
315
316 <div class="ai-plan-cta">
317 <button type="button" class="ai-cta-btn ai-plan-btn" data-subscription-type="creator">
318 <span class="ai-loading" style="display: none;"></span>
319 <span class="btn-text">Choose Agency</span>
320 </button>
321 </div>
322 </div>
323 </div>
324 </div>
325
326 <div class="ai-section-header" style="margin-bottom: 120px;">
327 </div>
328 </div>
329
330
331
332 <!-- Credit Purchase (One-time top-up with custom amount) -->
333 <div class="ai-section" id="credit-purchase-section">
334 <div class="ai-section-header">
335 <h2>One-time top-up</h2>
336 <p id="credit-purchase-subtitle">Buy extra credits whenever you need them. Purchased credits never expire.</p>
337 </div>
338
339 <div class="ai-topup-card" id="credit-purchase-card" data-locked="false">
340 <!-- Overlay shown to users without an active subscription -->
341 <div class="ai-topup-lock" id="topup-lock-overlay" hidden>
342 <div class="ai-topup-lock-icon" aria-hidden="true">
343 <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
344 <rect x="3" y="11" width="18" height="11" rx="2" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
345 <path d="M7 11V7a5 5 0 0 1 10 0v4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
346 </svg>
347 </div>
348 <div class="ai-topup-lock-text">
349 <h3>Subscribe to unlock top-ups</h3>
350 <p>One-time credit purchases are available to subscribers only. Choose a plan above to activate this option.</p>
351 </div>
352 </div>
353
354 <div class="ai-topup-body">
355 <div class="ai-topup-header">
356 <div class="ai-topup-header-icon" aria-hidden="true">
357 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
358 <path d="M12 1V23" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
359 <path d="M17 5H9.5C8.57174 5 7.6815 5.36875 7.02513 6.02513C6.36875 6.6815 6 7.57174 6 8.5C6 9.42826 6.36875 10.3185 7.02513 10.9749C7.6815 11.6313 8.57174 12 9.5 12H14.5C15.4283 12 16.3185 12.3687 16.9749 13.0251C17.6313 13.6815 18 14.5717 18 15.5C18 16.4283 17.6313 17.3185 16.9749 17.9749C16.3185 18.6313 15.4283 19 14.5 19H6"
360 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
361 </svg>
362 </div>
363 <div class="ai-topup-header-text">
364 <h3>Choose your amount</h3>
365 <p>Rate: <strong>$0.012</strong> per credit · Credits never expire</p>
366 </div>
367 </div>
368
369 <div class="ai-topup-grid">
370 <div class="ai-topup-input-group">
371 <label for="topup-amount" class="ai-topup-label">Amount in USD</label>
372 <div class="ai-topup-amount-wrapper">
373 <span class="ai-topup-currency">$</span>
374 <input
375 type="number"
376 id="topup-amount"
377 class="ai-topup-amount-input"
378 min="5"
379 max="1200"
380 step="1"
381 value="10"
382 inputmode="numeric"
383 autocomplete="off"
384 />
385 </div>
386 <p class="ai-topup-range-info">Between <strong>$5</strong> and <strong>$1,200</strong>.</p>
387 <div class="ai-topup-presets" role="group" aria-label="Quick amount presets">
388 <button type="button" class="ai-topup-preset" data-amount="10">$10</button>
389 <button type="button" class="ai-topup-preset" data-amount="25">$25</button>
390 <button type="button" class="ai-topup-preset" data-amount="50">$50</button>
391 <button type="button" class="ai-topup-preset" data-amount="100">$100</button>
392 <button type="button" class="ai-topup-preset" data-amount="250">$250</button>
393 <button type="button" class="ai-topup-preset" data-amount="500">$500</button>
394 </div>
395 <p class="ai-topup-error" id="topup-error" role="alert" aria-live="polite"></p>
396 </div>
397
398 <div class="ai-topup-summary" aria-live="polite">
399 <div class="ai-topup-summary-row">
400 <span class="ai-topup-summary-label">You pay</span>
401 <span class="ai-topup-summary-value" id="topup-pay-amount">$10.00</span>
402 </div>
403 <div class="ai-topup-summary-arrow" aria-hidden="true">
404 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
405 <path d="M12 5V19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
406 <path d="M5 12L12 19L19 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
407 </svg>
408 </div>
409 <div class="ai-topup-summary-row ai-topup-summary-credits">
410 <span class="ai-topup-summary-label">You get</span>
411 <span class="ai-topup-summary-value" id="topup-credits-amount">833 credits</span>
412 </div>
413
414 <button type="button" class="ai-primary-btn ai-topup-btn" id="buy-credits-btn">
415 <span class="ai-loading" style="display: none;"></span>
416 <span class="btn-text">Purchase credits</span>
417 </button>
418
419 <p class="ai-topup-hint">Between $5 and $1,200. Credits are added instantly after payment.</p>
420 </div>
421 </div>
422 </div>
423 </div>
424 </div>
425
426 <!-- Account Management -->
427 <div class="ai-section">
428 <div class="ai-section-header">
429 <h2>Account Management</h2>
430 <p>Manage your billing and account settings</p>
431 </div>
432
433 <div class="ai-account-actions">
434 <div class="ai-action-card">
435 <div class="ai-action-icon">
436 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
437 <path
438 d="M20 21V19C20 17.9391 19.5786 16.9217 18.8284 16.1716C18.0783 15.4214 17.0609 15 16 15H8C6.93913 15 5.92172 15.4214 5.17157 16.1716C4.42143 16.9217 4 17.9391 4 19V21"
439 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
440 <circle cx="12" cy="7" r="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"
441 stroke-linejoin="round" />
442 </svg>
443 </div>
444 <div class="ai-action-content">
445 <h3>Stripe Account</h3>
446 <p>Access your Stripe dashboard for billing management</p>
447 <button type="button" class="ai-secondary-btn" onclick="handleStripeAccount()">
448 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
449 <path d="M18 13V19A2 2 0 0 1 16 21H8A2 2 0 0 1 6 19V13" stroke="currentColor"
450 stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
451 <path d="M12 3V15" stroke="currentColor" stroke-width="2" stroke-linecap="round"
452 stroke-linejoin="round" />
453 <path d="M9 6L12 3L15 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"
454 stroke-linejoin="round" />
455 </svg>
456 View Stripe Account
457 </button>
458 </div>
459 </div>
460 </div>
461 </div>
462
463 <!-- Manage Subscription (shown when user has active subscription) -->
464 <div class="ai-section">
465 <div class="ai-action-card" id="cancel-subscription-card" style="display: none;">
466 <div class="ai-action-icon">
467 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
468 <path d="M12 2V6" stroke="currentColor" stroke-width="2" stroke-linecap="round"
469 stroke-linejoin="round" />
470 <path d="M12 18V22" stroke="currentColor" stroke-width="2" stroke-linecap="round"
471 stroke-linejoin="round" />
472 <path d="M4.93 4.93L7.76 7.76" stroke="currentColor" stroke-width="2" stroke-linecap="round"
473 stroke-linejoin="round" />
474 <path d="M16.24 16.24L19.07 19.07" stroke="currentColor" stroke-width="2" stroke-linecap="round"
475 stroke-linejoin="round" />
476 <path d="M2 12H6" stroke="currentColor" stroke-width="2" stroke-linecap="round"
477 stroke-linejoin="round" />
478 <path d="M18 12H22" stroke="currentColor" stroke-width="2" stroke-linecap="round"
479 stroke-linejoin="round" />
480 <path d="M4.93 19.07L7.76 16.24" stroke="currentColor" stroke-width="2" stroke-linecap="round"
481 stroke-linejoin="round" />
482 <path d="M16.24 7.76L19.07 4.93" stroke="currentColor" stroke-width="2" stroke-linecap="round"
483 stroke-linejoin="round" />
484 </svg>
485 </div>
486 <div class="ai-action-content">
487 <h3>Manage Subscription</h3>
488 <button type="button" class="ai-cancel-subscription-btn" id="subscription-btn" style="opacity: 0.7; font-weight: 400;">
489 <span class="ai-loading" style="display: none;"></span>
490 <span class="btn-text">Cancel Subscription</span>
491 </button>
492 </div>
493 </div>
494 </div>
495
496 <!-- Messages -->
497 <div id="message-container"></div>
498 </div>
499
500 <!-- Confirmation Modal -->
501 <div id="confirmation-modal" class="ai-modal" style="display: none;">
502 <div class="ai-modal-content">
503 <div class="ai-modal-header">
504 <h3>Cancel Subscription</h3>
505 <button type="button" class="ai-modal-close" onclick="closeModal()">×</button>
506 </div>
507 <div class="ai-modal-body">
508 <p>Are you sure you want to cancel your subscription? You will lose access to monthly credits at the end of
509 your current billing period.</p>
510 <p style="margin-top: 16px; padding: 12px; background: #fef3c7; border-left: 3px solid #f59e0b; border-radius: 4px; color: #92400e;">
511 <strong>Important:</strong> Once your credits are used up, you will no longer be able to use AI features such as page translation and AI-powered content creation.
512 </p>
513 </div>
514 <div class="ai-modal-footer">
515 <button type="button" class="ai-secondary-btn" onclick="closeModal()">Keep Subscription</button>
516 <button type="button" class="ai-danger-btn" onclick="confirmCancelSubscription()">
517 <span class="ai-loading" style="display: none;"></span>
518 Yes, Cancel Subscription
519 </button>
520 </div>
521 </div>
522 </div>
523
524 <!-- Switch subscription confirmation modal -->
525 <div id="switch-subscription-modal" class="ai-modal" style="display: none;">
526 <div class="ai-modal-content">
527 <div class="ai-modal-header">
528 <h3>Switch your subscription</h3>
529 <button type="button" class="ai-modal-close" onclick="closeSwitchSubscriptionModal()">×</button>
530 </div>
531 <div class="ai-modal-body">
532 <p>
533 You are about to switch to the <strong id="switch-target-plan-label">—</strong> plan.
534 </p>
535 <p style="margin-top: 16px; padding: 12px; background: #eef2ff; border-left: 3px solid #4f46e5; border-radius: 4px; color: #3730a3;">
536 <strong>Heads up:</strong> this change takes effect <strong>immediately</strong>. Your billing will be adjusted accordingly from today.
537 </p>
538 </div>
539 <div class="ai-modal-footer">
540 <button type="button" class="ai-secondary-btn" onclick="closeSwitchSubscriptionModal()">Cancel</button>
541 <button type="button" class="ai-primary-btn" id="switch-subscription-confirm-btn" onclick="confirmSwitchSubscription()">
542 <span class="ai-loading" style="display: none;"></span>
543 <span class="btn-text">Confirm switch</span>
544 </button>
545 </div>
546 </div>
547 </div>
548
549 <style>
550 /* Subscription Plans Container */
551 .ai-subscription-actions {
552 display: grid;
553 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
554 gap: 24px;
555 margin-bottom: 24px;
556 }
557
558 .ai-subscription-note {
559 font-size: 13px;
560 color: #6b7280;
561 text-align: center;
562 margin-bottom: 16px;
563 max-width: 540px;
564 margin-left: auto;
565 margin-right: auto;
566 }
567
568 /* ============================================================== */
569 /* Monthly / Yearly billing toggle */
570 /* ============================================================== */
571 .ai-billing-toggle {
572 display: inline-flex;
573 align-items: stretch;
574 background: #f1f5f9;
575 border: 1px solid #e2e8f0;
576 border-radius: 999px;
577 padding: 4px;
578 margin: 0 auto 24px;
579 gap: 4px;
580 position: relative;
581 left: 50%;
582 transform: translateX(-50%);
583 }
584
585 .ai-billing-option {
586 appearance: none;
587 border: none;
588 background: transparent;
589 color: #475569;
590 font-size: 14px;
591 font-weight: 600;
592 padding: 10px 22px;
593 border-radius: 999px;
594 cursor: pointer;
595 display: inline-flex;
596 align-items: center;
597 gap: 8px;
598 transition: color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
599 white-space: nowrap;
600 }
601
602 .ai-billing-option:hover:not(.is-active) {
603 color: #1e293b;
604 }
605
606 .ai-billing-option.is-active {
607 background: #ffffff;
608 color: #0f172a;
609 box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
610 }
611
612 .ai-billing-save {
613 font-size: 11px;
614 font-weight: 700;
615 letter-spacing: 0.3px;
616 color: #047857;
617 background: rgba(16, 185, 129, 0.12);
618 border: 1px solid rgba(16, 185, 129, 0.25);
619 padding: 3px 8px;
620 border-radius: 999px;
621 text-transform: uppercase;
622 }
623
624 /* Struck-through "was" monthly price shown in yearly mode */
625 .ai-price-old {
626 font-size: 22px;
627 font-weight: 500;
628 color: #94a3b8;
629 text-decoration: line-through;
630 text-decoration-thickness: 2px;
631 margin-right: 4px;
632 }
633
634 /* Billed annually note under the price */
635 .ai-price-billed {
636 display: block;
637 margin-top: 6px;
638 font-size: 12px;
639 font-weight: 500;
640 color: #475569;
641 }
642
643 /* La règle ci-dessus (display:block) écraserait l'attribut [hidden] sans
644 cette override (cf. même pattern que .ai-topup-lock). */
645 .ai-price-billed[hidden] {
646 display: none !important;
647 }
648
649 #credit-purchase-card .ai-credit-pack-persona {
650 text-align: center;
651 max-width: 420px;
652 margin-left: auto;
653 margin-right: auto;
654 margin-bottom: 8px;
655 }
656
657 .ai-plan-card-wrapper {
658 position: relative;
659 }
660
661 /* Modern Plan Card Styles */
662 .ai-plan-card {
663 --plan-accent: #4f46e5;
664 background: #ffffff;
665 border-radius: 16px;
666 padding: 32px;
667 color: #0f172a;
668 box-shadow: 0 18px 30px rgba(15, 23, 42, 0.07);
669 border: 1px solid #e4e8ef;
670 position: relative;
671 overflow: hidden;
672 transition: all 0.3s ease;
673 height: 100%;
674 display: flex;
675 flex-direction: column;
676 }
677
678 .ai-plan-card:hover {
679 transform: translateY(-4px);
680 box-shadow: 0 24px 45px rgba(15, 23, 42, 0.12);
681 }
682
683 .ai-plan-card::before {
684 content: '';
685 position: absolute;
686 top: 0;
687 left: 16px;
688 right: 16px;
689 height: 3px;
690 border-radius: 999px;
691 background: linear-gradient(90deg, var(--plan-accent), rgba(79, 70, 229, 0.1));
692 }
693
694 .ai-plan-card>* {
695 position: relative;
696 z-index: 1;
697 }
698
699 /* Plan Badge */
700 .ai-plan-badge {
701 position: absolute;
702 top: 18px;
703 right: 18px;
704 background: rgba(15, 23, 42, 0.08);
705 color: #0f172a;
706 padding: 6px 14px;
707 border-radius: 999px;
708 font-size: 11px;
709 font-weight: 600;
710 text-transform: uppercase;
711 letter-spacing: 0.6px;
712 line-height: 1.2;
713 max-width: calc(100% - 36px);
714 box-sizing: border-box;
715 }
716
717 .ai-plan-badge-popular {
718 background: rgba(79, 70, 229, 0.12);
719 color: #4338ca;
720 top: 14px;
721 right: 14px;
722 font-size: 10px;
723 padding: 5px 10px;
724 letter-spacing: 0.4px;
725 }
726
727 /* Plan Colors */
728 .ai-plan-essential {
729 --plan-accent: #1d4ed8;
730 }
731
732 .ai-plan-premium {
733 --plan-accent: #7c3aed;
734 }
735
736 .ai-plan-creator {
737 --plan-accent: #db2777;
738 }
739
740 .ai-plan-popular {
741 box-shadow: 0 24px 45px rgba(76, 29, 149, 0.18);
742 border-color: rgba(76, 29, 149, 0.2);
743 }
744
745 .ai-plan-header {
746 text-align: center;
747 margin-bottom: 24px;
748 }
749
750 .ai-plan-header:first-of-type {
751 margin-top: 16px;
752 }
753
754 .ai-plan-title h3 {
755 font-size: 26px;
756 font-weight: 600;
757 margin: 0 0 6px 0;
758 color: #0f172a;
759 }
760
761 .ai-plan-persona {
762 margin: 0;
763 font-size: 13px;
764 line-height: 1.5;
765 color: #64748b;
766 max-width: 300px;
767 margin-left: auto;
768 margin-right: auto;
769 }
770
771 .ai-plan-price {
772 display: flex;
773 align-items: baseline;
774 justify-content: center;
775 gap: 4px;
776 }
777
778 .ai-price-amount {
779 font-size: 38px;
780 font-weight: 600;
781 color: #0f172a;
782 margin-top: 12px;
783 }
784
785 .ai-price-period {
786 font-size: 16px;
787 font-weight: 500;
788 color: #6b7280;
789 }
790
791 .ai-plan-features {
792 margin-bottom: 24px;
793 flex-grow: 1;
794 }
795
796 .ai-feature-item {
797 display: flex;
798 align-items: center;
799 gap: 12px;
800 margin-bottom: 16px;
801 padding: 12px 16px;
802 background: #f8fafc;
803 border-radius: 12px;
804 border: 1px solid #e2e8f0;
805 transition: all 0.3s ease;
806 }
807
808 .ai-feature-item:hover {
809 border-color: rgba(79, 70, 229, 0.4);
810 transform: translateX(4px);
811 }
812
813 .ai-feature-icon {
814 flex-shrink: 0;
815 width: 32px;
816 height: 32px;
817 background: rgba(79, 70, 229, 0.12);
818 border-radius: 50%;
819 display: flex;
820 align-items: center;
821 justify-content: center;
822 color: var(--plan-accent);
823 border: 1px solid rgba(79, 70, 229, 0.2);
824 }
825
826 .ai-feature-text {
827 font-size: 16px;
828 font-weight: 500;
829 color: #0f172a;
830 line-height: 1.4;
831 }
832
833 .ai-plan-cta {
834 text-align: center;
835 }
836
837 .ai-cta-btn {
838 background: var(--plan-accent);
839 color: #fff;
840 border: 2px solid var(--plan-accent);
841 padding: 14px 28px;
842 border-radius: 12px;
843 font-size: 16px;
844 font-weight: 600;
845 display: inline-flex;
846 align-items: center;
847 justify-content: center;
848 gap: 8px;
849 cursor: pointer;
850 transition: all 0.3s ease;
851 box-shadow: 0 10px 25px rgba(79, 70, 229, 0.25);
852 text-transform: none;
853 letter-spacing: 0;
854 width: 100%;
855 backdrop-filter: none;
856 }
857
858 .ai-cta-btn:hover {
859 background: #fff;
860 color: var(--plan-accent);
861 transform: translateY(-2px);
862 box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
863 }
864
865 .ai-cta-btn:active {
866 transform: translateY(0);
867 }
868
869 .ai-cta-btn:disabled {
870 opacity: 0.6;
871 cursor: not-allowed;
872 transform: none;
873 }
874
875 .ai-plan-btn.current-plan {
876 background: rgba(79, 70, 229, 0.08);
877 border-color: rgba(79, 70, 229, 0.2);
878 cursor: default;
879 }
880
881 .ai-plan-btn.current-plan:hover {
882 transform: none;
883 }
884
885 /* Action Card Container */
886 .ai-action-card {
887 background: white;
888 border-radius: 16px;
889 padding: 32px;
890 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
891 border: 1px solid rgba(0, 0, 0, 0.06);
892 transition: all 0.3s ease;
893 }
894
895 .ai-action-card:hover {
896 transform: translateY(-4px);
897 box-shadow: 0 16px 48px rgba(0, 0, 0, 0.12);
898 }
899
900 /* Current Plan Indicator */
901 .ai-plan-card-wrapper[data-current-plan="true"] .ai-plan-card {
902 border: 3px solid rgba(255, 255, 255, 0.8);
903 box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.3), 0 24px 48px rgba(102, 126, 234, 0.3);
904 }
905
906 /* Responsive Design */
907 @media (max-width: 768px) {
908 .ai-subscription-actions {
909 grid-template-columns: 1fr;
910 }
911
912 .ai-plan-card {
913 padding: 24px;
914 }
915
916 .ai-price-amount {
917 font-size: 36px;
918 }
919
920 .ai-feature-item {
921 padding: 10px 12px;
922 }
923
924 .ai-cta-btn {
925 padding: 12px 24px;
926 font-size: 15px;
927 }
928
929 .ai-plan-badge {
930 font-size: 10px;
931 padding: 4px 8px;
932 }
933 }
934
935 /* ============================================================== */
936 /* One-time top-up (custom amount) */
937 /* ============================================================== */
938 .ai-topup-card {
939 position: relative;
940 background: #ffffff;
941 border-radius: 16px;
942 padding: 32px;
943 box-shadow: 0 18px 30px rgba(15, 23, 42, 0.07);
944 border: 1px solid #e4e8ef;
945 overflow: hidden;
946 transition: box-shadow 0.3s ease, transform 0.3s ease;
947 }
948
949 .ai-topup-card::before {
950 content: '';
951 position: absolute;
952 top: 0;
953 left: 16px;
954 right: 16px;
955 height: 3px;
956 border-radius: 999px;
957 background: linear-gradient(90deg, #4f46e5, rgba(79, 70, 229, 0.1));
958 }
959
960 .ai-topup-card[data-locked="true"] .ai-topup-body {
961 filter: blur(2px) grayscale(0.2);
962 opacity: 0.55;
963 pointer-events: none;
964 user-select: none;
965 }
966
967 .ai-topup-lock {
968 position: absolute;
969 inset: 0;
970 z-index: 2;
971 display: flex;
972 flex-direction: column;
973 align-items: center;
974 justify-content: center;
975 gap: 14px;
976 padding: 32px;
977 text-align: center;
978 background: rgba(255, 255, 255, 0.72);
979 backdrop-filter: blur(2px);
980 -webkit-backdrop-filter: blur(2px);
981 }
982
983 /* La règle .ai-topup-lock (display:flex) a une spécificité plus forte que
984 [hidden] (qui applique display:none via l'UA stylesheet). Sans cette
985 règle, lockOverlay.hidden = true ne masquerait pas l'overlay. */
986 .ai-topup-lock[hidden] {
987 display: none !important;
988 }
989
990 .ai-topup-lock-icon {
991 width: 56px;
992 height: 56px;
993 border-radius: 50%;
994 display: flex;
995 align-items: center;
996 justify-content: center;
997 background: rgba(79, 70, 229, 0.12);
998 color: #4338ca;
999 border: 1px solid rgba(79, 70, 229, 0.2);
1000 }
1001
1002 .ai-topup-lock-text h3 {
1003 margin: 0 0 6px 0;
1004 font-size: 18px;
1005 font-weight: 600;
1006 color: #0f172a;
1007 }
1008
1009 .ai-topup-lock-text p {
1010 margin: 0;
1011 font-size: 14px;
1012 color: #475569;
1013 max-width: 420px;
1014 line-height: 1.5;
1015 }
1016
1017 .ai-topup-header {
1018 display: flex;
1019 align-items: center;
1020 gap: 14px;
1021 margin-bottom: 24px;
1022 }
1023
1024 .ai-topup-header-icon {
1025 flex-shrink: 0;
1026 width: 44px;
1027 height: 44px;
1028 border-radius: 12px;
1029 display: flex;
1030 align-items: center;
1031 justify-content: center;
1032 background: rgba(79, 70, 229, 0.12);
1033 color: #4338ca;
1034 border: 1px solid rgba(79, 70, 229, 0.2);
1035 }
1036
1037 .ai-topup-header-text h3 {
1038 margin: 0 0 2px 0;
1039 font-size: 18px;
1040 font-weight: 600;
1041 color: #0f172a;
1042 }
1043
1044 .ai-topup-header-text p {
1045 margin: 0;
1046 font-size: 13px;
1047 color: #64748b;
1048 }
1049
1050 .ai-topup-header-text strong {
1051 color: #0f172a;
1052 font-weight: 600;
1053 }
1054
1055 .ai-topup-grid {
1056 display: grid;
1057 grid-template-columns: 1.2fr 1fr;
1058 gap: 28px;
1059 align-items: stretch;
1060 }
1061
1062 .ai-topup-input-group {
1063 display: flex;
1064 flex-direction: column;
1065 gap: 12px;
1066 }
1067
1068 .ai-topup-label {
1069 font-size: 13px;
1070 font-weight: 600;
1071 color: #334155;
1072 letter-spacing: 0.2px;
1073 }
1074
1075 .ai-topup-amount-wrapper {
1076 position: relative;
1077 display: flex;
1078 align-items: center;
1079 background: #f8fafc;
1080 border: 1px solid #e2e8f0;
1081 border-radius: 12px;
1082 transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
1083 }
1084
1085 .ai-topup-amount-wrapper:focus-within {
1086 border-color: #4f46e5;
1087 background: #ffffff;
1088 box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.12);
1089 }
1090
1091 .ai-topup-amount-wrapper.has-error {
1092 border-color: #ef4444;
1093 box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.12);
1094 }
1095
1096 .ai-topup-currency {
1097 padding: 0 14px 0 18px;
1098 font-size: 24px;
1099 font-weight: 600;
1100 color: #64748b;
1101 }
1102
1103 .ai-topup-amount-input {
1104 flex: 1;
1105 width: 100%;
1106 border: none;
1107 background: transparent;
1108 padding: 16px 18px 16px 0;
1109 font-size: 28px;
1110 font-weight: 600;
1111 color: #0f172a;
1112 outline: none;
1113 -moz-appearance: textfield;
1114 }
1115
1116 .ai-topup-amount-input::-webkit-outer-spin-button,
1117 .ai-topup-amount-input::-webkit-inner-spin-button {
1118 -webkit-appearance: none;
1119 margin: 0;
1120 }
1121
1122 .ai-topup-range-info {
1123 margin: 0;
1124 font-size: 12px;
1125 color: #94a3b8;
1126 }
1127
1128 .ai-topup-range-info strong {
1129 color: #475569;
1130 font-weight: 600;
1131 }
1132
1133 .ai-topup-presets {
1134 display: flex;
1135 flex-wrap: wrap;
1136 gap: 8px;
1137 margin-top: 4px;
1138 }
1139
1140 .ai-topup-preset {
1141 appearance: none;
1142 border: 1px solid #e2e8f0;
1143 background: #ffffff;
1144 color: #475569;
1145 padding: 8px 14px;
1146 border-radius: 999px;
1147 font-size: 13px;
1148 font-weight: 600;
1149 cursor: pointer;
1150 transition: all 0.2s ease;
1151 }
1152
1153 .ai-topup-preset:hover {
1154 border-color: #4f46e5;
1155 color: #4338ca;
1156 background: rgba(79, 70, 229, 0.06);
1157 }
1158
1159 .ai-topup-preset.is-active {
1160 border-color: #4f46e5;
1161 background: rgba(79, 70, 229, 0.1);
1162 color: #4338ca;
1163 }
1164
1165 .ai-topup-error {
1166 margin: 0;
1167 min-height: 18px;
1168 font-size: 12px;
1169 color: #dc2626;
1170 font-weight: 500;
1171 }
1172
1173 .ai-topup-summary {
1174 display: flex;
1175 flex-direction: column;
1176 gap: 12px;
1177 background: linear-gradient(160deg, rgba(79, 70, 229, 0.08), rgba(124, 58, 237, 0.05));
1178 border: 1px solid rgba(79, 70, 229, 0.15);
1179 border-radius: 14px;
1180 padding: 22px;
1181 }
1182
1183 .ai-topup-summary-row {
1184 display: flex;
1185 align-items: baseline;
1186 justify-content: space-between;
1187 gap: 12px;
1188 }
1189
1190 .ai-topup-summary-label {
1191 font-size: 13px;
1192 color: #64748b;
1193 font-weight: 500;
1194 }
1195
1196 .ai-topup-summary-value {
1197 font-size: 22px;
1198 font-weight: 700;
1199 color: #0f172a;
1200 }
1201
1202 .ai-topup-summary-credits .ai-topup-summary-value {
1203 color: #4338ca;
1204 font-size: 26px;
1205 }
1206
1207 .ai-topup-summary-arrow {
1208 display: flex;
1209 justify-content: center;
1210 color: #94a3b8;
1211 }
1212
1213 .ai-topup-btn {
1214 margin-top: 6px;
1215 padding: 14px 22px;
1216 font-size: 15px;
1217 font-weight: 600;
1218 width: 100%;
1219 display: inline-flex;
1220 align-items: center;
1221 justify-content: center;
1222 gap: 8px;
1223 }
1224
1225 .ai-topup-btn:disabled {
1226 opacity: 0.6;
1227 cursor: not-allowed;
1228 }
1229
1230 .ai-topup-hint {
1231 margin: 0;
1232 font-size: 12px;
1233 color: #64748b;
1234 text-align: center;
1235 line-height: 1.4;
1236 }
1237
1238 @media (max-width: 768px) {
1239 .ai-topup-card {
1240 padding: 24px;
1241 }
1242
1243 .ai-topup-grid {
1244 grid-template-columns: 1fr;
1245 gap: 20px;
1246 }
1247
1248 .ai-topup-amount-input {
1249 font-size: 24px;
1250 padding: 14px 14px 14px 0;
1251 }
1252
1253 .ai-topup-currency {
1254 font-size: 20px;
1255 padding: 0 10px 0 14px;
1256 }
1257
1258 .ai-topup-summary-credits .ai-topup-summary-value {
1259 font-size: 22px;
1260 }
1261 }
1262
1263 /* Animation for loading states */
1264 .ai-loading {
1265 animation: spin 1s linear infinite;
1266 }
1267
1268 @keyframes spin {
1269 from {
1270 transform: rotate(0deg);
1271 }
1272
1273 to {
1274 transform: rotate(360deg);
1275 }
1276 }
1277 </style>