pierreguillou commited on
Commit
7d5cf64
·
verified ·
1 Parent(s): bb0deeb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -402
app.py CHANGED
@@ -268,357 +268,8 @@ def update_api_info(model_name):
268
  with gr.Blocks(
269
  title="EduHTML Creator - Educational HTML Content Generator",
270
  theme=gr.themes.Soft(),
271
- css="""
272
- /* ==== Apple-inspired Global Reset & Typography ==== */
273
- :root {
274
- --apple-black: #0000;
275
- --apple-white: #ffff;
276
- --apple-grey-50: #f5f5f7;
277
- --apple-grey-100: #efeff4; /* iOS group background */
278
- --apple-grey-200: #e5e5ea;
279
- --apple-grey-300: #d1d1d6;
280
- --apple-grey-600: #8e8e93;
281
- --apple-blue: #007aff;
282
- --apple-blue-hover: #0056cc;
283
- --apple-green: #34c759;
284
- --apple-red: #ff3b30;
285
- --shadow-soft: 0 8px 30px rgba(0,0,0,0.08);
286
- --radius-lg: 14px;
287
- --radius-md: 12px;
288
- --radius-sm: 10px;
289
- --transition: all 0.3s ease;
290
- --text-color: #1d1d1f;
291
- --link-underline-offset: 2px;
292
- }
293
-
294
- * { box-sizing: border-box; }
295
- html, body {
296
- font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
297
- color: var(--text-color);
298
- background: var(--apple-grey-50);
299
- -webkit-font-smoothing: antialiased;
300
- -moz-osx-font-smoothing: grayscale;
301
- }
302
-
303
- /* ==== Layout Containers ==== */
304
- .main-container {
305
- max-width: 1100px;
306
- margin: 0 auto;
307
- padding: 24px;
308
- }
309
-
310
- /* Fixed top nav (subtle, Apple-like) */
311
- .top-nav {
312
- position: sticky;
313
- top: 0;
314
- z-index: 1000;
315
- backdrop-filter: saturate(180%) blur(12px);
316
- background: rgba(250,250,252,0.72);
317
- border-bottom: 1px solid rgba(0,0,0,0.06);
318
- }
319
- .top-nav-inner {
320
- max-width: 1100px;
321
- margin: 0 auto;
322
- height: 56px;
323
- display: flex;
324
- align-items: center;
325
- justify-content: space-between;
326
- padding: 0 16px;
327
- }
328
- .brand {
329
- display: flex;
330
- align-items: center;
331
- gap: 10px;
332
- font-weight: 600;
333
- letter-spacing: 0.2px;
334
- }
335
- .brand .dot {
336
- width: 10px;
337
- height: 10px;
338
- border-radius: 50%;
339
- background: var(--apple-blue);
340
- box-shadow: 0 0 0 4px rgba(0,122,255,0.15);
341
- }
342
- .nav-actions .burger {
343
- width: 36px; height: 36px;
344
- border-radius: 9px;
345
- border: 1px solid rgba(0,0,0,0.08);
346
- display: grid; place-items: center;
347
- background: var(--apple-white);
348
- box-shadow: var(--shadow-soft);
349
- cursor: pointer;
350
- transition: var(--transition);
351
- }
352
- .nav-actions .burger:hover { transform: translateY(-1px); }
353
-
354
- /* Inline burger menu panel (local help/actions) */
355
- .inline-menu {
356
- position: fixed;
357
- top: 64px;
358
- right: 16px;
359
- width: 260px;
360
- background: var(--apple-white);
361
- border: 1px solid rgba(0,0,0,0.06);
362
- border-radius: var(--radius-lg);
363
- box-shadow: var(--shadow-soft);
364
- padding: 12px;
365
- opacity: 0;
366
- pointer-events: none;
367
- transform: translateY(-8px);
368
- transition: var(--transition);
369
- }
370
- .inline-menu.open {
371
- opacity: 1;
372
- pointer-events: auto;
373
- transform: translateY(0);
374
- }
375
- .inline-menu h4 {
376
- margin: 6px 0 10px 0;
377
- font-size: 14px;
378
- font-weight: 700;
379
- }
380
- .inline-menu a {
381
- display: block;
382
- padding: 8px 10px;
383
- border-radius: 10px;
384
- text-decoration: underline;
385
- text-underline-offset: var(--link-underline-offset);
386
- color: var(--text-color);
387
- }
388
- .inline-menu a:hover { background: var(--apple-grey-100); }
389
-
390
- /* ==== Header (full-width black) ==== */
391
- .header {
392
- margin: 18px 0 28px 0;
393
- border-radius: var(--radius-lg);
394
- overflow: hidden;
395
- background: var(--apple-black);
396
- color: #ffff !important; /* Force white text */
397
- box-shadow: var(--shadow-soft);
398
- }
399
- .header, .header * {
400
- color: #ffff !important; /* All content in white */
401
- }
402
- .header a, .header a:visited, .header a:active {
403
- color: #ffff !important; /* White links */
404
- text-decoration: underline;
405
- text-underline-offset: var(--link-underline-offset);
406
- }
407
- .header-inner {
408
- padding: 48px 32px;
409
- text-align: center;
410
- }
411
- .header h1 {
412
- margin: 0;
413
- font-weight: 700;
414
- letter-spacing: -0.02em;
415
- font-size: clamp(28px, 3.5vw, 40px);
416
- }
417
- .header p {
418
- opacity: 0.92;
419
- font-size: 17px;
420
- line-height: 1.5;
421
- margin: 12px auto 0;
422
- max-width: 760px;
423
- }
424
-
425
- /* ==== Section Cards (alternating backgrounds) ==== */
426
- .section {
427
- background: var(--apple-white);
428
- border: 1px solid rgba(0,0,0,0.06);
429
- border-radius: var(--radius-lg);
430
- padding: 20px;
431
- box-shadow: var(--shadow-soft);
432
- }
433
- .section + .section { margin-top: 16px; }
434
-
435
- /* Alternate section – subtle grey Apple background */
436
- .section.alt {
437
- background: var(--apple-grey-100);
438
- }
439
-
440
- /* Labels/titles inside sections */
441
- .section h3, .section h2, .section h4 {
442
- margin-top: 0;
443
- letter-spacing: -0.01em;
444
- }
445
- .section h3 {
446
- font-size: 18px;
447
- font-weight: 700;
448
- margin-bottom: 12px;
449
- }
450
-
451
- /* ==== Inputs & Controls ==== */
452
- input[type="text"], input[type="password"], textarea {
453
- border-radius: var(--radius-md) !important;
454
- border: 1px solid rgba(0,0,0,0.08) !important;
455
- background: var(--apple-white) !important;
456
- transition: var(--transition) !important;
457
- box-shadow: 0 1px 0 rgba(0,0,0,0.02) inset;
458
- }
459
- input:focus, textarea:focus {
460
- outline: none !important;
461
- border-color: var(--apple-blue) !important;
462
- box-shadow: 0 0 0 3px rgba(0,122,255,0.15) !important;
463
- }
464
-
465
- /* Buttons */
466
- .apple-button, .reset-button, .ghost-button {
467
- display: inline-flex;
468
- align-items: center;
469
- gap: 8px;
470
- height: 44px;
471
- padding: 0 18px;
472
- border-radius: 12px;
473
- border: 1px solid transparent;
474
- cursor: pointer;
475
- font-weight: 600;
476
- letter-spacing: 0.2px;
477
- transition: var(--transition);
478
- user-select: none;
479
- }
480
- .apple-button {
481
- background: var(--apple-blue);
482
- color: #fff;
483
- box-shadow: 0 6px 18px rgba(0,122,255,0.25);
484
- }
485
- .apple-button:hover { background: var(--apple-blue-hover); transform: translateY(-1px); }
486
- .apple-button:active { transform: translateY(0); }
487
-
488
- .reset-button {
489
- background: var(--apple-red);
490
- color: #fff;
491
- box-shadow: 0 6px 18px rgba(255,59,48,0.22);
492
- }
493
- .reset-button:hover { filter: brightness(0.96); transform: translateY(-1px); }
494
- .reset-button:active { transform: translateY(0); }
495
-
496
- /* Secondary ghost button style if needed */
497
- .ghost-button {
498
- background: var(--apple-white);
499
- color: var(--text-color);
500
- border: 1px solid rgba(0,0,0,0.08);
501
- }
502
- .ghost-button:hover { background: #fafafa; }
503
-
504
- /* Status messages */
505
- .status-success { color: var(--apple-green); font-weight: 600; }
506
- .status-error { color: var(--apple-red); font-weight: 600; }
507
-
508
- /* ==== Tabs Styling (Apple-like) ==== */
509
- .tab-nav {
510
- background: var(--apple-grey-100);
511
- border-radius: var(--radius-md);
512
- padding: 4px;
513
- display: flex;
514
- gap: 2px;
515
- margin-bottom: 16px;
516
- }
517
-
518
- .tab-nav button {
519
- flex: 1;
520
- padding: 8px 16px;
521
- border: none;
522
- border-radius: var(--radius-sm);
523
- background: transparent;
524
- color: var(--apple-grey-600);
525
- font-weight: 500;
526
- font-size: 14px;
527
- cursor: pointer;
528
- transition: var(--transition);
529
- display: flex;
530
- align-items: center;
531
- justify-content: center;
532
- gap: 6px;
533
- }
534
-
535
- .tab-nav button.selected {
536
- background: var(--apple-white);
537
- color: var(--text-color);
538
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
539
- font-weight: 600;
540
- }
541
-
542
- .tab-nav button:hover:not(.selected) {
543
- color: var(--text-color);
544
- background: rgba(255,255,255,0.5);
545
- }
546
-
547
- /* Tab content */
548
- .tab-content {
549
- min-height: 120px;
550
- }
551
-
552
- /* ==== Download & Preview ==== */
553
- .preview-card {
554
- background: var(--apple-white);
555
- border: 1px solid rgba(0,0,0,0.06);
556
- border-radius: var(--radius-lg);
557
- box-shadow: var(--shadow-soft);
558
- overflow: hidden;
559
- }
560
- .preview-header {
561
- background: linear-gradient(180deg, #fafafa, #f2f2f7);
562
- border-bottom: 1px solid rgba(0,0,0,0.06);
563
- padding: 12px 16px;
564
- display: flex; align-items: center; gap: 8px;
565
- }
566
- .preview-dot {
567
- width: 10px; height: 10px; border-radius: 50%;
568
- background: #ff5f57; box-shadow: 16px 0 0 #ffbd2e, 32px 0 0 #28c840;
569
- }
570
- .preview-body {
571
- padding: 16px;
572
- max-height: 520px;
573
- overflow: auto;
574
- background: var(--apple-grey-50);
575
- }
576
- .preview-body pre, .preview-body code {
577
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
578
- font-size: 12px;
579
- }
580
-
581
- /* ==== Footer (full-width black) ==== */
582
- .footer {
583
- margin-top: 22px;
584
- border-radius: var(--radius-lg);
585
- overflow: hidden;
586
- background: var(--apple-black);
587
- color: #ffff !important; /* Force white text */
588
- box-shadow: var(--shadow-soft);
589
- }
590
- .footer, .footer * {
591
- color: #ffff !important; /* All content in white */
592
- }
593
- .footer a, .footer a:visited, .footer a:active {
594
- color: #ffff !important; /* White links */
595
- text-decoration: underline;
596
- text-underline-offset: var(--link-underline-offset);
597
- }
598
- .footer-inner {
599
- padding: 18px 20px;
600
- font-size: 14px;
601
- line-height: 1.5;
602
- }
603
-
604
- /* Links globally */
605
- a { text-decoration: underline; text-underline-offset: var(--link-underline-offset); }
606
-
607
- /* Hover animations */
608
- .section, .preview-card, .header, .footer {
609
- transition: var(--transition);
610
- }
611
- .section:hover, .preview-card:hover {
612
- transform: translateY(-2px);
613
- }
614
-
615
- /* Responsive */
616
- @media (max-width: 768px) {
617
- .top-nav-inner { padding: 0 12px; }
618
- .header-inner { padding: 36px 20px; }
619
- .preview-body { max-height: 420px; }
620
- }
621
- """
622
  ) as app:
