AYI-NEDJIMI commited on
Commit
61c3f1c
·
verified ·
1 Parent(s): ac9f74c

Deploy professional portfolio landing page - CyberSec & AI

Browse files
Files changed (3) hide show
  1. README.md +26 -6
  2. app.py +833 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,12 +1,32 @@
1
  ---
2
  title: Portfolio CyberSec AI
3
- emoji:
4
- colorFrom: yellow
5
- colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 6.6.0
8
  app_file: app.py
9
- pinned: false
 
 
 
 
 
 
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Portfolio CyberSec AI
3
+ emoji: "\U0001F6E1\uFE0F"
4
+ colorFrom: red
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 5.12.0
8
  app_file: app.py
9
+ pinned: true
10
+ license: apache-2.0
11
+ tags:
12
+ - portfolio
13
+ - cybersecurity
14
+ - ai
15
+ - consultant
16
+ - ayinedjimi-consultants
17
+ short_description: "Senior Offensive Cybersecurity & AI Consultant Portfolio"
18
  ---
19
 
20
+ # Portfolio - AYI NEDJIMI
21
+
22
+ Senior Offensive Cybersecurity & AI Consultant
23
+
24
+ Professional portfolio showcasing 4 fine-tuned models, 40 interactive Spaces, 85 cybersecurity datasets, and published research articles on Hugging Face.
25
+
26
+ ## Links
27
+
28
+ - Website: https://www.ayinedjimi-consultants.fr
29
+ - LinkedIn: https://www.linkedin.com/in/ayi-nedjimi
30
+ - GitHub: https://github.com/ayinedjimi
31
+ - Twitter/X: https://x.com/AyiNEDJIMI
32
+ - Collection: https://huggingface.co/collections/AYI-NEDJIMI/cybersec-ai-portfolio-datasets-models-and-spaces-699224074a478ec0feeac493
app.py ADDED
@@ -0,0 +1,833 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Portfolio - AYI NEDJIMI
3
+ Senior Offensive Cybersecurity & AI Consultant
4
+ """
5
+
6
+ import gradio as gr
7
+ import requests
8
+ import json
9
+ from datetime import datetime
10
+
11
+ # ============================================================
12
+ # DATA
13
+ # ============================================================
14
+
15
+ MODELS = [
16
+ {
17
+ "name": "m365-expert-v3",
18
+ "full": "AYI-NEDJIMI/m365-expert-v3",
19
+ "desc": "Expert-level Microsoft 365 administration assistant covering PowerShell, Microsoft Graph, Entra ID, SharePoint, Exchange Online, Intune, and Teams. Full GGUF quantized versions available for Ollama deployment.",
20
+ "base": "Qwen/Qwen3-8B",
21
+ "tags": ["Microsoft 365", "PowerShell", "Graph API", "Entra ID", "GGUF", "Ollama"],
22
+ "lang": "FR / EN",
23
+ "method": "QLoRA Fine-tuning",
24
+ "downloads": 25,
25
+ },
26
+ {
27
+ "name": "CyberSec-Assistant-3B",
28
+ "full": "AYI-NEDJIMI/CyberSec-Assistant-3B",
29
+ "desc": "Cybersecurity compliance assistant covering GDPR/RGPD, NIS2, DORA, AI Act, ISO 27001, MITRE ATT&CK, OWASP, pentesting, SOC operations, Zero Trust, and DevSecOps.",
30
+ "base": "Qwen/Qwen2.5-3B-Instruct",
31
+ "tags": ["Cybersecurity", "Compliance", "GDPR", "NIS2", "MITRE ATT&CK", "OWASP"],
32
+ "lang": "FR / EN",
33
+ "method": "QLoRA + LoRA Fine-tuning",
34
+ "downloads": 12,
35
+ },
36
+ {
37
+ "name": "ISO27001-Expert-1.5B",
38
+ "full": "AYI-NEDJIMI/ISO27001-Expert-1.5B",
39
+ "desc": "Specialized ISO/IEC 27001:2022 expert for information security management systems (ISMS), risk management, security controls, and audit procedures.",
40
+ "base": "Qwen/Qwen2.5-1.5B-Instruct",
41
+ "tags": ["ISO 27001", "ISMS", "Compliance", "Risk Management", "Audit"],
42
+ "lang": "FR / EN",
43
+ "method": "QLoRA Fine-tuning",
44
+ "downloads": 11,
45
+ },
46
+ {
47
+ "name": "RGPD-Expert-1.5B",
48
+ "full": "AYI-NEDJIMI/RGPD-Expert-1.5B",
49
+ "desc": "GDPR/RGPD data protection expert covering DPO, DPIA, consent management, breach notification procedures, and privacy compliance frameworks.",
50
+ "base": "Qwen/Qwen2.5-1.5B-Instruct",
51
+ "tags": ["GDPR", "RGPD", "Data Protection", "Privacy", "DPO", "DPIA"],
52
+ "lang": "FR / EN",
53
+ "method": "QLoRA + LoRA Fine-tuning",
54
+ "downloads": 12,
55
+ },
56
+ ]
57
+
58
+ SPACES_BY_CATEGORY = {
59
+ "Security Explorers": [
60
+ ("iso27001-explorer", "ISO 27001 Explorer", "Interactive ISO 27001:2022 standard explorer"),
61
+ ("mitre-attack-explorer", "MITRE ATT&CK Explorer", "Navigate the MITRE ATT&CK framework"),
62
+ ("ad-attack-explorer", "AD Attack Explorer", "Active Directory attack techniques"),
63
+ ("owasp-top10-explorer", "OWASP Top 10 Explorer", "OWASP Top 10 vulnerabilities reference"),
64
+ ("zero-trust-explorer", "Zero Trust Explorer", "Zero Trust architecture principles"),
65
+ ("soc-analyst-explorer", "SOC Analyst Explorer", "SOC analyst operations guide"),
66
+ ("bug-bounty-pentest-explorer", "Bug Bounty & Pentest Explorer", "Bug bounty and penetration testing"),
67
+ ("devsecops-pipeline-explorer", "DevSecOps Pipeline Explorer", "DevSecOps pipeline reference"),
68
+ ],
69
+ "Security Tools": [
70
+ ("cve-lookup-tool", "CVE Lookup Tool", "Search and analyze CVE vulnerabilities"),
71
+ ("attack-path-visualizer", "Attack Path Visualizer", "Visualize attack paths with MITRE ATT&CK"),
72
+ ("security-assessment-generator", "Security Assessment Generator", "Generate security assessments"),
73
+ ("ad-attack-simulator", "AD Attack Simulator", "Simulate Active Directory attacks"),
74
+ ("ssrf-payload-generator", "SSRF Payload Generator", "Generate SSRF test payloads"),
75
+ ("ad-tiering-builder", "AD Tiering Builder", "Build Active Directory tiering models"),
76
+ ("kql-threat-hunting", "KQL Threat Hunting", "KQL queries for threat hunting"),
77
+ ("edr-evasion-explorer", "EDR Evasion Explorer", "EDR evasion techniques analysis"),
78
+ ("sbom-generator", "SBOM Generator", "Software Bill of Materials generator"),
79
+ ("forensics-timeline-builder", "Forensics Timeline Builder", "Digital forensics timeline builder"),
80
+ ],
81
+ "Compliance & GRC": [
82
+ ("compliance-checker", "Compliance Checker", "Multi-framework compliance assessment"),
83
+ ("m365-security-scorecard", "M365 Security Scorecard", "Microsoft 365 security scoring"),
84
+ ("ai-act-risk-classifier", "AI Act Risk Classifier", "EU AI Act risk classification"),
85
+ ("pqc-migration-planner", "PQC Migration Planner", "Post-quantum crypto migration planning"),
86
+ ("dora-assessment", "DORA Assessment", "DORA compliance assessment"),
87
+ ("Compliance-Assistant", "Compliance Assistant", "GDPR, ISO 27001, NIS2 compliance help"),
88
+ ("rgpd-gdpr-explorer", "RGPD/GDPR Explorer", "RGPD/GDPR regulation explorer"),
89
+ ("nis2-directive-explorer", "NIS2 Directive Explorer", "NIS2 directive requirements"),
90
+ ("cybersecurity-quiz", "Cybersecurity Quiz", "Interactive security training quiz"),
91
+ ],
92
+ "AI / ML Tools": [
93
+ ("rag-langchain-explorer", "RAG LangChain Explorer", "RAG pipeline with LangChain"),
94
+ ("prompt-engineering-explorer", "Prompt Engineering Explorer", "Prompt engineering techniques"),
95
+ ("mlops-infrastructure-explorer", "MLOps Infrastructure Explorer", "MLOps infrastructure reference"),
96
+ ("ai-agents-explorer", "AI Agents Explorer", "AI agents architecture patterns"),
97
+ ("llm-finetuning-explorer", "LLM Fine-tuning Explorer", "LLM fine-tuning methodologies"),
98
+ ("ai-code-multimodal-explorer", "AI Code & Multimodal Explorer", "Code generation and multimodal AI"),
99
+ ("ai-cybersecurity-explorer", "AI Cybersecurity Explorer", "AI for cybersecurity applications"),
100
+ ("ai-governance-explorer", "AI Governance Explorer", "AI governance frameworks"),
101
+ ],
102
+ "Model Demos": [
103
+ ("CyberSec-Models-Demo", "CyberSec Models Demo", "Interactive cybersecurity model demos"),
104
+ ("Model-Playground", "Model Playground", "Compare ISO27001, GDPR, RGPD models"),
105
+ ("CyberSec-Chat-RAG", "CyberSec Chat RAG", "RAG-powered cybersecurity chat"),
106
+ ("Dataset-Explorer", "Dataset Explorer", "Explore all cybersecurity datasets"),
107
+ ("portfolio", "Portfolio (Static)", "Original static portfolio page"),
108
+ ],
109
+ }
110
+
111
+ DATASETS_BY_DOMAIN = {
112
+ "Standards & Frameworks": [
113
+ "iso27001", "iso27001-en", "nist-csf-fr", "nist-csf-en",
114
+ "cis-controls-fr", "cis-controls-en", "mitre-attack-fr", "mitre-attack-en"
115
+ ],
116
+ "Offensive Security": [
117
+ "ad-attacks-fr", "ad-attacks-en", "owasp-top10-fr", "owasp-top10-en",
118
+ "pentest-checklist-fr", "pentest-checklist-en", "cve-top100-fr", "cve-top100-en"
119
+ ],
120
+ "EU Regulations & Compliance": [
121
+ "compliance-eu-fr", "compliance-eu-en", "ai-act-fr", "ai-act-en",
122
+ "dora-controls-fr", "dora-controls-en", "rgpd-fr", "rgpd-en"
123
+ ],
124
+ "Incident Response & DFIR": [
125
+ "incident-response-fr", "incident-response-en", "forensics-windows-fr",
126
+ "forensics-windows-en", "ransomware-playbooks-fr", "ransomware-playbooks-en"
127
+ ],
128
+ "Cloud & Infrastructure Security": [
129
+ "cloud-security-fr", "cloud-security-en", "k8s-security-fr", "k8s-security-en",
130
+ "m365-security-fr", "m365-security-en"
131
+ ],
132
+ "SOC & Threat Intelligence": [
133
+ "threat-hunting-soc-fr", "threat-hunting-soc-en",
134
+ "oauth-api-security-fr", "oauth-api-security-en"
135
+ ],
136
+ "Emerging Technologies": [
137
+ "post-quantum-crypto-fr", "post-quantum-crypto-en",
138
+ "llm-security-fr", "llm-security-en"
139
+ ],
140
+ "Supply Chain & SBOM": [
141
+ "sbom-compliance-fr", "sbom-compliance-en",
142
+ "supply-chain-attacks-fr", "supply-chain-attacks-en"
143
+ ],
144
+ "M365 & Microsoft Admin": [
145
+ "m365-admin-fr", "m365-admin-en", "m365-expert-v3-training"
146
+ ],
147
+ }
148
+
149
+ ARTICLES = [
150
+ {"title": "JavaScript-Code-Large - A 5M file JavaScript corpus for LLM pretraining", "slug": "551299945389829"},
151
+ {"title": "Casino Benchmark: Dataset + Space for evaluating LLM performance", "slug": "490691201493061"},
152
+ {"title": "Tiny Aya - Multilingual model release analysis", "slug": "682471247625526"},
153
+ {"title": "134,614 tok/sec input prefill max - Performance benchmarks", "slug": "139250541798125"},
154
+ {"title": "FEETECH STS3215 Stress-Test: Real backlash measurements", "slug": "621296339305286"},
155
+ {"title": "OpenClaw - Exploring new possibilities in robotics", "slug": "419291286474435"},
156
+ {"title": "GLiClass-Instruct: One Model to Classify, Verify, and Guard", "slug": "352121818088184"},
157
+ {"title": "AI Privacy Tool Validation Against World-Class Benchmarks", "slug": "749099860276897"},
158
+ {"title": "Spartacus-1B-Instruct: O(1) Inference Foundational Design", "slug": "866420978580038"},
159
+ {"title": "3B vs 120B: Open-Source LLMs Running Locally on Mac", "slug": "199749719779775"},
160
+ ]
161
+
162
+ # ============================================================
163
+ # CSS
164
+ # ============================================================
165
+
166
+ CUSTOM_CSS = """
167
+ /* Global dark cybersec theme */
168
+ :root {
169
+ --bg-primary: #0a0a0f;
170
+ --bg-secondary: #12121a;
171
+ --bg-card: #1a1a2e;
172
+ --bg-card-hover: #20203a;
173
+ --accent-red: #e63946;
174
+ --accent-purple: #9b59b6;
175
+ --accent-gradient: linear-gradient(135deg, #e63946 0%, #9b59b6 50%, #6c3483 100%);
176
+ --text-primary: #e8e8f0;
177
+ --text-secondary: #a0a0b8;
178
+ --text-muted: #6c6c88;
179
+ --border-color: #2a2a40;
180
+ --glow-red: 0 0 20px rgba(230,57,70,0.3);
181
+ --glow-purple: 0 0 20px rgba(155,89,182,0.3);
182
+ }
183
+
184
+ .gradio-container {
185
+ background: var(--bg-primary) !important;
186
+ max-width: 100% !important;
187
+ padding: 0 !important;
188
+ }
189
+
190
+ .tab-nav button {
191
+ color: var(--text-secondary) !important;
192
+ background: var(--bg-secondary) !important;
193
+ border: 1px solid var(--border-color) !important;
194
+ font-weight: 600 !important;
195
+ font-size: 0.95rem !important;
196
+ padding: 12px 24px !important;
197
+ border-radius: 8px 8px 0 0 !important;
198
+ transition: all 0.3s ease !important;
199
+ }
200
+
201
+ .tab-nav button:hover {
202
+ color: var(--accent-red) !important;
203
+ background: var(--bg-card) !important;
204
+ }
205
+
206
+ .tab-nav button.selected {
207
+ color: #fff !important;
208
+ background: var(--accent-gradient) !important;
209
+ border-color: var(--accent-red) !important;
210
+ }
211
+
212
+ footer { display: none !important; }
213
+ """
214
+
215
+ # ============================================================
216
+ # HTML SECTIONS
217
+ # ============================================================
218
+
219
+ def build_hero_html():
220
+ return """
221
+ <div style="
222
+ background: linear-gradient(135deg, #0a0a0f 0%, #1a0a1e 30%, #0f0a1a 60%, #1a0510 100%);
223
+ padding: 80px 20px 60px;
224
+ text-align: center;
225
+ position: relative;
226
+ overflow: hidden;
227
+ border-bottom: 2px solid #2a2a40;
228
+ ">
229
+ <!-- Animated background grid -->
230
+ <div style="
231
+ position: absolute; top: 0; left: 0; right: 0; bottom: 0;
232
+ background-image:
233
+ linear-gradient(rgba(230,57,70,0.05) 1px, transparent 1px),
234
+ linear-gradient(90deg, rgba(230,57,70,0.05) 1px, transparent 1px);
235
+ background-size: 50px 50px;
236
+ opacity: 0.5;
237
+ "></div>
238
+
239
+ <!-- Glow orbs -->
240
+ <div style="position:absolute;top:10%;left:15%;width:200px;height:200px;background:radial-gradient(circle,rgba(230,57,70,0.15),transparent 70%);border-radius:50%;filter:blur(40px);"></div>
241
+ <div style="position:absolute;bottom:10%;right:15%;width:250px;height:250px;background:radial-gradient(circle,rgba(155,89,182,0.15),transparent 70%);border-radius:50%;filter:blur(40px);"></div>
242
+
243
+ <div style="position: relative; z-index: 1;">
244
+ <!-- Shield icon -->
245
+ <div style="
246
+ width: 100px; height: 100px; margin: 0 auto 24px;
247
+ background: linear-gradient(135deg, #e63946, #9b59b6);
248
+ border-radius: 50%;
249
+ display: flex; align-items: center; justify-content: center;
250
+ box-shadow: 0 0 40px rgba(230,57,70,0.4), 0 0 80px rgba(155,89,182,0.2);
251
+ font-size: 48px; line-height: 1;
252
+ ">
253
+ <span style="filter: drop-shadow(0 0 10px rgba(255,255,255,0.5));">&#x1F6E1;</span>
254
+ </div>
255
+
256
+ <h1 style="
257
+ font-size: 3.2rem; font-weight: 800;
258
+ background: linear-gradient(135deg, #fff 0%, #e63946 50%, #9b59b6 100%);
259
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
260
+ background-clip: text;
261
+ margin: 0 0 12px; letter-spacing: -1px;
262
+ ">AYI NEDJIMI</h1>
263
+
264
+ <p style="
265
+ font-size: 1.35rem; color: #e63946; font-weight: 600;
266
+ margin: 0 0 16px; letter-spacing: 1px; text-transform: uppercase;
267
+ ">Senior Offensive Cybersecurity & AI Consultant</p>
268
+
269
+ <p style="
270
+ font-size: 1.05rem; color: #a0a0b8; max-width: 700px; margin: 0 auto 32px;
271
+ line-height: 1.6;
272
+ ">
273
+ Building the bridge between offensive cybersecurity and artificial intelligence.
274
+ Fine-tuned models, 85+ bilingual datasets, and 40 interactive tools for the security community.
275
+ </p>
276
+
277
+ <!-- CTA Buttons -->
278
+ <div style="display: flex; gap: 16px; justify-content: center; flex-wrap: wrap;">
279
+ <a href="https://www.ayinedjimi-consultants.fr" target="_blank" style="
280
+ padding: 12px 28px; border-radius: 8px;
281
+ background: linear-gradient(135deg, #e63946, #9b59b6);
282
+ color: #fff; text-decoration: none; font-weight: 700; font-size: 0.95rem;
283
+ box-shadow: 0 4px 20px rgba(230,57,70,0.4);
284
+ transition: transform 0.2s, box-shadow 0.2s;
285
+ ">Visit Website</a>
286
+ <a href="https://huggingface.co/collections/AYI-NEDJIMI/cybersec-ai-portfolio-datasets-models-and-spaces-699224074a478ec0feeac493" target="_blank" style="
287
+ padding: 12px 28px; border-radius: 8px;
288
+ border: 2px solid #e63946; background: transparent;
289
+ color: #e63946; text-decoration: none; font-weight: 700; font-size: 0.95rem;
290
+ transition: background 0.2s, color 0.2s;
291
+ ">View Full Collection</a>
292
+ <a href="https://www.linkedin.com/in/ayi-nedjimi" target="_blank" style="
293
+ padding: 12px 28px; border-radius: 8px;
294
+ border: 2px solid #9b59b6; background: transparent;
295
+ color: #9b59b6; text-decoration: none; font-weight: 700; font-size: 0.95rem;
296
+ ">LinkedIn</a>
297
+ </div>
298
+ </div>
299
+ </div>
300
+ """
301
+
302
+
303
+ def build_stats_html(stats):
304
+ cards = [
305
+ ("&#x1F916;", "Fine-tuned Models", str(stats.get("models", 4)), "Custom cybersecurity LLMs"),
306
+ ("&#x1F680;", "Interactive Spaces", str(stats.get("spaces", 40)), "Tools, demos & explorers"),
307
+ ("&#x1F4CA;", "Datasets Published", str(stats.get("datasets", 85)), "Bilingual FR/EN datasets"),
308
+ ("&#x2B07;", "Total Downloads", f"{stats.get('downloads', 0):,}", "Across all repositories"),
309
+ ("&#x2764;", "Total Likes", str(stats.get("likes", 0)), "Community engagement"),
310
+ ("&#x1F4DD;", "Articles Published", str(stats.get("articles", 10)), "Research & analysis posts"),
311
+ ]
312
+
313
+ cards_html = ""
314
+ for icon, label, value, sub in cards:
315
+ cards_html += f"""
316
+ <div style="
317
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
318
+ border: 1px solid #2a2a40; border-radius: 16px;
319
+ padding: 28px 20px; text-align: center;
320
+ min-width: 160px; flex: 1;
321
+ transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
322
+ position: relative; overflow: hidden;
323
+ " onmouseover="this.style.transform='translateY(-4px)';this.style.boxShadow='0 8px 30px rgba(230,57,70,0.2)';this.style.borderColor='#e63946'"
324
+ onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='none';this.style.borderColor='#2a2a40'">
325
+ <div style="position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#e63946,#9b59b6);"></div>
326
+ <div style="font-size: 2rem; margin-bottom: 8px;">{icon}</div>
327
+ <div style="font-size: 2rem; font-weight: 800; color: #fff; margin-bottom: 4px;
328
+ background: linear-gradient(135deg, #e63946, #9b59b6);
329
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
330
+ ">{value}</div>
331
+ <div style="font-size: 0.95rem; font-weight: 600; color: #e8e8f0; margin-bottom: 4px;">{label}</div>
332
+ <div style="font-size: 0.8rem; color: #6c6c88;">{sub}</div>
333
+ </div>
334
+ """
335
+
336
+ return f"""
337
+ <div style="padding: 40px 20px; background: #0a0a0f;">
338
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 8px;
339
+ background: linear-gradient(135deg, #e63946, #9b59b6);
340
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
341
+ ">Portfolio Statistics</h2>
342
+ <p style="text-align:center; color: #6c6c88; margin-bottom: 32px; font-size: 0.9rem;">
343
+ Live data from Hugging Face API
344
+ </p>
345
+ <div style="display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; max-width: 1100px; margin: 0 auto;">
346
+ {cards_html}
347
+ </div>
348
+ </div>
349
+ """
350
+
351
+
352
+ def build_models_html():
353
+ html = """
354
+ <div style="padding: 40px 20px; background: #0a0a0f;">
355
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 8px;
356
+ background: linear-gradient(135deg, #e63946, #9b59b6);
357
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
358
+ ">Fine-Tuned Models</h2>
359
+ <p style="text-align:center; color: #6c6c88; margin-bottom: 32px; font-size: 0.9rem;">
360
+ Custom cybersecurity & compliance LLMs trained with QLoRA
361
+ </p>
362
+ <div style="display: flex; flex-direction: column; gap: 20px; max-width: 900px; margin: 0 auto;">
363
+ """
364
+ for m in MODELS:
365
+ tags_html = "".join(
366
+ f'<span style="display:inline-block;padding:4px 10px;background:rgba(230,57,70,0.15);color:#e63946;border:1px solid rgba(230,57,70,0.3);border-radius:20px;font-size:0.75rem;font-weight:600;">{t}</span>'
367
+ for t in m["tags"]
368
+ )
369
+ html += f"""
370
+ <div style="
371
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
372
+ border: 1px solid #2a2a40; border-radius: 16px;
373
+ padding: 28px; position: relative; overflow: hidden;
374
+ transition: border-color 0.3s, box-shadow 0.3s;
375
+ " onmouseover="this.style.borderColor='#e63946';this.style.boxShadow='0 0 30px rgba(230,57,70,0.15)'"
376
+ onmouseout="this.style.borderColor='#2a2a40';this.style.boxShadow='none'">
377
+ <div style="position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#e63946,#9b59b6);"></div>
378
+
379
+ <div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:12px;">
380
+ <div>
381
+ <h3 style="margin:0 0 6px;font-size:1.3rem;font-weight:700;color:#fff;">
382
+ &#x1F916; {m['name']}
383
+ </h3>
384
+ <p style="margin:0 0 4px;font-size:0.85rem;color:#9b59b6;font-weight:600;">
385
+ Base: {m['base']} | {m['method']} | {m['lang']}
386
+ </p>
387
+ </div>
388
+ <a href="https://huggingface.co/{m['full']}" target="_blank" style="
389
+ padding: 8px 18px; border-radius: 8px;
390
+ background: linear-gradient(135deg, #e63946, #9b59b6);
391
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.85rem;
392
+ white-space: nowrap;
393
+ ">View Model &#x2192;</a>
394
+ </div>
395
+
396
+ <p style="margin:12px 0;color:#a0a0b8;font-size:0.9rem;line-height:1.6;">{m['desc']}</p>
397
+
398
+ <div style="display:flex;gap:6px;flex-wrap:wrap;margin-top:8px;">
399
+ {tags_html}
400
+ </div>
401
+ </div>
402
+ """
403
+ html += "</div></div>"
404
+ return html
405
+
406
+
407
+ def build_spaces_html():
408
+ html = """
409
+ <div style="padding: 40px 20px; background: #0a0a0f;">
410
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 8px;
411
+ background: linear-gradient(135deg, #e63946, #9b59b6);
412
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
413
+ ">Interactive Spaces</h2>
414
+ <p style="text-align:center; color: #6c6c88; margin-bottom: 32px; font-size: 0.9rem;">
415
+ 40 Gradio-powered tools, explorers, and demos
416
+ </p>
417
+ """
418
+ category_icons = {
419
+ "Security Explorers": "&#x1F50D;",
420
+ "Security Tools": "&#x1F6E0;",
421
+ "Compliance & GRC": "&#x2696;",
422
+ "AI / ML Tools": "&#x1F9E0;",
423
+ "Model Demos": "&#x1F3AE;",
424
+ }
425
+
426
+ for cat, spaces in SPACES_BY_CATEGORY.items():
427
+ icon = category_icons.get(cat, "&#x1F4E6;")
428
+ html += f"""
429
+ <div style="max-width: 1100px; margin: 0 auto 32px;">
430
+ <h3 style="color: #e63946; font-size: 1.15rem; font-weight: 700; margin-bottom: 16px; padding-left: 4px;
431
+ border-left: 3px solid #e63946; padding-left: 12px;">
432
+ {icon} {cat} <span style="color: #6c6c88; font-weight: 400; font-size: 0.85rem;">({len(spaces)} spaces)</span>
433
+ </h3>
434
+ <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px;">
435
+ """
436
+ for slug, name, desc in spaces:
437
+ html += f"""
438
+ <a href="https://huggingface.co/spaces/AYI-NEDJIMI/{slug}" target="_blank" style="
439
+ display: block; text-decoration: none;
440
+ background: linear-gradient(145deg, #1a1a2e, #1e1e32);
441
+ border: 1px solid #2a2a40; border-radius: 12px;
442
+ padding: 16px; transition: all 0.3s;
443
+ " onmouseover="this.style.borderColor='#9b59b6';this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 20px rgba(155,89,182,0.15)'"
444
+ onmouseout="this.style.borderColor='#2a2a40';this.style.transform='translateY(0)';this.style.boxShadow='none'">
445
+ <div style="font-size: 0.95rem; font-weight: 600; color: #e8e8f0; margin-bottom: 4px;">
446
+ {name}
447
+ </div>
448
+ <div style="font-size: 0.8rem; color: #6c6c88; line-height: 1.4;">
449
+ {desc}
450
+ </div>
451
+ </a>
452
+ """
453
+ html += "</div></div>"
454
+ html += "</div>"
455
+ return html
456
+
457
+
458
+ def build_datasets_html():
459
+ html = """
460
+ <div style="padding: 40px 20px; background: #0a0a0f;">
461
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 8px;
462
+ background: linear-gradient(135deg, #e63946, #9b59b6);
463
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
464
+ ">Cybersecurity Datasets</h2>
465
+ <p style="text-align:center; color: #6c6c88; margin-bottom: 32px; font-size: 0.9rem;">
466
+ 85 bilingual (FR/EN) datasets covering the full cybersecurity spectrum
467
+ </p>
468
+ <div style="max-width: 1000px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px;">
469
+ """
470
+ domain_icons = {
471
+ "Standards & Frameworks": "&#x1F3DB;",
472
+ "Offensive Security": "&#x2694;",
473
+ "EU Regulations & Compliance": "&#x1F1EA;&#x1F1FA;",
474
+ "Incident Response & DFIR": "&#x1F6A8;",
475
+ "Cloud & Infrastructure Security": "&#x2601;",
476
+ "SOC & Threat Intelligence": "&#x1F50E;",
477
+ "Emerging Technologies": "&#x1F52E;",
478
+ "Supply Chain & SBOM": "&#x1F517;",
479
+ "M365 & Microsoft Admin": "&#xF0;",
480
+ }
481
+ for domain, ds_list in DATASETS_BY_DOMAIN.items():
482
+ icon = domain_icons.get(domain, "&#x1F4C1;")
483
+ chips = ""
484
+ for ds in ds_list:
485
+ chips += f"""
486
+ <a href="https://huggingface.co/datasets/AYI-NEDJIMI/{ds}" target="_blank" style="
487
+ display: inline-block; padding: 5px 12px; margin: 3px;
488
+ background: rgba(155,89,182,0.1); border: 1px solid rgba(155,89,182,0.25);
489
+ border-radius: 20px; color: #9b59b6; text-decoration: none;
490
+ font-size: 0.8rem; font-weight: 500;
491
+ transition: background 0.2s, border-color 0.2s;
492
+ " onmouseover="this.style.background='rgba(155,89,182,0.25)';this.style.borderColor='#9b59b6'"
493
+ onmouseout="this.style.background='rgba(155,89,182,0.1)';this.style.borderColor='rgba(155,89,182,0.25)'">
494
+ {ds}
495
+ </a>"""
496
+
497
+ html += f"""
498
+ <div style="
499
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
500
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
501
+ ">
502
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
503
+ <h3 style="margin:0;color:#e8e8f0;font-size:1.05rem;font-weight:600;">
504
+ {icon} {domain}
505
+ </h3>
506
+ <span style="
507
+ padding: 4px 12px; border-radius: 20px;
508
+ background: rgba(230,57,70,0.15); color: #e63946;
509
+ font-size: 0.8rem; font-weight: 600;
510
+ ">{len(ds_list)} datasets</span>
511
+ </div>
512
+ <div style="display: flex; flex-wrap: wrap; gap: 2px;">
513
+ {chips}
514
+ </div>
515
+ </div>
516
+ """
517
+ html += "</div></div>"
518
+ return html
519
+
520
+
521
+ def build_articles_html():
522
+ html = """
523
+ <div style="padding: 40px 20px; background: #0a0a0f;">
524
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 8px;
525
+ background: linear-gradient(135deg, #e63946, #9b59b6);
526
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
527
+ ">Published Articles</h2>
528
+ <p style="text-align:center; color: #6c6c88; margin-bottom: 32px; font-size: 0.9rem;">
529
+ Research posts, analysis, and community contributions
530
+ </p>
531
+ <div style="max-width: 800px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px;">
532
+ """
533
+ for i, art in enumerate(ARTICLES, 1):
534
+ html += f"""
535
+ <a href="https://huggingface.co/posts/AYI-NEDJIMI/{art['slug']}" target="_blank" style="
536
+ display: flex; align-items: center; gap: 16px; text-decoration: none;
537
+ background: linear-gradient(145deg, #1a1a2e, #1e1e32);
538
+ border: 1px solid #2a2a40; border-radius: 10px;
539
+ padding: 16px 20px; transition: all 0.3s;
540
+ " onmouseover="this.style.borderColor='#e63946';this.style.transform='translateX(4px)'"
541
+ onmouseout="this.style.borderColor='#2a2a40';this.style.transform='translateX(0)'">
542
+ <div style="
543
+ min-width: 36px; height: 36px; border-radius: 8px;
544
+ background: linear-gradient(135deg, #e63946, #9b59b6);
545
+ display: flex; align-items: center; justify-content: center;
546
+ font-size: 0.85rem; font-weight: 700; color: #fff;
547
+ ">{i:02d}</div>
548
+ <div style="color: #e8e8f0; font-size: 0.92rem; font-weight: 500; line-height: 1.4;">
549
+ {art['title']}
550
+ </div>
551
+ </a>
552
+ """
553
+ html += """
554
+ </div>
555
+ <p style="text-align:center; margin-top: 20px;">
556
+ <a href="https://huggingface.co/AYI-NEDJIMI" target="_blank" style="
557
+ color: #9b59b6; text-decoration: none; font-weight: 600; font-size: 0.9rem;
558
+ ">View all posts on Hugging Face &#x2192;</a>
559
+ </p>
560
+ </div>
561
+ """
562
+ return html
563
+
564
+
565
+ def build_about_html():
566
+ return """
567
+ <div style="padding: 40px 20px; background: #0a0a0f;">
568
+ <h2 style="text-align:center; font-size: 1.8rem; font-weight: 700; margin-bottom: 32px;
569
+ background: linear-gradient(135deg, #e63946, #9b59b6);
570
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
571
+ ">About Me</h2>
572
+
573
+ <div style="max-width: 900px; margin: 0 auto; display: flex; flex-direction: column; gap: 24px;">
574
+
575
+ <!-- Bio -->
576
+ <div style="
577
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
578
+ border: 1px solid #2a2a40; border-radius: 16px; padding: 28px;
579
+ position: relative; overflow: hidden;
580
+ ">
581
+ <div style="position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#e63946,#9b59b6);"></div>
582
+ <h3 style="color: #e63946; margin: 0 0 16px; font-size: 1.15rem;">&#x1F464; Professional Profile</h3>
583
+ <p style="color: #a0a0b8; line-height: 1.7; margin: 0; font-size: 0.95rem;">
584
+ Senior Offensive Cybersecurity & AI Consultant with deep expertise in penetration testing,
585
+ red team operations, compliance frameworks, and applied artificial intelligence.
586
+ Specializing in bridging the gap between advanced cybersecurity practices and cutting-edge AI/ML
587
+ technologies to build smarter, automated security solutions.
588
+ </p>
589
+ <p style="color: #a0a0b8; line-height: 1.7; margin: 12px 0 0; font-size: 0.95rem;">
590
+ Creator of the largest bilingual (French/English) cybersecurity dataset collection on Hugging Face,
591
+ with 85+ datasets spanning MITRE ATT&CK, ISO 27001, OWASP, NIST CSF, EU regulations (NIS2, DORA, GDPR, AI Act),
592
+ incident response, forensics, cloud security, and more. Builder of 4 fine-tuned cybersecurity LLMs
593
+ and 40 interactive Gradio-powered security tools.
594
+ </p>
595
+ </div>
596
+
597
+ <!-- Expertise Grid -->
598
+ <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px;">
599
+ <div style="
600
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
601
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
602
+ ">
603
+ <h4 style="color: #e63946; margin: 0 0 12px; font-size: 1rem;">&#x2694; Offensive Security</h4>
604
+ <ul style="color: #a0a0b8; font-size: 0.85rem; line-height: 1.8; margin: 0; padding-left: 18px;">
605
+ <li>Penetration Testing (Web, Network, AD)</li>
606
+ <li>Red Team Operations</li>
607
+ <li>Active Directory Attacks</li>
608
+ <li>OWASP / MITRE ATT&CK</li>
609
+ <li>Bug Bounty Hunting</li>
610
+ <li>EDR Evasion & Bypass</li>
611
+ </ul>
612
+ </div>
613
+
614
+ <div style="
615
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
616
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
617
+ ">
618
+ <h4 style="color: #9b59b6; margin: 0 0 12px; font-size: 1rem;">&#x1F916; AI & Machine Learning</h4>
619
+ <ul style="color: #a0a0b8; font-size: 0.85rem; line-height: 1.8; margin: 0; padding-left: 18px;">
620
+ <li>LLM Fine-tuning (QLoRA, LoRA)</li>
621
+ <li>RAG Pipelines & LangChain</li>
622
+ <li>Prompt Engineering</li>
623
+ <li>MLOps & Model Deployment</li>
624
+ <li>AI Security (LLM Top 10)</li>
625
+ <li>Dataset Engineering</li>
626
+ </ul>
627
+ </div>
628
+
629
+ <div style="
630
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
631
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
632
+ ">
633
+ <h4 style="color: #e63946; margin: 0 0 12px; font-size: 1rem;">&#x1F4DC; Compliance & GRC</h4>
634
+ <ul style="color: #a0a0b8; font-size: 0.85rem; line-height: 1.8; margin: 0; padding-left: 18px;">
635
+ <li>ISO 27001 / 27002</li>
636
+ <li>GDPR / RGPD</li>
637
+ <li>NIS2 Directive</li>
638
+ <li>DORA Regulation</li>
639
+ <li>EU AI Act</li>
640
+ <li>NIST CSF / CIS Controls</li>
641
+ </ul>
642
+ </div>
643
+ </div>
644
+
645
+ <!-- Certifications -->
646
+ <div style="
647
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
648
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
649
+ ">
650
+ <h4 style="color: #e63946; margin: 0 0 12px; font-size: 1rem;">&#x1F3C6; Key Competencies & Frameworks</h4>
651
+ <div style="display: flex; flex-wrap: wrap; gap: 8px;">
652
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">MITRE ATT&CK</span>
653
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">OWASP Top 10</span>
654
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">ISO 27001</span>
655
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">NIST CSF</span>
656
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">Active Directory</span>
657
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">GDPR/RGPD</span>
658
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">NIS2</span>
659
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">DORA</span>
660
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">AI Act</span>
661
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">Kubernetes Security</span>
662
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">Cloud Security (AWS/Azure/GCP)</span>
663
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">Microsoft 365</span>
664
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">DevSecOps</span>
665
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">QLoRA / LoRA Fine-tuning</span>
666
+ <span style="padding:6px 14px;background:rgba(230,57,70,0.12);border:1px solid rgba(230,57,70,0.3);border-radius:20px;color:#e63946;font-size:0.82rem;font-weight:600;">RAG / LangChain</span>
667
+ <span style="padding:6px 14px;background:rgba(155,89,182,0.12);border:1px solid rgba(155,89,182,0.3);border-radius:20px;color:#9b59b6;font-size:0.82rem;font-weight:600;">Post-Quantum Crypto</span>
668
+ </div>
669
+ </div>
670
+
671
+ <!-- Links -->
672
+ <div style="
673
+ background: linear-gradient(145deg, #1a1a2e, #20203a);
674
+ border: 1px solid #2a2a40; border-radius: 12px; padding: 20px;
675
+ ">
676
+ <h4 style="color: #9b59b6; margin: 0 0 16px; font-size: 1rem;">&#x1F310; Connect & Follow</h4>
677
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;">
678
+ <a href="https://www.ayinedjimi-consultants.fr" target="_blank" style="
679
+ padding: 10px 24px; border-radius: 8px;
680
+ background: linear-gradient(135deg, #e63946, #c0392b);
681
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
682
+ ">&#x1F310; Website</a>
683
+ <a href="https://www.linkedin.com/in/ayi-nedjimi" target="_blank" style="
684
+ padding: 10px 24px; border-radius: 8px;
685
+ background: linear-gradient(135deg, #0077b5, #005885);
686
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
687
+ ">&#x1F4BC; LinkedIn</a>
688
+ <a href="https://github.com/ayinedjimi" target="_blank" style="
689
+ padding: 10px 24px; border-radius: 8px;
690
+ background: linear-gradient(135deg, #333, #24292e);
691
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
692
+ ">&#x1F4BB; GitHub</a>
693
+ <a href="https://x.com/AyiNEDJIMI" target="_blank" style="
694
+ padding: 10px 24px; border-radius: 8px;
695
+ background: linear-gradient(135deg, #1da1f2, #0d8bd9);
696
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
697
+ ">&#x1F426; Twitter / X</a>
698
+ <a href="https://huggingface.co/AYI-NEDJIMI" target="_blank" style="
699
+ padding: 10px 24px; border-radius: 8px;
700
+ background: linear-gradient(135deg, #ff9d00, #e68a00);
701
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
702
+ ">&#x1F917; Hugging Face</a>
703
+ <a href="https://huggingface.co/collections/AYI-NEDJIMI/cybersec-ai-portfolio-datasets-models-and-spaces-699224074a478ec0feeac493" target="_blank" style="
704
+ padding: 10px 24px; border-radius: 8px;
705
+ background: linear-gradient(135deg, #9b59b6, #6c3483);
706
+ color: #fff; text-decoration: none; font-weight: 600; font-size: 0.9rem;
707
+ ">&#x1F4E6; Full Collection</a>
708
+ </div>
709
+ </div>
710
+ </div>
711
+
712
+ <!-- Footer -->
713
+ <div style="text-align: center; padding: 40px 20px 20px; color: #6c6c88; font-size: 0.8rem;">
714
+ <p style="margin: 0;">AYI NEDJIMI &middot; Senior Offensive Cybersecurity & AI Consultant</p>
715
+ <p style="margin: 4px 0 0; color: #4a4a60;">Built with Gradio on Hugging Face Spaces</p>
716
+ </div>
717
+ </div>
718
+ """
719
+
720
+
721
+ # ============================================================
722
+ # FETCH LIVE STATS
723
+ # ============================================================
724
+
725
+ def fetch_stats():
726
+ """Fetch live statistics from Hugging Face API."""
727
+ stats = {
728
+ "models": 4,
729
+ "spaces": 40,
730
+ "datasets": 85,
731
+ "downloads": 0,
732
+ "likes": 0,
733
+ "articles": 10,
734
+ }
735
+
736
+ try:
737
+ headers = {"Accept": "application/json"}
738
+
739
+ # Fetch models
740
+ resp = requests.get(
741
+ "https://huggingface.co/api/models",
742
+ params={"author": "AYI-NEDJIMI", "limit": 100},
743
+ headers=headers,
744
+ timeout=10,
745
+ )
746
+ if resp.status_code == 200:
747
+ models = resp.json()
748
+ stats["models"] = len(models)
749
+ for m in models:
750
+ stats["downloads"] += m.get("downloads", 0)
751
+ stats["likes"] += m.get("likes", 0)
752
+
753
+ # Fetch datasets
754
+ resp = requests.get(
755
+ "https://huggingface.co/api/datasets",
756
+ params={"author": "AYI-NEDJIMI", "limit": 200},
757
+ headers=headers,
758
+ timeout=10,
759
+ )
760
+ if resp.status_code == 200:
761
+ datasets = resp.json()
762
+ stats["datasets"] = len(datasets)
763
+ for d in datasets:
764
+ stats["downloads"] += d.get("downloads", 0)
765
+ stats["likes"] += d.get("likes", 0)
766
+
767
+ # Fetch spaces
768
+ resp = requests.get(
769
+ "https://huggingface.co/api/spaces",
770
+ params={"author": "AYI-NEDJIMI", "limit": 200},
771
+ headers=headers,
772
+ timeout=10,
773
+ )
774
+ if resp.status_code == 200:
775
+ spaces = resp.json()
776
+ stats["spaces"] = len(spaces)
777
+ for s in spaces:
778
+ stats["likes"] += s.get("likes", 0)
779
+
780
+ except Exception as e:
781
+ print(f"Stats fetch error: {e}")
782
+
783
+ return stats
784
+
785
+
786
+ # ============================================================
787
+ # BUILD APP
788
+ # ============================================================
789
+
790
+ def create_app():
791
+ stats = fetch_stats()
792
+
793
+ with gr.Blocks(
794
+ title="AYI NEDJIMI - CyberSec & AI Portfolio",
795
+ css=CUSTOM_CSS,
796
+ theme=gr.themes.Base(
797
+ primary_hue=gr.themes.colors.red,
798
+ secondary_hue=gr.themes.colors.purple,
799
+ neutral_hue=gr.themes.colors.gray,
800
+ font=gr.themes.GoogleFont("Inter"),
801
+ ),
802
+ ) as app:
803
+
804
+ # Hero
805
+ gr.HTML(build_hero_html())
806
+
807
+ # Stats
808
+ gr.HTML(build_stats_html(stats))
809
+
810
+ # Tabbed sections
811
+ with gr.Tabs():
812
+ with gr.TabItem("Models"):
813
+ gr.HTML(build_models_html())
814
+
815
+ with gr.TabItem("Spaces"):
816
+ gr.HTML(build_spaces_html())
817
+
818
+ with gr.TabItem("Datasets"):
819
+ gr.HTML(build_datasets_html())
820
+
821
+ with gr.TabItem("Articles"):
822
+ gr.HTML(build_articles_html())
823
+
824
+ with gr.TabItem("About"):
825
+ gr.HTML(build_about_html())
826
+
827
+ return app
828
+
829
+
830
+ app = create_app()
831
+
832
+ if __name__ == "__main__":
833
+ app.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio>=4.0.0
2
+ requests