From 0777577aa699462172a3d5c043de2f33961eccbc Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 21 Jan 2026 19:28:45 +0000 Subject: [PATCH] version:1.0 --- ai/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 404 bytes ai/__pycache__/local_ai_api.cpython-311.pyc | Bin 0 -> 19874 bytes core/__pycache__/admin.cpython-311.pyc | Bin 212 -> 1492 bytes core/__pycache__/models.cpython-311.pyc | Bin 209 -> 3509 bytes core/__pycache__/urls.cpython-311.pyc | Bin 347 -> 436 bytes core/__pycache__/views.cpython-311.pyc | Bin 1364 -> 3171 bytes core/admin.py | 16 +- core/migrations/0001_initial.py | 46 +++ .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 2844 bytes core/models.py | 43 ++- core/templates/base.html | 80 ++++-- core/templates/core/index.html | 265 ++++++++---------- core/urls.py | 6 +- core/views.py | 54 +++- static/css/custom.css | 106 ++++++- staticfiles/css/custom.css | 117 ++++++-- 16 files changed, 538 insertions(+), 195 deletions(-) create mode 100644 ai/__pycache__/__init__.cpython-311.pyc create mode 100644 ai/__pycache__/local_ai_api.cpython-311.pyc create mode 100644 core/migrations/0001_initial.py create mode 100644 core/migrations/__pycache__/0001_initial.cpython-311.pyc diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9beeae7341d797e2eac5af07416a24e9ee781f92 GIT binary patch literal 404 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 Yvh>4l)Eu8fmRV$(MHaYwzkM8&e;|EGWdHyG delta 148 zcmcb@eT6Y)IWI340}xFAk)LS~q#uJgFu(+5d=>&SrZc24q%h_%s&fIEmn79NU}NQtr(N8U89T}SS^NdzY{+NMFU$ZlZR&d;u68a3LnycTXP*E5)Xyqv?S z)-<=qG;OtK|GJBNttyP^VgxtHb~g9ufu|hb#WhS7)IiZRoL|#|l%~OebqnRRrroLQ zR;XdPfgm}yq_fKvYMBi85+qAjeUaB;>Oc{(qgQ@8?)&m`05cUW7 zV>x7a5S-zex%0pp(QjMrTR-oseH*T)4mZ_dUmb3YM~&w^^>kA`?W?DuvHO$9$NcV3 zUY_&1FEqO^_}v#8f8CLUc<&B5%);q$=8l+?p#f=k16VueOrb17%t*_v{3bL3wU#x3 z80^Tgvcj#CI2001fi*gwlPSVaf|!HRHlq>CkXc~W6nS#hv z19^ry3l)nN#6m1kOE+dFX0_4r>({1M)lz+hvizu7t=OPTPS0N1(;VF&6_J5-qckzg zFs~pAla8%H!csWGK(5m2JY{Y{Vnd*X2(4RI5TCbn`*x6K)Z*ug!SNbTmi-Zj5E({T zAR9|g#h`8=n{+|1TeXgKz(~Sxw+O5=9hRfC`4S)$5+#DKFUi*;Y&|x$D(27T3t}ME z0Z{@4IW8iQm}61a4MT?M6UG=WZ8f{+tyU@=N28B`K`INV!nEj`w&|P$EKCjbW+0D^mc~ZMC)io6 zr7lCRRu=8Q(FZ)_1En-Er%m0MoD9;=K9pg-IL`<&?$rU5+9{LADzXfGZUb05Wp-jx zPogoolOpLn=FW)?>1E=(jHg~|s+WBA5~NCQ=<#_!H?;AOf8G4I=9T{LX@E+g% zxivqx)|iYkjJ>@0>X@g_G}RejooS3?LVbY=b&!RN%fm__eiAOVO@MPe-4>yYDX=>Q z3{E@7KCZQN@ZUc1jp(fRsmYqKC3J!`UY#ZWK{ONu?q3MJJoE}=XMUL)H8)6vzyra1 z9@~|Q?bdYLpb(lNA_a-t_jI=Cx_DT5ARaG4E>vq6R@zFKWbDsi(g&aWIj{!#Siu5o zZAyK<)aSKIxDhaosCC`${s2vF;N%xAdX^JDN0wWbkk|b32JL2KQ4X)>s7{st+XJ3M zV1sbOsnbFHY4d(9Law+Ea)m9iGsempQ{r$N2h2$XDqMTD>(q7iMLGu#9)c;^No1#x zrGa%I93C%6ID`&(4kD6)6cQj=EJQK|hs{HQC`RAE8@+P-CT}6wFj%`sf#GF7{A}o} z5idK8MH%L2bQrccP%#W(4)*Lbln|Q2YxoP0g5(^%Ukfj8K!3hle51K5jt%M1kH&nN z??R?A)FMOQxKDsJqTjaKkAT$wZ0_5eTeto*^vd+qQd2GYYUuzd-STE{dbj4ioYBk~ ze$D_y$_%V8_?dxbChuqRjVs&P6YF>V?1^S}(9aGwuD1jBR*#5SyJfaE!`iI&2!XxVqw!dvFKP0hK&SrZc24q%h_%HmHb8ZyIjMF< a96&KfATE|=m|V*v$$f!A28fE-fIap9s3XH$bdiyeoQKL zsLaUJtx~s6*rg00p3nB3-#fp1sn@HZ@v(p7Kk56^6hCm*$->pi190FdfDpL|0k=2~ ztPs06BrZWrkG9AmcdF2e6)tQktks=Apx-(=7OOb9I z3RPnMh1X@70%@;B5evor21|U({6oW0X(l~wI;zI6Sk#GIxeQWiMo{*xFM8>!ccoG_ z&1suV$S8eSi--%JnhF2%#zL6u)B%d&Pe-cfhU;PKH~<^N~}K#+WoFq%kFB{kA*We(V>dJtpl5 QY0quEX$@*-$+|ZB0y1cDRsaA1 delta 253 zcmdnOe4D9$IWI340}xbw%g@XL(vLwL7+{4mKHC5p(-~42QW$d>av7r-85vTTQkZj? za+#x;85x)uQW;ZNQkhd&*RU;PW?)zi#1N3q7{!vp9?YQ0@e(AU$#{#UAh9IlB_ouR zA)23?dW)e5WD!U*FEKaOPm^`xIk|}+ePj55q9B#UUO?glGb1D84F;JDsOSNM_ytt- nfsKKcv%#f9s3T+s+XWW+i!Ab2SmZx2Gx0MuaD!kG570OO_q8{@ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2a36fd69370b38a98d8b01bf8eb9817c42f16ed6..d2627c45505f40029dc9166ce81c1359f60d0c62 100644 GIT binary patch literal 3171 zcmZ`*O>7&-6`tMYpF~om#5iO`yWB{s6#9pX;=on|Lk=Yw4g*`ZCAY45A=ccHxXS)8 zvqMQFs6YoF+#+a=qJV`$Ky`AJIz@BzwM`B^E(;!r1qcK!a`26TV<5<>Z6V{?M))BJhA!+X?#Hk2Q7c&|FF1@l3N_o*Q*oDVy^UmejR`3UdFGHIxoLVIwPP&JJ#1TG+zGR16)uK7w@_6W~H0 zn})uM&9b4J82SOKXt-wRj1Lw~vR=SDSSwTL4qq{flA6tB%gPfD^rm?`xKxtpRcxBl z2DU@j$cCgVHHpF|MJCZNaBoO}|I_~fd4T8(bDIO+ZNV-lbJW{cfL^kX`k&8idiuOu zL!G0+{tQB!zCJJWvhWaI?ot2s&}-y8vezvq`wo1&JdN}#Gs{HT0zHfGEsATBv^H2F!ZJ}a;9YeQ>lBkR zQA})R?9sla+|}&mONC#qUa?WyXNStf*u+Iz&?ODqBl4!CZy0?iu}8{PS~B!OKUAy` z@ETfR4r0gpYh?^(DP{KL_Go`l(ZC-H6{6N6MT6j31)OasQ=*!h4iNSbwxAo^WR!7% za?fBg#=5*=+CFertZxzauxY{e6Z~lfo0PoC1pGwyW;GBi9}xl_?; zWfr`(SfK`)-8RT4W?3rYS?35_3f?v|<*Myr(&Pjz4#D44f$X90hQ~fX{hQ3^nZ2cs z551LckH6CxKiM2V*&d&0j?Xp5&o;-;wi3y9>g|K7m0qwutTa+v&D2)=MC#zSHS@va z#m0$?%@Y?pVSmKeK|uB{KZ~N!*!>wRdHQIh5j@unp0hmXp2B{}6&%c!o#0pohkO7o zwaG-BB6FWOPI{js{1Bo87Xx=5I4{T##vej3JsJemE?4Ic2f@+T$y%9zNs_PgX6(f< zkOkSJaI*JHpF0HBz~LDT9q{sSooDR^zbnx2bM2dh(3FF90d$1qusm|WyY=jP>Ymq} zE#f{KnQ>_k^mnRz+;U}3j_!J0HjLK23g?zua|OFBy!I4=Jmx+zSQ7jH+n7X@xoxjZ zA#!rp=Q@KxkM(B(E`09Oyh>-0zYR%Z*Y}wZ?%HX$xoxx~+(z3jK!X>0f_C4vE} z7%UBd>a-{UyzG=Qp`xOTcPgf$!!9C=w{_LnHcvaK#KdF3XrNQu!&KT{MK4$A z6BZm#E&u_!aM@7Rg2M1{OHu*!SeId#QK7cqtQ3o&w{|i&qluOQ%VUBG_AVt7-h5lxC2#}6QfYA){?4e6LMcl<&0q`*G zC*y3DN0z8$hu94i`Y#^nF{T|DC<{mmXoj=f95z{)0(`PUjx#NOm@Pt1A`8%Cdd(`> zvxmO*kKFxi|IL5P-)O{dG~+j{=#5SQjZbtCn!PFj9bM_s)?2Bg zD^~OuP&-~BF>>#tXTvBl(TvZvMicw*SkcMW#N=12R&*Zf_e|mkqGT^fa#n%ymeHvrp`Cw^UXNZ_8mLw zQR(mMU)9Iwt>s@eGPjzUTh`RCElIZGxDm(AIJTnr$95zE#tmJ3PTH~5Vf=5CN75J5 zUrt-%+~Y|rw$O+zG-C@^=;it&l#T%Fp?&5T)`oY4;TMk-WM&2Gj%-W%#BQW-;5l_1ZW8TOG# zm^axGNy(_}8?gYcB$bt}Py5&>320%T(S&`GImy@YvM&(%85>~!_fy~k2v$_QKrTa< zWihi21g?tXT4-p``L$4F&-t}baL@U*(7Tqqw$P;It}QfWxoZo(ZMka;y>Gc|3r$<@ p+CpcnSJjRu#GUV;0XdHNaEBMUMXrMw{a%29yU7=ax)YB1{{vcUN1Olv literal 1364 zcmZ`(&1)M+6ra_{dS%J>I&SM!uH%hUh$T{~CE!96oTjQ1oHkCdQ$lozPf-Q6#oM~=1-7}AYwoe=&3h>36z}rW~~)fO5P4{-h1=r&HMPV zzfVm~BA|nRhVUX&zZ=1NEJDd#(kRMro?7~GlVKiARAFbK7y={g8`rq_)Wa;XDEltUWCmB zkq~sth&3ZeP{;A878u54V{Oaty2i>_vx<&kIwj51DaMXgGg(=)ND+pj!HI^Q9g`Br z#tzdA%!;PvWg3a1>()Z2BR!#4DWHiJ1dw>FOuS)~xge&2p-9tZ06jh%7)=`o)~k%rY>m)oo?Fy$ z*3WOp#5FJD)_FvD(?z&0py>SutcBjF^RHFyMAbU#a#vk`t*)G?D;+i6Rnx7Fo|by~ z_(Z$b)~@ZR_tUQyT0itB&pp5LYvy^Tl^e+D)6aYJ%l+g^CzEdC%omzVp>MZ5DOS%5y(&3}_|W(xv}LYKpGcC8^yMqANi+|+@eAog4UgB$`t94 zl>genLx+yp;<4!9wupxe9Xxc%n4tp&a4>EP&?%dOc*@egqeNM$)8?lq@#)=r@7{gy z=Z^Zht1HC7u+H6;zYH+UpLF65UyFG@2h4p2F^E-|5(~ea!c{#b4@+ep#as22d{w^0 zvkb>fG06KpgM8Rm@w<+8JPh*yp5`d|5nEu={8KueNwXwiVAGUU$w+e~RFx%NG-XXS z2w&9@R*Z6Mo%0iIO`d-T{_Zo_!BgT8Tk>!W_EucX4CXubXJLPMnnPks0mnAzN)U(W z>QE)zmavFLUgX>5cf7C`p5|EOkl(S4xDpiD4eq?;A8bO7O;_87-3=eHi8wah9X4J6 zw2{2K-8&rY4^MNz8gJzg_p!IY9d-6Q=6c!z=7Bq50CVg$`ZvIfdK@2aji6r;i({1@ zcbkgSYjjq5uPuwaTxZ30-#e1``2X>Zjvw_X@vq5l?^|Ry;h<}Gg~Xr}Kd~r@`gTvg z-2IU0cZuY1Rg4bT8y--05l%K)LKC?u$<0$f4Z z#Dp_7645$>+>Dhq9glR1h<{Gk7G(vz>6(Jm9=OoLh55P3+d_6?`o_#=xKLZc`l&3c z$|~rBv$v;Onx4-5wGF)Ug~{8*I}gzGvk=WwdRWpP;x8|0av2-MkMN>cQ%pTZV}-D) z3s^VOKK&%j^?phQs3xLgg%-fcuRaJO$Pd*x{7m`;2?&l(5J*T6;Nq<*82E@F+^vZU ztq08fvMQTUF`eFrByOyUD=Xpx7$UraRfN^@hEA_}ax6Pvye?4i!u0IKWS&IY7BZj? zk2~!!O|N&Ib}@-ulcg*)N{$wb1ff=Xi!DIKn{3wvL{OBgxTPuLb+gHaa!?6bQg1<1 z@u(uIl14bRKmtzf;9WxeSVi{*>17r?gSeen$(GP`Ijz(5Cbov5x2)tPt z<2Sg)x7wd4-91}V4W0>}{~=@t&ixXw&tI(vvUVWb@NjW{E8hq)!4%aE?#EJ3V#lq- z(7jbVF|_A>eAX%nma1C`qnzL=QkS+@?bM}5aVwRpr*d{GXGNzPL0`PP;R^&q&ln&Flr(w{!3@3u zm_Doj!gkK?zfkWVvHM4?Xl6fl(i#}v{=yy@t`B7Ffs7R${Z|MM=ph=-(8KuN#N*r_ zH|+e^b{^aLs-!7A9~I0tW$ljw>wOHLq5P9RH;4;g#_jA5F?;XVHM zpnc`KedTle%2(E%Mf=XGm0YVQ*X-n)6m>h3x3rXH;?U3ax|cZ~LLt7ytkO literal 0 HcmV?d00001 diff --git a/core/models.py b/core/models.py index 71a8362..8cbec7a 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,44 @@ from django.db import models +from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver -# Create your models here. +class Organization(models.Model): + name = models.CharField(max_length=255) + slug = models.SlugField(unique=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.name + +class Profile(models.Model): + ROLE_CHOICES = ( + ('SUPER_ADMIN', 'Super Admin'), + ('ORG_ADMIN', 'Organization Admin'), + ('USER', 'User'), + ) + user = models.OneToOneField(User, on_delete=models.CASCADE) + organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, null=True, blank=True, related_name='members') + role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='USER') + + def __str__(self): + return f"{self.user.username} - {self.role}" + +@receiver(post_save, sender=User) +def create_user_profile(sender, instance, created, **kwargs): + if created: + Profile.objects.create(user=instance) + +@receiver(post_save, sender=User) +def save_user_profile(sender, instance, **kwargs): + instance.profile.save() + +class ChatMessage(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + organization = models.ForeignKey(Organization, on_delete=models.CASCADE, null=True, blank=True) + message = models.TextField() + response = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Chat at {self.created_at}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..db59b26 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,67 @@ - - - {% block title %}Knowledge Base{% endblock %} - {% if project_description %} - - - - {% endif %} - {% if project_image_url %} - - - {% endif %} - {% load static %} - - {% block head %}{% endblock %} + + + {% block title %}AIBiz Platform - AI-Driven B2B SaaS{% endblock %} + {% if project_description %} + + + + {% endif %} + {% if project_image_url %} + + + {% endif %} + + + + + + + + + + {% load static %} + + {% block head %}{% endblock %} + + - - {% block content %}{% endblock %} +
+ {% block content %}{% endblock %} +
+ +
+
+
+
+
AIBiz Platform
+