623
 
624
  # Header hero (black, full-width look within container)
@@ -700,57 +351,6 @@ a { text-decoration: underline; text-underline-offset: var(--link-underline-offs
700
  </div>
701
  """)
702
 
703
- # Light JS: smooth scroll to top, inline burger, focus handling
704
- gr.HTML("""
705
- <script>
706
- (function() {
707
- const menuBtn = document.getElementById('inlineMenuBtn');
708
- const menu = document.getElementById('inlineMenu');
709
- const topLink = document.getElementById('scrollTopLink');
710
-
711
- function closeMenu() {
712
- if (!menu) return;
713
- menu.classList.remove('open');
714
- menu.setAttribute('aria-hidden', 'true');
715
- }
716
-
717
- if (menuBtn && menu) {
718
- menuBtn.addEventListener('click', function(e) {
719
- e.preventDefault();
720
- const isOpen = menu.classList.contains('open');
721
- if (isOpen) {
722
- closeMenu();
723
- } else {
724
- menu.classList.add('open');
725
- menu.setAttribute('aria-hidden', 'false');
726
- }
727
- });
728
- }
729
-
730
- if (topLink) {
731
- topLink.addEventListener('click', function(e) {
732
- e.preventDefault();
733
- window.scrollTo({ top: 0, behavior: 'smooth' });
734
- closeMenu();
735
- });
736
- }
737
-
738
- // Close when clicking outside
739
- document.addEventListener('click', function(e) {
740
- if (!menu || !menuBtn) return;
741
- if (!menu.contains(e.target) && !menuBtn.contains(e.target)) {
742
- closeMenu();
743
- }
744
- });
745
-
746
- // Accessibility: close on Escape
747
- document.addEventListener('keydown', function(e) {
748
- if (e.key === 'Escape') closeMenu();
749
- });
750
- })();
751
- </script>
752
- """)
753
-
754
  # Events
755
  model_dropdown.change(
756
  fn=update_api_info,
 
268
  with gr.Blocks(
269
  title="EduHTML Creator - Educational HTML Content Generator",
270
  theme=gr.themes.Soft(),
271
+ css="style.css",
272
+ js="script.js"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  ) as app:
274
 
275
  # Header hero (black, full-width look within container)
 
351
  </div>
352
  """)
353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  # Events
355
  model_dropdown.change(
356
  fn=update_api_info,