v1.8.0: bge-m3 embeddings, qwen3 LLM, retrieval fixes, input validation, memory poisoning fix

This commit is contained in:
2026-05-28 18:54:05 +00:00
parent e87b33f403
commit 7ce5c6f7d0
1433 changed files with 63814 additions and 199 deletions
+374
View File
@@ -0,0 +1,374 @@
<!DOCTYPE html>
<html class="dark" lang="ar" dir="rtl">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>المكتبة — AfakZaid RAG</title>
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
<script>tailwind.config={darkMode:"class",safelist:["grid","grid-cols-2","grid-cols-3","grid-cols-4","md:grid-cols-3","lg:grid-cols-4","gap-4","space-y-3","col-span-4"],theme:{extend:{colors:{"primary":"#4edea3","surface":"#0c1324","surface-low":"#151b2d","surface-container":"#191f31","surface-high":"#23293c","on-surface":"#dce1fb","on-surface-variant":"#bbcabf","outline-variant":"#3c4a42","secondary":"#95d3ba","tertiary":"#45dfa4","error":"#f87171"},fontFamily:{sans:["Manrope","sans-serif"]}}}}</script>
<style>
:root {
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
}
*{box-sizing:border-box}
body{background:radial-gradient(circle at 50% -20%,#151b2d 0%,#0c1324 100%);font-family:'Manrope',sans-serif;color:#dce1fb;min-height:100vh}
/* Glass: purposeful, not default — liquid glass per design-taste */
.glass{
background:rgba(21,27,45,0.5);
backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
border:1px solid rgba(78,222,163,0.12);
box-shadow:inset 0 1px 0 rgba(255,255,255,0.04);
}
.glass-hover { transition: background 180ms ease, border-color 180ms ease; }
@media (hover: hover) and (pointer: fine) {
.glass-hover:hover { background:rgba(78,222,163,0.06); border-color:rgba(78,222,163,0.22); }
}
.glow{box-shadow:0 0 20px rgba(78,222,163,0.15)}
.glow-sm{box-shadow:0 0 10px rgba(78,222,163,0.1)}
.msym{font-family:'Material Symbols Outlined';font-variation-settings:'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 24;vertical-align:middle;line-height:1}
/* Filter chips — specific transitions */
.filter-chip {
padding:6px 14px; border-radius:999px; font-size:12px; font-weight:600; cursor:pointer;
border:1px solid rgba(78,222,163,0.15); background:rgba(21,27,45,0.5); color:#bbcabf;
transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out);
will-change: transform;
}
.filter-chip.active { background:rgba(78,222,163,0.12); border-color:rgba(78,222,163,0.4); color:#4edea3; }
@media (hover: hover) and (pointer: fine) {
.filter-chip:hover { background:rgba(78,222,163,0.08); border-color:rgba(78,222,163,0.3); color:#4edea3; }
}
.filter-chip:active { transform: scale(0.97); }
.scrollbar::-webkit-scrollbar{width:4px}
.scrollbar::-webkit-scrollbar-thumb{background:rgba(78,222,163,0.2);border-radius:4px}
.inp{
background:#23293c; border:1px solid #3c4a42; border-radius:12px;
padding:10px 14px; color:#dce1fb; font-size:13px; outline:none;
transition: border-color 180ms ease, box-shadow 180ms ease;
font-family:'Manrope',sans-serif; width:100%;
}
.inp:focus { border-color:#4edea3; box-shadow:0 0 0 2px rgba(78,222,163,0.1); }
/* Book card — purposeful hover, only pointer devices */
.book-card {
transition: transform 200ms var(--ease-out), box-shadow 200ms ease, border-color 200ms ease;
will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
.book-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(78,222,163,0.1);
border-color: rgba(78,222,163,0.28) !important;
}
}
.book-card:active { transform: scale(0.98); }
/* Skeleton loading — design-taste: layout-matching shimmer */
@keyframes shimmer {
0% { background-position: -400px 0; }
100% { background-position: 400px 0; }
}
.skeleton {
background: linear-gradient(90deg, #1a2035 25%, #23293c 50%, #1a2035 75%);
background-size: 800px 100%;
animation: shimmer 1.4s ease-in-out infinite;
border-radius: 8px;
}
/* Upload zone */
.upload-zone {
border: 2px dashed rgba(78,222,163,0.2);
transition: border-color 200ms ease, background 200ms ease;
}
@media (hover: hover) and (pointer: fine) {
.upload-zone:hover { border-color: rgba(78,222,163,0.45); background: rgba(78,222,163,0.03); }
}
.upload-zone.dragover { border-color:rgba(78,222,163,0.6); background:rgba(78,222,163,0.05); }
/* Fav button pulse on add */
@keyframes favPulse {
0% { transform: scale(1); }
40% { transform: scale(1.35); }
100% { transform: scale(1); }
}
.fav-btn.added { animation: favPulse 350ms var(--ease-out); color: #f87171 !important; }
/* Page entry */
@keyframes fadeUp {
from { opacity:0; transform:translateY(8px); }
to { opacity:1; transform:translateY(0); }
}
header { animation: fadeUp 350ms var(--ease-out) both; }
.search-section { animation: fadeUp 400ms var(--ease-out) 80ms both; }
.books-section { animation: fadeUp 400ms var(--ease-out) 160ms both; }
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
transition-duration: .01ms !important;
}
.skeleton { animation: none; background: #1a2035; }
}
/* ── Mobile-visible improvements ─────────────────────────────────────────── */
/* Larger touch targets — 44px minimum per Apple HIG */
button, a, .filter-chip, .book-card, .stat-card, .nav-btn {
-webkit-tap-highlight-color: transparent;
}
/* Tap feedback — visible on ALL devices including mobile */
.book-card:active,
.stat-card:active,
.filter-chip:active {
transform: scale(0.97) !important;
transition: transform 100ms ease !important;
}
/* Buttons get a visible press state on tap */
button:active:not(:disabled) {
filter: brightness(0.9);
transform: scale(0.97);
transition: transform 100ms ease, filter 100ms ease !important;
}
/* Restore .glow — ensure it stacks correctly */
.glow {
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.06),
0 0 20px rgba(78,222,163,0.15) !important;
}
.glow-sm {
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.04),
0 0 10px rgba(78,222,163,0.1) !important;
}
/* Mobile: book cards get a more visible pressed state */
@media (max-width: 768px) {
.book-card {
transition: transform 150ms ease, opacity 150ms ease !important;
}
.book-card:active {
transform: scale(0.97) !important;
opacity: 0.85 !important;
}
/* Ensure skeleton is visible on mobile */
.skeleton {
background: linear-gradient(90deg, #1a2035 25%, #2a3348 50%, #1a2035 75%) !important;
background-size: 800px 100% !important;
animation: shimmer 1.2s ease-in-out infinite !important;
}
/* Better spacing on small screens */
.filter-chip {
padding: 8px 16px !important;
font-size: 13px !important;
}
}
/* ── design-taste-frontend: Liquid Glass + Spotlight ─────────────────────── */
/* True liquid glass — inner refraction border */
/* NOTE: does NOT define outer shadow — .glow still wins */
.glass {
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.06),
inset 0 -1px 0 rgba(0,0,0,0.2);
}
/* Combined: liquid glass + green glow */
.glass.glow {
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.06),
inset 0 -1px 0 rgba(0,0,0,0.2),
0 0 20px rgba(78,222,163,0.18),
0 4px 24px rgba(0,0,0,0.15);
}
.glass.glow-sm {
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.06),
inset 0 -1px 0 rgba(0,0,0,0.2),
0 0 10px rgba(78,222,163,0.12);
}
/* .glow overrides naturally on top — no !important needed */
/* Spotlight border card — JS-driven cursor tracking */
.spotlight-card {
position: relative;
overflow: hidden;
}
.spotlight-card::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(
400px circle at var(--mx, 50%) var(--my, 50%),
rgba(78,222,163,0.06),
transparent 60%
);
opacity: 0;
transition: opacity 300ms ease;
pointer-events: none;
border-radius: inherit;
z-index: 0;
}
@media (hover: hover) and (pointer: fine) {
.spotlight-card:hover::before { opacity: 1; }
}
/* Ensure content above spotlight overlay */
.spotlight-card > * { position: relative; z-index: 1; }
/* Tactile button press — design-taste rule */
button:not(:disabled):active,
a[role=button]:active {
transform: translateY(-1px) scale(0.98) !important;
transition-duration: 80ms !important;
}
/* Hardware acceleration on animated elements */
.stat-card, .book-card, .query-card, .books-card, .upload-card-wrap {
transform: translateZ(0);
backface-visibility: hidden;
}
/* Directional hover-aware CTA — shimmer from left on hover */
.cta-primary {
position: relative; overflow: hidden;
}
.cta-primary::before {
content: '';
position: absolute;
top: 0; left: -100%; bottom: 0; width: 50%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
transition: left 400ms cubic-bezier(0.77,0,0.175,1);
pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
.cta-primary:hover::before { left: 200%; }
}
/* ── Mobile improvements (actually visible on mobile) ────────────────────── */
/* Larger touch targets — 44px minimum per Apple HIG */
@media (max-width: 768px) {
/* Bigger tap areas on buttons */
button, a { min-height: 44px; }
.filter-chip { padding: 8px 16px; font-size: 13px; }
/* Book cards: more breathing room on mobile */
.book-card { padding: 14px !important; }
/* Stats cards: larger numbers on mobile */
.stat-card .stat-num, #s-books, #s-vectors, #s-convos, #s-memory {
font-size: 1.75rem;
}
/* Header: tighter on mobile */
header { padding-top: 10px; padding-bottom: 10px; }
/* Search input: larger font so iOS doesn't zoom */
#search-input, .inp, textarea, input[type="text"], input[type="email"], input[type="password"] {
font-size: 16px !important; /* prevents iOS zoom on focus */
}
/* Bottom action bar spacing */
main { padding-bottom: env(safe-area-inset-bottom, 16px); }
}
/* Reader: full height on mobile */
@media (max-width: 768px) {
#pdf-frame { position: absolute; inset: 0; }
.reader-header { padding: 8px 12px; }
}
/* FORCE LAYOUT — overrides everything */
main {
display: block !important;
width: 100% !important;
max-width: 72rem !important;
margin-left: auto !important;
margin-right: auto !important;
box-sizing: border-box !important;
}
/* Grid view */
#books-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
@media (max-width: 768px) {
#books-container { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
#books-container { grid-template-columns: 1fr; }
}
/* List view — overrides grid completely */
#books-container.books-list {
display: flex;
flex-direction: column;
gap: 12px;
}
/* Sticky footer — no layout impact */
#sticky-footer { position: sticky; top: 100vh; }
</style>
<script src="/static/analytics.js" defer></script>
<link rel="privacy-policy" href="https://rag.afaqzaid.com/privacy"/>
</head>
<body>
<div id="universal-header"></div>
<main class="max-w-3xl" mx-auto px-4 lg:px-8 py-10">
<div class="glass rounded-2xl p-8" style="border:1px solid rgba(78,222,163,0.12)">
<div class="flex items-center gap-3 mb-8 pb-6 border-b border-white/5">
<div class="w-10 h-10 bg-primary/15 rounded-xl flex items-center justify-center shrink-0">
<span class="msym text-primary text-xl">gavel</span>
</div>
<div>
<h1 class="text-xl font-bold">شروط الخدمة</h1>
<p class="text-xs text-on-surface-variant mt-1">آخر تحديث: مايو 2026</p>
</div>
</div>
<div class="space-y-6 text-on-surface-variant leading-relaxed text-sm">
<div><h2 class="text-primary font-bold mb-2">١. الاستخدام المقبول</h2>
<p>يُسمح باستخدام المنصة لأغراض تعليمية وبحثية مشروعة. يُمنع رفع محتوى مخالف للحقوق أو القوانين المعمول بها.</p></div>
<div><h2 class="text-primary font-bold mb-2">٢. ربط Google Drive</h2>
<p>عند ربط حسابك بـ Google Drive، فإنك تمنح المنصة صلاحية القراءة فقط للملفات التي تختار استيرادها. يمكنك إلغاء هذا الإذن في أي وقت من إعدادات حسابك في Google.</p></div>
<div><h2 class="text-primary font-bold mb-2">٣. المسؤولية</h2>
<p>أنت مسؤول عن المحتوى الذي ترفعه والتأكد من امتلاك حقوق استخدامه.</p></div>
<div><h2 class="text-primary font-bold mb-2">٤. تعديل الشروط</h2>
<p>نحتفظ بحق تعديل هذه الشروط في أي وقت مع إشعار المستخدمين.</p></div>
<div><h2 class="text-primary font-bold mb-2">٥. التواصل</h2>
<p>لأي استفسار: <a href="mailto:admin@afaqzaid.com" class="text-primary hover:underline">admin@afaqzaid.com</a></p></div>
</div>
</div>
</main>
<div id="universal-footer"></div>
<script src="/components.js"></script>
</body>
</html>