Upload app.py with huggingface_hub
Browse files
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 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 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 |
-
|
| 904 |
-
|
| 905 |
-
<div class="chat-container"
|
| 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 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 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("""
|