Empowering businesses with production-ready AI workflows.

+
+
+

© 2026 AIBiz Platform. All rights reserved.

+
+
+
+
+ + - - + \ No newline at end of file diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..6469d09 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,145 +1,128 @@ {% extends "base.html" %} - -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} - - - - -{% endblock %} +{% load static %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
+
+
+
+ Enterprise Ready AI +

Scale Your Business with Intelligent Workflows

+

The ultimate AI-driven SaaS platform for multitenant organizations. Manage teams, automate documents, and chat with your business intelligence.

+ +
+
+
+
+
AI
+
AIBiz Assistant
+
+
+
+
+ Hello! I'm your AIBiz Assistant. How can I help you optimize your business today? +
+
+
+
+ + +
+
+
+
+
+
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
-
-
- Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC) -
-{% endblock %} \ No newline at end of file + + +
+
+
+

Everything You Need to Succeed

+

Powerful tools designed for the modern B2B ecosystem.

+
+
+
+
+
🏢
+
Multitenancy
+

Built-in organization management with isolated data and custom roles.

+
+
+
+
+
🤖
+
AI Chat
+

Context-aware assistant trained on your business data and workflows.

+
+
+
+
+
📄
+
Doc Ingestion
+

Automated summarization and data extraction from complex business documents.

+
+
+
+
+
+ + +{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..fd499c3 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,7 @@ from django.urls import path - -from .views import home +from .views import home, ai_chat urlpatterns = [ path("", home, name="home"), -] + path("api/ai-chat/", ai_chat, name="ai_chat"), +] \ No newline at end of file diff --git a/core/views.py b/core/views.py index c9aed12..619c0b7 100644 --- a/core/views.py +++ b/core/views.py @@ -1,25 +1,59 @@ import os import platform - +import json from django import get_version as django_version from django.shortcuts import render +from django.http import JsonResponse from django.utils import timezone - +from django.views.decorators.csrf import csrf_exempt +from ai.local_ai_api import LocalAIApi +from .models import ChatMessage, Organization def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" + """Render the landing screen with AI Chat Assistant.""" now = timezone.now() - + context = { - "project_name": "New Style", - "agent_brand": agent_brand, + "project_name": "AIBiz Platform", "django_version": django_version(), "python_version": platform.python_version(), "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), + "project_description": os.getenv("PROJECT_DESCRIPTION", "AI-Driven B2B SaaS Platform for modern enterprises."), "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), } return render(request, "core/index.html", context) + +@csrf_exempt +def ai_chat(request): + if request.method == "POST": + try: + data = json.loads(request.body) + user_message = data.get("message") + + if not user_message: + return JsonResponse({"error": "No message provided"}, status=400) + + # Construct the prompt for the AI + messages = [ + {"role": "system", "content": "You are AIBiz Assistant, an expert in business workflows, SaaS, and AI automation. Help the user with their business questions concisely and professionally."}, + {"role": "user", "content": user_message}, + ] + + response = LocalAIApi.create_response( + {"input": messages}, + {"poll_interval": 2, "poll_timeout": 60} + ) + + if response.get("success"): + ai_reply = LocalAIApi.extract_text(response) or "I'm sorry, I couldn't generate a response." + + # Save message to DB if user is authenticated (optional for landing) + # ChatMessage.objects.create(message=user_message, response=ai_reply) + + return JsonResponse({"reply": ai_reply}) + else: + return JsonResponse({"error": response.get("error", "AI service error")}, status=500) + except Exception as e: + return JsonResponse({"error": str(e)}, status=500) + + return JsonResponse({"error": "Invalid request"}, status=400) \ No newline at end of file diff --git a/static/css/custom.css b/static/css/custom.css index 925f6ed..0ccb83f 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -1,4 +1,104 @@ -/* Custom styles for the application */ -body { - font-family: system-ui, -apple-system, sans-serif; +:root { + --primary-color: #2563eb; + --secondary-color: #0f172a; + --accent-color: #10b981; + --bg-light: #f8fafc; + --navy: #0f172a; } + +body { + font-family: 'Plus Jakarta Sans', sans-serif; + color: #334155; + background-color: var(--bg-light); +} + +.text-primary { color: var(--primary-color) !important; } +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + font-weight: 600; +} +.btn-primary:hover { + background-color: #1d4ed8; +} + +.bg-navy { background-color: var(--navy); } + +/* Hero Section */ +.hero-section { + padding: 100px 0; + background: radial-gradient(circle at top right, rgba(37, 99, 235, 0.05), transparent), + radial-gradient(circle at bottom left, rgba(16, 185, 129, 0.05), transparent); +} + +.glass-card { + background: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); +} + +/* Chat Assistant Widget */ +.chat-container { + height: 400px; + display: flex; + flex-direction: column; +} + +.chat-messages { + flex-grow: 1; + overflow-y: auto; + padding: 15px; +} + +.chat-bubble { + padding: 10px 15px; + border-radius: 15px; + margin-bottom: 10px; + max-width: 85%; + font-size: 0.9rem; +} + +.bubble-ai { + background-color: #f1f5f9; + color: #1e293b; + align-self: flex-start; +} + +.bubble-user { + background-color: var(--primary-color); + color: white; + align-self: flex-end; + margin-left: auto; +} + +.chat-input-area { + padding: 15px; + border-top: 1px solid #e2e8f0; +} + +.feature-card { + padding: 30px; + border-radius: 20px; + background: white; + transition: transform 0.3s ease; + border: 1px solid #e2e8f0; +} + +.feature-card:hover { + transform: translateY(-5px); +} + +.feature-icon { + width: 50px; + height: 50px; + background: rgba(37, 99, 235, 0.1); + color: var(--primary-color); + display: flex; + align-items: center; + justify-content: center; + border-radius: 12px; + margin-bottom: 20px; + font-size: 1.5rem; +} \ No newline at end of file diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 108056f..0ccb83f 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -1,21 +1,104 @@ - :root { - --bg-color-start: #6a11cb; - --bg-color-end: #2575fc; - --text-color: #ffffff; - --card-bg-color: rgba(255, 255, 255, 0.01); - --card-border-color: rgba(255, 255, 255, 0.1); + --primary-color: #2563eb; + --secondary-color: #0f172a; + --accent-color: #10b981; + --bg-light: #f8fafc; + --navy: #0f172a; } + body { - margin: 0; - font-family: 'Inter', sans-serif; - background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); - color: var(--text-color); - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; - text-align: center; - overflow: hidden; - position: relative; + font-family: 'Plus Jakarta Sans', sans-serif; + color: #334155; + background-color: var(--bg-light); } + +.text-primary { color: var(--primary-color) !important; } +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + font-weight: 600; +} +.btn-primary:hover { + background-color: #1d4ed8; +} + +.bg-navy { background-color: var(--navy); } + +/* Hero Section */ +.hero-section { + padding: 100px 0; + background: radial-gradient(circle at top right, rgba(37, 99, 235, 0.05), transparent), + radial-gradient(circle at bottom left, rgba(16, 185, 129, 0.05), transparent); +} + +.glass-card { + background: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); +} + +/* Chat Assistant Widget */ +.chat-container { + height: 400px; + display: flex; + flex-direction: column; +} + +.chat-messages { + flex-grow: 1; + overflow-y: auto; + padding: 15px; +} + +.chat-bubble { + padding: 10px 15px; + border-radius: 15px; + margin-bottom: 10px; + max-width: 85%; + font-size: 0.9rem; +} + +.bubble-ai { + background-color: #f1f5f9; + color: #1e293b; + align-self: flex-start; +} + +.bubble-user { + background-color: var(--primary-color); + color: white; + align-self: flex-end; + margin-left: auto; +} + +.chat-input-area { + padding: 15px; + border-top: 1px solid #e2e8f0; +} + +.feature-card { + padding: 30px; + border-radius: 20px; + background: white; + transition: transform 0.3s ease; + border: 1px solid #e2e8f0; +} + +.feature-card:hover { + transform: translateY(-5px); +} + +.feature-icon { + width: 50px; + height: 50px; + background: rgba(37, 99, 235, 0.1); + color: var(--primary-color); + display: flex; + align-items: center; + justify-content: center; + border-radius: 12px; + margin-bottom: 20px; + font-size: 1.5rem; +} \ No newline at end of file