1<!DOCTYPE html> 2<html lang="ar" dir="rtl"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 7 <!-- Set UI language/direction before React mounts to avoid a flash (FOUC). 8 Mirrors i18n STORAGE_KEY 'almustashar_lang'; defaults to Arabic/RTL. --> 9
9<script> 10 (function () { 11 try { 12 var lang = localStorage.getItem('almustashar_lang'); 13 if (lang === 'en') { 14 document.documentElement.lang = 'en'; 15 document.documentElement.dir = 'ltr'; 16 } 17 } catch (e) {} 18 })(); 19 </script>
19 20 <title>اÙ٠ستشار â ٠ساعد٠اÙÙØ§ÙÙÙÙ Ø§ÙØ°ÙÙ</title> 21 22 <!-- SEO Description --> 23 <meta name="description" content="٠ساعد ÙØ§ÙÙÙ٠ذÙ٠٠تخصص ÙÙ Ø§ÙØ£Ùظ٠ة ÙØ§ÙÙÙØ§Ø¦Ø Ø§ÙØ³Ø¹ÙØ¯ÙØ©." /> 24 25 <!-- Open Graph / Facebook / WhatsApp --> 26 <meta property="og:type" content="website" /> 27 <meta property="og:title" content="اÙ٠ستشار â ٠ساعد٠اÙÙØ§ÙÙÙÙ Ø§ÙØ°ÙÙ" /> 28 <meta property="og:description" content="٠ساعد ÙØ§ÙÙÙ٠ذÙ٠٠تخصص ÙÙ Ø§ÙØ£Ùظ٠ة ÙØ§ÙÙÙØ§Ø¦Ø Ø§ÙØ³Ø¹ÙØ¯ÙØ©." /> 29 <!-- Social sharing image --> 30 <meta property="og:image" content="/favicon-96x96.png" /> 31 <meta property="og:image:width" content="96" /> 32 <meta property="og:image:height" content="96" /> 33 34 <!-- Twitter --> 35 <meta name="twitter:card" content="summary" /> 36 <meta name="twitter:title" content="اÙ٠ستشار â ٠ساعد٠اÙÙØ§ÙÙÙÙ Ø§ÙØ°ÙÙ" /> 37 <meta name="twitter:description" content="٠ساعد ÙØ§ÙÙÙ٠ذÙ٠٠تخصص ÙÙ Ø§ÙØ£Ùظ٠ة ÙØ§ÙÙÙØ§Ø¦Ø Ø§ÙØ³Ø¹ÙØ¯ÙØ©." /> 38 <meta name="twitter:image" content="/favicon-96x96.png" /> 39 40 <!-- Favicon --> 41 <link rel="icon" href="/favicon.ico" sizes="48x48" /> 42 <link rel="icon" href="/favicon.svg" type="image/svg+xml" /> 43 <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> 44 <link rel="manifest" href="/site.webmanifest" /> 45 46 <!-- Cloudflare Turnstile --> 47
47<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
47 48 49
49<script src="https://cdn.tailwindcss.com"></script>
49 50
50<script> 51 // Brand gold, sampled from the logo (#B29022 = gold-600). Replaces the old indigo/purple accents. 52 tailwind.config = { 53 theme: { 54 extend: { 55 colors: { 56 gold: { 57 50: '#fbf7ea', 100: '#f5eccb', 200: '#ebd897', 300: '#ddbf5e', 400: '#cba73a', 58 500: '#bf9a2a', 600: '#b29022', 700: '#8f731b', 800: '#6e5916', 900: '#4f4011', 59 }, 60 }, 61 }, 62 }, 63 }; 64 </script>
64 65 <link rel="preconnect" href="https://fonts.googleapis.com"> 66 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 67 <link href="https://fonts.googleapis.com/css2?family=Almarai:wght@400;700;800&family=Tajawal:wght@300;400;500;700&display=swap" rel="stylesheet"> 68 <style> 69 :root { 70 /* Corporate Legal Green Palette */ 71 --primary-900: #064e3b; 72 --primary-800: #065f46; 73 --primary-700: #047857; 74 --primary-600: #059669; 75 --primary-500: #10b981; 76 --primary-100: #d1fae5; 77 --primary-50: #ecfdf5; 78 79 /* Neutral palette */ 80 --neutral-900: #111827; 81 --neutral-800: #1f2937; 82 --neutral-700: #374151; 83 --neutral-600: #4b5563; 84 --neutral-500: #6b7280; 85 --neutral-400: #9ca3af; 86 --neutral-300: #d1d5db; 87 --neutral-200: #e5e7eb; 88 --neutral-100: #f3f4f6; 89 --neutral-50: #f9fafb; 90 91 /* Accent - Gold for legal feel */ 92 --accent-500: #b45309; 93 --accent-400: #d97706; 94 } 95 96 body { 97 font-family: 'Tajawal', sans-serif; 98 background-color: var(--neutral-50); 99 color: var(--neutral-800); 100 } 101 102 /* Custom Scrollbar - refined */ 103 ::-webkit-scrollbar {
104 width: 6px; 105 } 106 ::-webkit-scrollbar-track { 107 background: transparent; 108 } 109 ::-webkit-scrollbar-thumb { 110 background: var(--neutral-300); 111 border-radius: 3px; 112 } 113 ::-webkit-scrollbar-thumb:hover { 114 background: var(--neutral-400); 115 } 116 117 /* Markdown content â direction is content-driven via the element's dir 118 attribute (ChatBubble sets it per message; admin uses dir="auto"). 119 Alignment uses logical 'start' so English renders LTR, Arabic RTL. */ 120 .markdown-content { 121 text-align: start; 122 overflow-wrap: break-word; 123 word-wrap: break-word; 124 max-width: 100%; 125 } 126 127 .markdown-content * { 128 max-width: 100%; 129 overflow-wrap: break-word; 130 } 131 132 /* Text elements â alignment follows content direction */ 133 .markdown-content p, 134 .markdown-content li, 135 .markdown-content h1, 136 .markdown-content h2, 137 .markdown-content h3, 138 .markdown-content h4, 139 .markdown-content th, 140 .markdown-content td { 141 text-align: start; 142 } 143 144 .markdown-content p { 145 margin-bottom: 0.5rem; 146 white-space: pre-wrap; 147 } 148 149 .markdown-content strong, 150 .markdown-content b { 151 font-weight: 700; 152 } 153 154 /* Lists â bullets/numbers on the leading side (right in RTL, left in LTR) */ 155 .markdown-content ul, 156 .markdown-content ol { 157 text-align: start; 158 padding-inline-start: 1.5rem; 159 padding-inline-end: 0; 160 margin-bottom: 0.5rem; 161 } 162 163 .markdown-content li { 164 text-align: start; 165 margin-bottom: 0.25rem; 166 } 167 168 /* Code blocks - auto-detect direction */ 169 .markdown-content pre { 170 direction: auto; 171 text-align: start; 172 unicode-bidi: plaintext; 173 white-space: pre-wrap; 174 overflow-x: auto; 175 max-width: 100%; 176 background: #f3f4f6; 177 padding: 0.75rem; 178 border-radius: 0.5rem; 179 font-size: 0.875rem; 180 } 181 182 .markdown-content code { 183 direction: auto; 184 unicode-bidi: plaintext; 185 background: #f3f4f6; 186 padding: 0.125rem 0.375rem; 187 border-radius: 0.25rem; 188 font-size: 0.875em; 189 } 190 191 .markdown-content h1 { font-size: 1.5rem; font-weight: 700; margin: 1rem 0 0.75rem; text-align: start; } 192 .markdown-content h2 { font-size: 1.25rem; font-weight: 700; margin: 0.75rem 0 0.5rem; text-align: start; } 193 .markdown-content h3 { font-size: 1.125rem; font-weight: 700; margin: 0.5rem 0; text-align: start; } 194 195 /* Table styling */ 196 .markdown-content table { 197 width: 100%; 198 border-collapse: collapse; 199 margin: 1rem 0; 200 font-size: 0.9rem; 201 border-radius: 0.5rem; 202 overflow: hidden; 203 box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); 204 border: 1px solid #e5e7eb; 205 } 206 207 .markdown-content thead { 208 background: linear-gradient(to bottom, #f8fafc, #f1f5f9); 209 } 210 211 .markdown-content th { 212 padding: 0.875rem 1rem; 213 font-weight: 600; 214 color: #374151; 215 border-bottom: 2px solid #e5e7eb; 216 text-align: start; 217 } 218 219 .markdown-content td { 220 padding: 0.75rem 1rem; 221 color: #4b5563; 222 border-bottom: 1px solid #e5e7eb; 223 vertical-align: top; 224 } 225 226 .markdown-content tbody tr:nth-child(even) { 227 background-color: #f9fafb; 228 } 229 230 .markdown-content tbody tr:hover { 231 background-color: #f3f4f6; 232 } 233 234 .markdown-content tbody tr:last-child td { 235 border-bottom: none; 236 } 237 238 .markdown-content blockquote { 239 text-align: start; 240 border-inline-start: 4px solid var(--primary-700); 241 padding-inline-start: 1rem; 242 margin: 0 0 0.5rem 0; 243 color: var(--neutral-600); 244 font-style: italic; 245 } 246 247 /* Professional button styles */ 248 .btn-primary { 249 background-color: var(--primary-800); 250 color: white; 251 transition: background-color 0.2s ease; 252 } 253 .btn-primary:hover { 254 background-color: var(--primary-700); 255 } 256 .btn-primary:disabled { 257 background-color: var(--neutral-300); 258 color: var(--neutral-500); 259 } 260 261 /* Focus states */ 262 .focus-ring:focus { 263 outline: none; 264 box-shadow: 0 0 0 2px var(--primary-100), 0 0 0 4px var(--primary-600); 265 } 266 267 /* Streaming indicator â the three dots shown while waiting for the AI. 268 Animates opacity only, never transform, so the dots stay on one 269 baseline. Tailwind's animate-bounce translated each dot vertically and 270 the staggered delays left them visibly out of line. */ 271 .typing-dot { 272 animation: typing-dot-fade 1.4s ease-in-out infinite; 273 } 274 @keyframes typing-dot-fade { 275 0%, 60%, 100% { opacity: 0.25; } 276 30% { opacity: 1; } 277 } 278 @media (prefers-reduced-motion: reduce) { 279 .typing-dot { animation: none; opacity: 0.6; } 280 } 281 </style> 282 283
283<script type="importmap"> 284{ 285 "imports": { 286 "react/": "https://aistudiocdn.com/react@^19.2.0/", 287 "react": "https://aistudiocdn.com/react@^19.2.0", 288 "react-dom/": "https://aistudiocdn.com/react-dom@^19.2.0/", 289 "@google/genai": "https://aistudiocdn.com/@google/genai@^1.30.0", 290 "react-markdown": "https://aistudiocdn.com/react-markdown@^10.1.0", 291 "jszip": "https://esm.run/jszip", 292 "file-saver": "https://esm.run/file-saver" 293 } 294} 295</script>
295 296
296<script type="module" crossorigin src="/assets/index-BEvyjLS9.js"></script>
296 297</head> 298 <body> 299 <div id="root"></div> 300
300<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"71f6dc726e094d39b3c73f7a03c09b0b","r":1,"spa":2}' crossorigin="anonymous"></script>
300 301</body> 302</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.