OpceanAI commited on
Commit
709e3ad
·
verified ·
1 Parent(s): 921cddf

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +244 -32
app.py CHANGED
@@ -706,21 +706,17 @@ label span, .label-wrap span {
706
  /* ─── Hide Gradio Footer ───────────────────────────────────────────────────── */
707
  footer, .footer, .built-with { display: none !important; }
708
 
709
- /* ─── Animations ───────────────────────────────────────────────────────────── */
710
- @keyframes fadeInUp {
711
- from {
712
- opacity: 0;
713
- transform: translateY(20px);
714
- }
715
- to {
716
- opacity: 1;
717
- transform: translateY(0);
718
- }
719
- }
720
-
721
- .hero { animation: fadeInUp 0.6s ease-out; }
722
- .features-grid { animation: fadeInUp 0.6s ease-out 0.1s both; }
723
- .chat-section { animation: fadeInUp 0.6s ease-out 0.2s both; }
724
 
725
  /* ─── Responsive ───────────────────────────────────────────────────────────── */
726
  @media (max-width: 768px) {
@@ -764,6 +760,15 @@ footer, .footer, .built-with { display: none !important; }
764
 
765
  # ─── Custom JS ────────────────────────────────────────────────────────────────
766
  custom_js = """
 
 
 
 
 
 
 
 
 
767
  function initTheme() {
768
  const stored = localStorage.getItem('theme');
769
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
@@ -778,6 +783,12 @@ function toggleTheme() {
778
  document.documentElement.setAttribute('data-theme', next);
779
  localStorage.setItem('theme', next);
780
  updateThemeIcon(next);
 
 
 
 
 
 
781
  }
782
 
783
  function updateThemeIcon(theme) {
@@ -804,6 +815,206 @@ function setupNavbar() {
804
  document.body.insertBefore(navbar, document.body.firstChild);
805
  }
806
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
807
  document.addEventListener('DOMContentLoaded', () => {
808
  initTheme();
809
  setupNavbar();
@@ -900,30 +1111,31 @@ with gr.Blocks(
900
  """)
901
 
902
  # Chat Section
903
- with gr.Group(elem_classes="chat-section"):
904
- gr.HTML("""
905
- <div class="chat-container" id="chat">
906
  <div class="chat-header">
907
  <span class="chat-header-dot"></span>
908
  <h3>Chat con Yuuki-RxG</h3>
909
  <span>Featherless AI</span>
910
  </div>
911
  </div>
912
- """)
913
-
914
- with gr.Sidebar():
915
- gr.Markdown("# Yuuki-RxG")
916
- gr.Markdown(
917
- "Modelo servido via featherless-ai. "
918
- "Inicia sesión con tu cuenta de Hugging Face para acceder a la inferencia."
919
- )
920
- button = gr.LoginButton("Iniciar sesión")
921
-
922
- gr.load(
923
- "models/OpceanAI/Yuuki-RxG",
924
- accept_token=button,
925
- provider="featherless-ai",
926
  )
 
 
 
 
 
 
 
927
 
928
  # Footer
929
  gr.HTML("""
 
706
  /* ─── Hide Gradio Footer ───────────────────────────────────────────────────── */
707
  footer, .footer, .built-with { display: none !important; }
708
 
709
+ /* ─── Animations (anime.js handles all) ────────────────────────────────────── */
710
+ .hero { opacity: 0; }
711
+ .hero-badge { opacity: 0; }
712
+ .hero h1 { opacity: 0; }
713
+ .hero p { opacity: 0; }
714
+ .hero-cta { opacity: 0; }
715
+ .features-grid { opacity: 1; }
716
+ .feature-card { opacity: 0; }
717
+ .chat-section { opacity: 1; }
718
+ .chat-container { opacity: 0; }
719
+ .footer { opacity: 0; }
 
 
 
 
720
 
721
  /* ─── Responsive ───────────────────────────────────────────────────────────── */
722
  @media (max-width: 768px) {
 
760
 
761
  # ─── Custom JS ────────────────────────────────────────────────────────────────
762
  custom_js = """
763
+ (function() {
764
+ const script = document.createElement('script');
765
+ script.src = 'https://cdn.jsdelivr.net/npm/animejs@4.0.0/lib/anime.min.js';
766
+ script.onload = function() {
767
+ initAnimations();
768
+ };
769
+ document.head.appendChild(script);
770
+ })();
771
+
772
  function initTheme() {
773
  const stored = localStorage.getItem('theme');
774
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
 
783
  document.documentElement.setAttribute('data-theme', next);
784
  localStorage.setItem('theme', next);
785
  updateThemeIcon(next);
786
+ anime({
787
+ targets: '.theme-toggle',
788
+ rotate: [0, 360],
789
+ duration: 400,
790
+ easing: 'easeInOutQuad'
791
+ });
792
  }
793
 
794
  function updateThemeIcon(theme) {
 
815
  document.body.insertBefore(navbar, document.body.firstChild);
816
  }
817
 
818
+ function initAnimations() {
819
+ const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
820
+ if (prefersReduced) {
821
+ document.querySelectorAll('.hero, .hero-badge, .hero h1, .hero p, .hero-cta, .features-grid, .feature-card, .chat-section, .footer').forEach(el => {
822
+ el.style.opacity = '1';
823
+ });
824
+ return;
825
+ }
826
+
827
+ // Navbar slide down
828
+ anime({
829
+ targets: '.navbar',
830
+ translateY: [-60, 0],
831
+ opacity: [0, 1],
832
+ duration: 600,
833
+ easing: 'easeOutExpo'
834
+ });
835
+
836
+ // Hero entrance timeline
837
+ const heroTL = anime.timeline({ easing: 'easeOutExpo' });
838
+ heroTL
839
+ .add({
840
+ targets: '.hero-badge',
841
+ opacity: [0, 1],
842
+ translateY: [15, 0],
843
+ scale: [0.95, 1],
844
+ duration: 500
845
+ })
846
+ .add({
847
+ targets: '.hero h1',
848
+ opacity: [0, 1],
849
+ translateY: [25, 0],
850
+ duration: 700
851
+ }, '-=300')
852
+ .add({
853
+ targets: '.hero p',
854
+ opacity: [0, 1],
855
+ translateY: [20, 0],
856
+ duration: 600
857
+ }, '-=400')
858
+ .add({
859
+ targets: '.hero-cta',
860
+ opacity: [0, 1],
861
+ translateY: [20, 0],
862
+ duration: 600
863
+ }, '-=350');
864
+
865
+ // Floating orbs animation
866
+ anime({
867
+ targets: 'body::after',
868
+ translateX: ['-52%', '-48%'],
869
+ translateY: ['-2%', '2%'],
870
+ duration: 8000,
871
+ loop: true,
872
+ direction: 'alternate',
873
+ easing: 'easeInOutSine'
874
+ });
875
+
876
+ // Feature cards stagger on scroll
877
+ const scrollObserver = anime.scroll('.features', {
878
+ repeat: false,
879
+ threshold: 0.2,
880
+ onEnter: () => {
881
+ anime({
882
+ targets: '.feature-card',
883
+ opacity: [0, 1],
884
+ translateY: [30, 0],
885
+ delay: anime.stagger(120, { start: 100 }),
886
+ duration: 700,
887
+ easing: 'easeOutExpo'
888
+ });
889
+ }
890
+ });
891
+
892
+ // Chat section on scroll
893
+ anime.scroll('.chat-section', {
894
+ repeat: false,
895
+ threshold: 0.15,
896
+ onEnter: () => {
897
+ anime({
898
+ targets: '.chat-container',
899
+ opacity: [0, 1],
900
+ translateY: [25, 0],
901
+ scale: [0.98, 1],
902
+ duration: 600,
903
+ easing: 'easeOutExpo'
904
+ });
905
+ }
906
+ });
907
+
908
+ // Footer on scroll
909
+ anime.scroll('.footer', {
910
+ repeat: false,
911
+ threshold: 0.5,
912
+ onEnter: () => {
913
+ anime({
914
+ targets: '.footer',
915
+ opacity: [0, 1],
916
+ translateY: [15, 0],
917
+ duration: 500,
918
+ easing: 'easeOutExpo'
919
+ });
920
+ }
921
+ });
922
+
923
+ // Button hover micro-interactions
924
+ document.querySelectorAll('.btn-primary').forEach(btn => {
925
+ btn.addEventListener('mouseenter', () => {
926
+ anime({
927
+ targets: btn,
928
+ scale: 1.03,
929
+ duration: 200,
930
+ easing: 'easeOutQuad'
931
+ });
932
+ });
933
+ btn.addEventListener('mouseleave', () => {
934
+ anime({
935
+ targets: btn,
936
+ scale: 1,
937
+ duration: 200,
938
+ easing: 'easeOutQuad'
939
+ });
940
+ });
941
+ });
942
+
943
+ document.querySelectorAll('.btn-secondary').forEach(btn => {
944
+ btn.addEventListener('mouseenter', () => {
945
+ anime({
946
+ targets: btn,
947
+ scale: 1.02,
948
+ duration: 200,
949
+ easing: 'easeOutQuad'
950
+ });
951
+ });
952
+ btn.addEventListener('mouseleave', () => {
953
+ anime({
954
+ targets: btn,
955
+ scale: 1,
956
+ duration: 200,
957
+ easing: 'easeOutQuad'
958
+ });
959
+ });
960
+ });
961
+
962
+ // Feature card hover
963
+ document.querySelectorAll('.feature-card').forEach(card => {
964
+ card.addEventListener('mouseenter', () => {
965
+ anime({
966
+ targets: card.querySelector('.feature-icon'),
967
+ scale: 1.1,
968
+ rotate: '5deg',
969
+ duration: 300,
970
+ easing: 'easeOutQuad'
971
+ });
972
+ });
973
+ card.addEventListener('mouseleave', () => {
974
+ anime({
975
+ targets: card.querySelector('.feature-icon'),
976
+ scale: 1,
977
+ rotate: '0deg',
978
+ duration: 300,
979
+ easing: 'easeOutQuad'
980
+ });
981
+ });
982
+ });
983
+
984
+ // Logo pulse
985
+ anime({
986
+ targets: '.navbar-logo',
987
+ boxShadow: [
988
+ '0 0 20px rgba(34, 197, 94, 0.15)',
989
+ '0 0 35px rgba(34, 197, 94, 0.3)',
990
+ '0 0 20px rgba(34, 197, 94, 0.15)'
991
+ ],
992
+ duration: 3000,
993
+ loop: true,
994
+ easing: 'easeInOutSine'
995
+ });
996
+
997
+ // Badge dot pulse
998
+ anime({
999
+ targets: '.hero-badge-dot',
1000
+ scale: [1, 1.3, 1],
1001
+ opacity: [1, 0.6, 1],
1002
+ duration: 2000,
1003
+ loop: true,
1004
+ easing: 'easeInOutSine'
1005
+ });
1006
+
1007
+ // Chat header dot pulse
1008
+ anime({
1009
+ targets: '.chat-header-dot',
1010
+ scale: [1, 1.4, 1],
1011
+ opacity: [1, 0.5, 1],
1012
+ duration: 2500,
1013
+ loop: true,
1014
+ easing: 'easeInOutSine'
1015
+ });
1016
+ }
1017
+
1018
  document.addEventListener('DOMContentLoaded', () => {
1019
  initTheme();
1020
  setupNavbar();
 
1111
  """)
1112
 
1113
  # Chat Section
1114
+ gr.HTML("""
1115
+ <section class="chat-section" id="chat">
1116
+ <div class="chat-container">
1117
  <div class="chat-header">
1118
  <span class="chat-header-dot"></span>
1119
  <h3>Chat con Yuuki-RxG</h3>
1120
  <span>Featherless AI</span>
1121
  </div>
1122
  </div>
1123
+ </section>
1124
+ """)
1125
+
1126
+ with gr.Sidebar():
1127
+ gr.Markdown("# Yuuki-RxG")
1128
+ gr.Markdown(
1129
+ "Modelo servido via featherless-ai. "
1130
+ "Inicia sesión con tu cuenta de Hugging Face para acceder a la inferencia."
 
 
 
 
 
 
1131
  )
1132
+ button = gr.LoginButton("Iniciar sesión")
1133
+
1134
+ gr.load(
1135
+ "models/OpceanAI/Yuuki-RxG",
1136
+ accept_token=button,
1137
+ provider="featherless-ai",
1138
+ )
1139
 
1140
  # Footer
1141
  gr.HTML("""