Files
teknav-bak/app/Frontend-6226.md
arsam e9cd12dda6 Import remaining project documentation and reference notes
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:33:04 +03:30

5162 lines
217 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Teknav Frontend Design System — Complete Reference (v6226)
> **Disclaimer**: This document is a complete design reference for the Teknav frontend (a Persian RTL React SPA at teknav.ir). Every color, spacing, typography, component state, animation, responsive breakpoint, and layout pattern is documented below. After reading this document, the reader should be able to reconstruct the entire UI verbatim without ever seeing the live site.
---
## 1. IDENTITY & BRAND
### 1.1 Brand Overview
- **Name (Persian)**: تکناو (Teknav)
- **Tagline (Persian)**: روایت عمیق فناوری / تحلیل فناوری، هوش مصنوعی و امنیت سایبری
- **Tagline (English)**: Deep technology narrative
- **English Sub-brand**: TEKNAV (all-caps, letter-spacing 0.15em–0.32em)
- **Domain**: teknav.ir
- **Language**: fa-IR (Persian), RTL; secondary LTR for TekRAG English article
- **Category**: Technology analysis media — AI, data science, cybersecurity, software, hardware, startups, future tech
- **Year Established**: Static copyright reads "۱۴۰۵" (2026)
### 1.2 Brand Voice
- Authoritative, data-driven, academic yet accessible
- Persian-first RTL, technical Persian terminology
- Uses formal Persian greetings ("صبح بخیر", "شب بخیر") with time-based greeting on login
- "Learner" tone — content is deep analysis, not breaking news
### 1.3 Logo & Wordmark
**Header Logo:**
- Wordmark "تکناو" in Vazirmatn 900 weight, 22px font size, color #0F6B73
- Sub-label "TEKNAV" below in sans-serif 9px, letter-spacing 0.15em, color #5F6B6D
- Clickable (navigates to /)
- Hamburger menu icon on mobile (3 horizontal lines, SVG 20x20, stroke #263238, strokeWidth 2)
**Footer Logo:**
- "تکناو" in PelakFA 900, 28px, color #0F2A2E
- "TEKNAV" below in 11px, letter-spacing 0.18em, color #C46A4D, weight 700
**Auth Page Logo (Brand Panel):**
- Gold gradient square (26px radius) with "ت" character in center on dark background
- Dashed and solid orbiting rings around logo with animation
- Gradient: linear-gradient(145deg, #C8951C 0%, #F4C36A 50%, #C8951C 100%)
- Character: color #0B2226, font-size 44px, weight 900
**Auth Page Mobile Logo:**
- Same gold gradient square 44x44px, boxShadow '0 4px 14px rgba(200,149,28,0.3)'
- "ت" character at 21px, #0F2A2E
- Wordmark "تکناو" at 24px, PelakFA, #0F2A2E
**Favicon:**
- /favicon.ico (ICO format)
- /favicon.png 512x512 (PNG, apple-touch-icon and PWA)
---
## 2. COLOR SYSTEM
### 2.1 Primary Palette
| Token | Hex | Usage | Shade Name |
|---|---|---|---|
| `--tek-teal` | `#0F6B73` | Primary brand, links, buttons, active states, header logo, borders | Deep Teal |
| `--tek-teal-dark` | `#0F2A2E` | Headings, premium banners, dark brand text | Dark Teal |
| `--tek-teal-light` | `#0F6B7318` | Background tints (18% opacity) | Light Teal Tint |
| `--tek-terracotta` | `#C46A4D` | Login button, stats accent, profile primary | Terracotta |
| `--tek-terracotta-light` | `#C46A4D18` | Background tints | Light Terracotta |
| `--tek-gold` | `#D49A2A` | Shimmer text, badges, premium, brand panel | Gold |
| `--tek-gold-light` | `#D49A2A0A` | Blockquote backgrounds, tints | Light Gold |
| `--tek-gold-dark` | `#A8761B` | Gold gradient endpoints | Dark Gold |
| `--tek-green` | `#2F8F6B` | Success, published status, positive metrics | Warm Green |
| `--tek-green-light` | `#E8F4EF` | Profile expertise tags, follow states | Light Green |
| `--tek-cream` | `#FAF7F0` | Page body background, splash bg | Cream |
| `--tek-cream-dark` | `#F4EFE6` | Panels, secondary backgrounds, hover states | Dark Cream |
| `--tek-sand` | `#ebe3d2` | Footer background, stats bar, newsletter box | Sand |
| `--tek-line` | `#E4DDD2` | Borders, dividers, scrollbar thumb | Border Line |
| `--tek-ink` | `#263238` | Body text, headings primary | Ink |
| `--tek-muted` | `#5F6B6D` | Secondary text, metadata | Muted |
| `--tek-muted-light` | `#9AA5A6` | Tertiary text, hints, placeholders in auth | Muted Light |
| `--tek-white` | `#fff` | Card backgrounds, code blocks, contrast surfaces | White |
| `--tek-red` | `#C94C4C` | Error, danger, breaking news badge, delete | Red |
| `--tek-red-light` | `#C94C4D0A` | Error backgrounds, security alerts | Light Red |
### 2.2 Article Type Color Map (Badges)
| Type | Background | Text |
|---|---|---|
| تحلیل عمیق (Deep Analysis) | `#0F6B73` | `#fff` |
| راهنمای فنی (Technical Guide) | `#D49A2A` | `#fff` |
| داده‌نما (Data Visualization) | `#C76D4A` | `#fff` |
| پژوهش (Research) | `#2F8F6B` | `#fff` |
| راستی‌آزمایی‌شده (Fact-checked) | `#263238` | `#fff` |
| خبر فوری (Breaking News) | `#C94C4C` | `#fff` |
| خبر تحلیلی (Analytical News) | `#5F6B6D` | `#fff` |
| پرونده (Dossier) | `#20343A` | `#FAF7F0` |
| default | `#E4DDD2` | `#263238` |
### 2.3 Status Color Map
| Status | Color |
|---|---|
| منتشرشده (Published) | `#2F8F6B` |
| پیش‌نویس (Draft) | `#5F6B6D` |
| در انتظار بررسی (Pending Review) | `#D49A2A` |
| نیازمند اصلاح (Needs Revision) | `#C94C4C` |
| زمان‌بندی‌شده (Scheduled) | `#0F6B73` |
### 2.4 Role Color Map
| Role | Color | Persian Label |
|---|---|---|
| admin | `#C76D4A` | مدیر کل |
| editor | `#0F6B73` | سردبیر |
| writer | `#D49A2A` | نویسنده |
| reviewer | `#2F8F6B` | بازبین |
| reader | `#5F6B6D` | خواننده |
### 2.5 Profile Page Color Palette (Terracotta-oriented)
The profile page (`teknav-profile.jsx`) uses its own color system separate from main site teal:
| Token | Hex | Usage |
|---|---|---|
| terracotta | `#C45C3D` | Primary action color (buttons, links, accent bars) |
| orange | `#E07A3A` | Secondary accent (counters, analytics) |
| green | `#3A7D5E` | Success states, expertise tags, toggle on |
| greenLight | `#E8F4EF` | Background for green-tagged elements |
| ink | `#263238` | Headings, body text |
| muted | `#5F6B6D` | Secondary text, metadata |
| cream | `#FAF7F0` | Page background |
| panel | `#F4EFE6` | Card/panel background |
| line | `#E4DDD2` | Borders |
| white | `#fff` | Card surfaces |
### 2.6 Category Colors
| Category slug | Color | Usage |
|---|---|---|
| ai | `#0F6B73` | Teal — AI / هوش مصنوعی |
| data | `#2F8F6B` | Green — Data Science / علم داده |
| security | `#C62828` | Red — Security / امنیت سایبری |
| software | `#1565C0` | Blue — Software / نرم‌افزار |
| hardware | `#6A1B9A` | Purple — Hardware / سخت‌افزار |
| startup | `#C76D4A` | Terracotta — Startup / استارتاپ |
| future | `#D49A2A` | Gold — Future Tech / آینده فناوری |
Category badges use the color at 18% opacity for background (via `color + '18'` CSS) and the full color for text, with a 30% opacity border.
### 2.7 Gradient Definitions
- **Hero background glows**: `radial-gradient(circle, rgba(15,107,115,0.10) 0%, transparent 70%)` and `radial-gradient(circle, rgba(196,106,77,0.10) 0%, transparent 70%)`
- **Gold shimmer text**: `linear-gradient(90deg, #A8761B 0%, #D49A2A 30%, #F4C36A 50%, #D49A2A 70%, #A8761B 100%)`
- **Footer accent bar**: `linear-gradient(90deg, transparent 0%, #0F6B73 25%, #D49A2A 50%, #C46A4D 75%, transparent 100%)`
- **Streak widget**: `linear-gradient(135deg, #FF9D6C 0%, #C46A4D 100%)`
- **Premium gate**: `linear-gradient(135deg, #0F2A2E 0%, #1A3A40 100%)`
- **Gold button (auth)**: `linear-gradient(135deg, #C8951C 0%, #D49A2A 60%, #C8951C 100%)`
- **Profile banner**: `linear-gradient(145deg, #FDF6EE 0%, #F7EDE0 55%, #EEF5F0 100%)`
- **Verdict section (comparison)**: `#0F3540` (solid dark teal background)
- **Newsletter box**: `#ebe3d2` solid with radial gradient decorative circles
- **Category page**: `linear-gradient(135deg, ${cat.color}18 0%, #F4EFE6 100%)`
- **CVE summary card**: `linear-gradient(135deg, #EEF6F7 0%, #E8F3F4 100%)`
- **Article diagram card**: `linear-gradient(135deg, #F4EFE6 0%, #FFFFFF 100%)`
- **TekRAG diagram card**: `#FAFAFA` solid with `#E8E8E8` border
- **Gold logo glow (auth)**: logoGlow animation shadow `0 10px 36px rgba(200,149,28,0.35)` -> `0 10px 56px rgba(200,149,28,0.6)`
---
## 3. TYPOGRAPHY
### 3.1 Font Families
**Primary (Body) — Vazirmatn:**
- Font family: `'Vazirmatn', system-ui, sans-serif`
- 6 weights loaded (all TrueType): 400 (Regular), 500 (Medium), 600 (SemiBold), 700 (Bold), 800 (ExtraBold), 900 (Black)
- Source: `/fonts/Vazirmatn-{weight}.ttf` (self-hosted, zero CDN)
- `font-display: swap`
**Display (Headlines) — PelakFA:**
- Font family: `'PelakFA', 'Vazirmatn', sans-serif`
- 2 weights loaded (WOFF): 700 (Bold), 800 (ExtraBold)
- Source: `/fonts/PelakFA-{weight}.woff` (self-hosted, zero CDN)
- Used for: hero headlines, auth brand wordmark, footer headings, section titles, stats numbers
**TekRAG Article — Inter/Arial:**
- English article pages use `'Inter', Arial, sans-serif`
- Fallback for code blocks: `'Courier New', Consolas, monospace`
- LTR direction
### 3.2 Font Sizes & Line Heights
**Body Scale:**
- Article content body: 16px, line-height 2.0
- Body paragraph (general): 14px–16px
- Small/secondary: 13px, line-height 1.7–1.9
- X-small/metadata: 12px, line-height 1.7
- Tiny/labels: 11px
- Micro/badges: 10px–11px
**Heading Scale:**
- Hero H1 (homepage): `clamp(34px, 5.4vw, 58px)`, line-height 1.25, PelakFA 800
- Article H1: `clamp(22px, 4vw, 34px)`, line-height 1.4, Vazirmatn 900
- Section H2 (homepage): 22px, Vazirmatn 800
- Article H2: 22px, Vazirmatn 800
- Article H3: 18px, Vazirmatn 700
- Category page H1: `clamp(28px, 5vw, 42px)`, Vazirmatn 900
- Featured headline: 18px (homepage sidebar card), PelakFA 700
- Article header subtitle: 18px, color #5F6B6D, weight 400
**Article Content Typography:**
- Lead paragraph: 18px, line-height 2.05, color #1A3035, weight 500
- Body: 16px, line-height 2.0, color #263238
- Blockquote: 16px, line-height 2.0, color #263238
- Code inline: 13px (code:not(pre code))
- Code block: 13.5px, line-height 1.85, monospace
### 3.3 Font Weights Usage
| Weight | CSS Variable | Usage |
|---|---|---|
| 400 (Regular) | `font-weight: 400` | Body text, paragraphs, meta |
| 500 (Medium) | `font-weight: 500` | Lead paragraphs, some labels |
| 600 (SemiBold) | `font-weight: 600` | Buttons, category badges, active filters |
| 700 (Bold) | `font-weight: 700` | H3, subheadings, type badges, filter chips |
| 800 (ExtraBold) | `font-weight: 800` | H1, H2, section titles, stat values, article titles |
| 900 (Black) | `font-weight: 900` | Hero headlines, prominent numbers, stat counters |
### 3.4 CSS Class-Based Typography
| Class | Properties |
|---|---|
| `.lead` | 18px, line-height 2.05, #1A3035, weight 500, white bg, 1px #E4DDD2 border, 4px #0F6B73 right border, 12px radius, 20px 22px padding |
| `.gold-shimmer` | Animated gold gradient text via background-clip |
| `.ltr` | direction: ltr, unicode-bidi: isolate, display inline-block, font-family Inter/Arial |
---
## 4. SPACING & LAYOUT
### 4.1 Page Structure
- **Page max-width**: 1280px (centered with `margin: 0 auto`)
- **Article max-width content**: 760px (Persian), 860px (TekRAG English)
- **Header height**: 64px (desktop), 56px (mobile <560px)
- **Header padding**: 0 24px (desktop), 0 14px (mobile)
- **Footer padding**: 56px 24px 28px, margin-top 80px
- **Page padding-top**: 64px (to offset fixed header)
- **Article list page padding-top**: 80px
- **Auth page**: split-panel, no header/footer
### 4.2 Grid Systems
**Homepage grids:**
- Article cards: `repeat(auto-fill, minmax(280px, 1fr))`, gap 20px
- Featured article: `1fr 1fr` (two-column), min-height 280px
- Authors: `repeat(auto-fill, minmax(200px, 1fr))`, gap 16px
- Categories: `repeat(auto-fill, minmax(200px, 1fr))`, gap 12px
- Stats bar: `repeat(auto-fit, minmax(180px, 1fr))`, gap 16px
- Newsletter box: single column centered, max-width 520px for text
**Article list grids:**
- Article rows: `1fr 140px` (text column + thumbnail column), gap 24px
- Related articles: `repeat(auto-fill, minmax(220px, 1fr))`, gap 16px
**Article detail grids:**
- Layout: `200px 1fr` (TOC sidebar + article content), gap 48px
- Author box: flex row with gap 16px
- Series nav banner: flex space-between, gap 12px
**Search layout:**
- Two-column: `240px 1fr`, gap 32px (filters sidebar + results)
**Category page:**
- Hero: `1fr 320px`, gap 40px (text + diagram)
**Profile page:**
- Own profile grid: `1fr 1fr`, gap 16px (reading history + followed writers)
- Analytics cards: `repeat(3, 1fr)`, gap 14px
- Badges: horizontal flex wrap, gap 10px
**Comparison page:**
- Cards: flex `1 1 300px`, gap 20px
- Use cases: flex `1 1 280px`, gap 20px
**Directory page:**
- Companies: `repeat(auto-fill, minmax(280px, 1fr))`, gap 16px
**Stories list page:**
- Grid: `repeat(auto-fill, minmax(160px, 1fr))`, gap 14px
- Aspect ratio: padding-bottom 177% (portrait phone ratio)
**Footer grid:**
- `repeat(auto-fit, minmax(200px, 1fr))`, gap 40px (5 sections)
### 4.3 Border Radii
| Radius | Usage |
|---|---|
| 3px | Type badges (small), role badges |
| 4px | Category badges, inline code blocks, tag pills |
| 6px | Skill tags, progress bars, skeleton loaders, small buttons |
| 8px | Buttons (pillBtn), inputs, cards, thumbnails, icons, search bar |
| 10px | Article hero diagram, notification dropdown, comment cards, filter chips, search results |
| 12px | Article cards, featured card, category cards, profile cards, modals, auth form sections, sendBeacon sections |
| 14px | Stories cards |
| 16px | Featured article (homepage hero), newsletter box, comparison verdict, premium gate, company profile header, reading list modal |
| 18px | Forgot password modal |
| 20px | Newsletter box, some containers |
| 999px | Pill badges, verified expert badges, status badges with dot |
### 4.4 Shadows
| Shadow | Usage |
|---|---|
| `0 2px 12px rgba(0,0,0,0.04)` | Default article card |
| `0 8px 32px rgba(0,0,0,0.1)` | Article card hover |
| `0 4px 24px rgba(0,0,0,0.06)` | Featured article default |
| `0 12px 48px rgba(0,0,0,0.12)` | Featured article hover |
| `0 14px 40px rgba(15,42,46,0.08)` | Hero sidebar featured card |
| `0 6px 22px rgba(15,107,115,0.28)` | Hero CTA button |
| `0 10px 28px rgba(15,107,115,0.35)` | Hero CTA button hover |
| `0 4px 20px rgba(0,0,0,0.06)` | Category hero diagram card |
| `0 4px 20px rgba(196,92,61,0.15)` | Profile avatar |
| `0 20px 60px rgba(0,0,0,0.2)` | Confirm modal |
| `0 24px 64px rgba(0,0,0,0.22)` | Profile settings modal |
| `0 32px 80px rgba(0,0,0,0.24)` | Forgot password modal |
| `0 4px 16px rgba(200,149,28,0.22)` | Auth gold button |
| `0 12px 40px rgba(0,0,0,0.22)` | Push notification prompt |
| `0 4px 16px rgba(0,0,0,0.4)` | Quote sharer tooltip |
| `0 16px 44px rgba(0,0,0,0.14)` | Notification dropdown |
| `0 12px 34px rgba(15,42,46,0.06)` | Article diagram card |
| `0 4px 15px rgba(196,106,77,0.3)` | Streak widget |
| `-4px 0 24px rgba(0,0,0,0.12)` | Mobile drawer |
| `0 1px 4px rgba(0,0,0,0.05)` | Badge pills |
| `0 8px 24px rgba(0,0,0,0.08)` | Author card hover |
| `0 4px 16px rgba(0,0,0,0.09)` | Comparison card hover |
| `0 8px 24px rgba(0,0,0,0.07)` | Article mini-card hover (profile) |
| `0 4px 14px rgba(200,149,28,0.3)` | Auth mobile logo |
### 4.5 Gap / Padding Scale
| Value | Common Usage |
|---|---|
| 4px | Very tight spacing (verified badge inner) |
| 6px | Badge wrapping, tight element groups |
| 8px | Button icon spacing, filter chip gaps, tight sections |
| 10px | Toast gaps, icon-text spacing |
| 12px | Element clusters, tag wrapping, breadcrumb gaps |
| 14px | Input padding, button padding (auth) |
| 16px | General card padding, section spacing, grid gaps |
| 18px | Code block padding, some card padding |
| 20px | Card padding, grid gaps, section padding |
| 24px | Page padding, card padding, section margins |
| 28px | Toast bottom position, large margins |
| 32px | Page sections, padding, gaps |
| 40px | Section spacing, hero padding |
| 44px | Auth form padding (mobile) |
| 48px | Section spacing, auth padding desktop |
| 52px | Profile hero padding |
| 56px | Footer padding top |
| 60px | Empty state padding |
| 64px | Header offset |
---
## 5. COMPONENT DESIGN SYSTEM
### 5.1 Header
**Structure:**
- Fixed position, top:0, right:0, left:0, z-index:100
- Background: `rgba(250,247,240,0.95)` (scrolled) or `rgba(250,247,240,0.85)` (default), backdrop-filter blur(12px)
- Border-bottom: 1px solid #E4DDD2 (scrolled) or transparent (default)
- Height: 64px (desktop), 56px (<560px)
- Inner max-width: 1280px, margin auto, padding 0 24px
- Flex layout: logo | nav | actions
**Navigation Items (desktop):**
1. خانه (/) — Home
2. هوش مصنوعی (/category/ai) — AI
3. علم داده (/category/data) — Data Science
4. استارتاپ (/category/startup) — Startup
5. امنیت (/category/security) — Security
6. سخت‌افزار (/category/hardware) — Hardware
7. نرم‌افزار (/category/software) — Software
8. آینده فناوری (/category/future) — Future Tech
9. نویسندگان (/authors) — Authors
**Nav Item States:**
- Default: font-size 13px, color #263238, weight 400
- Active (current page): color #0F6B73, weight 700, border-bottom 2px solid #0F6B73
- Hover: no explicit hover (transition on all 0.15s)
**Action Buttons (right side):**
- Search icon: SVG circle + path magnifying glass, 18x18px, stroke #263238, strokeWidth 2
- Notification bell: SVG bell icon, 18x18px, with badge counter (red #C94C4C circle, 17px min-width, 9px radius, white text)
- Admin button: pillBtn, background #0F6B73, color #fff
- Profile button: pillBtn, background #F4EFE6, color #263238, shows @username
- Logout button: pillBtn, background #F4EFE6, color #263238
- Login button: pillBtn, background #C46A4D, color #fff, text "ورود / ثبت‌نام"
**Search Bar (expandable):**
- Toggled by search icon button
- Full-width strip below header, borderTop 1px solid #E4DDD2, background #FAF7F0, padding 12px 24px
- Form max-width 600px, centered, flex gap 8px
- Input: inputStyle, placeholder "جستجو در مقاله‌ها، نویسندگان و دسته‌بندی‌ها..."
- Submit button: pillBtn, background #0F6B73, color #fff, text "جستجو"
### 5.2 Mobile Drawer
- Trigger: hamburger button (display:none on desktop, flex on <768px)
- Overlay: fixed inset 0, background rgba(0,0,0,0.4)
- Panel: absolute, top 0, right 0, width 280px (or min(84vw, 300px) on mobile), height 100%, background #FAF7F0, padding 24px, boxShadow '-4px 0 24px rgba(0,0,0,0.12)'
- Close button: top-right, "✕"
- Nav items: block, width 100%, text-align right, padding 12px 0, font-size 15px, borderBottom 1px solid #E4DDD2, active color #0F6B73
- Auth section: follows same pattern as desktop action buttons but stacked vertically
### 5.3 Footer
- Background: #ebe3d2, color #4A5A5C
- Decorative top accent bar: 3px height, gradient across full width
- 5-column grid: About, Categories, Tools, Links, Contact
- About section: "تکناو" headline 28px PelakFA 900, #0F2A2E; "TEKNAV" sub-label 11px, #C46A4D; description paragraph 13px, line-height 1.9
- Link sections (Categories, Tools, Links): 14px headings in PelakFA, #0F2A2E; link items 13px, #5F6B6D with hover effect (color #0F6B73 + translateX(-4px) with transition)
- Social buttons: background rgba(15,107,115,0.08), border 1px rgba(15,107,115,0.25), color #0F6B73, padding 7px 14px, radius 8px, 12px font weight 600; hover: fill #0F6B73, text white, translateY(-2px)
- Support badges: "🌊 حامی خلیج فارس" and "🌐 حامی اینترنت آزاد برای عموم" — amber background, dark text
- Bottom bar: copyright "© ۱۴۰۵ تکناو — تمام حقوق محفوظ است" + "Designed By Coaxys" with #0F6B73 accent
### 5.4 Article Card (Grid — Homepage & Related)
**Structure:** White card, 12px radius, 1px #E4DDD2 border, 24px padding, cursor pointer
- `opacity: 0` -> 1 with `translateY(24px)` -> 0 on intersection (staggered delay)
- Hover: boxShadow 0 8px 32px rgba(0,0,0,0.1)
**Sections (top to bottom):**
1. **Diagram thumbnail**: 120px height, #F4EFE6 background, 8px radius, centered DiagramRenderer scaled to 0.7
- Continue-reading overlay: bottom progress bar (4px, #0F6B73) + badge ("ادامه مطالعه" in #0F6B73 bg, white text, 10px)
2. **Badge row**: TypeBadge + CategoryBadge (+ optional "Promoted Content" amber or "Premium" dark badge), flex wrap gap 6px
3. **Title**: 15px, weight 700, color #263238, line-height 1.5
4. **Summary**: 12px, color #5F6B6D, line-height 1.7, truncated to 100 chars
5. **Meta row**: flex space-between, 11px, color #5F6B6D
- Left: date
- Right: AuthorAvatar (22px) + read time + bookmark button
### 5.5 Featured Article (Homepage Hero)
- Two-column grid: `1fr 1fr`, min-height 280px
- Left column: padding 32px (right side padding 24px)
- Badge row: TypeBadge + CategoryBadge
- Title: 22px, weight 800, #263238, line-height 1.5, Vazirmatn
- Summary: 14px, #5F6B6D, line-height 1.8
- Author line: borderTop 1px solid #E4DDD2, avatar 36px + name + date/read time
- Right column: #F4EFE6 background, DiagramRenderer centered
- Hover: boxShadow 0 12px 48px rgba(0,0,0,0.12)
### 5.6 Article Row (List — Article List Page)
- Grid: `1fr 140px`, gap 24px, padding 32px 0, borderBottom 1px solid #E4DDD2
- Staggered entry animation (opacity 0->1, translateY 16px->0, 0.4s, idx*60ms delay)
- Hover: opacity 0.85
**Text column:**
- Meta: date · TypeBadge · CategoryBadge, 12px, gap 8px
- Title: 19px, weight 800, #263238, line-height 1.5
- Subtitle (optional): 14px, #0F6B73, weight 600
- Author: 13px clickable name (#0F6B73 if clickable), specialty, separator ·
- Summary: 14px, #5F6B6D, line-height 1.8
- Stats: type, read time, views, tags (2 max, #F4EFE6 bg)
**Thumbnail column:**
- 140px wide, 120px height, #F4EFE6 bg, 10px radius
- DiagramRenderer at 0.5 scale, 280px container width
- Hidden on mobile (<560px)
### 5.7 Article Detail Page
**Breadcrumb (sticky-aware):**
- Background #F4EFE6, borderBottom 1px solid #E4DDD2, padding 12px 24px
- Font 12px, color #5F6B6D
- Home › Category › Article title (truncated to 40 chars)
- Clickable: home (#0F6B73), category (#0F6B73)
**Layout:**
- Two-column: TOC sidebar (200px) + article content (max-width 760px), gap 48px
- For TekRAG: TOC 220px + content max-width 860px, gap 52px, centered with justify-content center
**Article Header:**
- badge row (TypeBadge, CategoryBadge, StatusBadge, optional promoted/premium)
- H1: clamp(22px,4vw,34px), 900 weight, #263238, line-height 1.4
- Subtitle: 18px, #5F6B6D, weight 400, line-height 1.6
- Author byline: avatar 40px + clickable name + specialty + verified badge
- Meta: date · type · read time · comment count, 13px, #5F6B6D
- Action row: Save button + Share buttons (Telegram blue #0088cc, WhatsApp green #25D366, X dark #14171A, LinkedIn blue #0A66C2, copy link)
**Author Box (bottom of article):**
- Background #F4EFE6, 12px radius, 24px padding
- Flex row, gap 16px
- Avatar 64px, author name 16px 700 weight, specialty #0F6B73, bio 13px
- Social links as pill buttons (white bg, 1px #0F6B7330 border)
**Reaction Row:**
- Label: "واکنش شما به این مقاله؟"
- 5 reaction buttons: مفید (thumbsUpIcon), عالی (starIcon), عاشقانه (heartIcon), داغ (flameIcon), تأمل‌برانگیز (lightbulbIcon)
- Each: pillBtn style, bg #F4EFE6 / #0F6B7318 (active), border #E4DDD2 / #0F6B7340 (active)
- TekRAG English: Helpful, Excellent, Valuable, Important, Thought-provoking
**Series Banner (if part of series):**
- Background #0F6B7308, border 1px #0F6B7330, 10px radius, 16px padding
- "سری مقاله" badge (#0F6B73 bg, white text) + series title + position
- "مشاهده همه قسمت‌ها ←" link
**Correction Notice:**
- Background #FFF8EA, border 1px #D49A2A55, 12px radius, 18px padding
- Title "اصلاحیه و به‌روزرسانی" 14px, 900 weight
**Tags:**
- Flex wrap, gap 8px
- "برچسب‌ها:" label 12px, #5F6B6D
- Tag buttons: bg #F4EFE6, border 1px #E4DDD2, 3px 10px padding, 4px radius, 12px, #5F6B6D
**Related Articles:**
- Section below comments
- H3 "مقاله‌های مرتبط" 18px 700
- Grid of ArticleCard components
### 5.8 Table of Contents (Sidebar)
- Sticky position, top 90px, max-height calc(100vh - 100px), overflow-y auto
- Header: "فهرست مطالب" 11px, 700 weight, #5F6B6D, letter-spacing 0.08em
- Headings: block items with padding
- H2 level: 5px 0, font-size 13px
- H3 level: 4px 12px, font-size 12px
- Active state: color #0F6B73, weight 700, right border 2px solid #0F6B73
- Inactive: color #5F6B6D, weight 400, transparent right border
- Smooth scroll on click via scrollIntoView
- Hidden on <900px screens
### 5.9 Article Content Styling (articleContentStyle)
- font-size 16px, line-height 2.0, color #263238, direction rtl
- H2: 22px, 800 weight, #263238, margin 40px 0 16px, padding-bottom 8px, border-bottom 2px solid #E4DDD2
- H3: 18px, 700 weight, #263238, margin 32px 0 12px
- P: margin 0 0 20px
- .lead: 18px, line-height 2.05, #1A3035, 500 weight, white bg, border 1px #E4DDD2, right border 4px #0F6B73, 12px radius, 20px 22px padding
- Blockquote: right border 4px #D49A2A, margin 28px 0, padding 16px 20px, bg #D49A2A0A, radius 0 8px 8px 0
- .security-quote blockquote: right border color #C94C4D, bg #C94C4D08
- Strong: color #263238, weight 700
- Em: color #0F6B73, font-style normal, weight 600
- Inline code: bg #0F6B7316, border 1px #0F6B7328, 4px radius, padding 1px 6px, font-size 13px, monospace, color #0A5060, direction ltr, unicode-bidi isolate, white-space nowrap
- Pre/code blocks: bg #131F22, 10px radius, padding 40px 18px 18px, margin 24px 0, border 1px #1E3035, direction ltr; code: color #A8D8DC, font-size 13.5px, line-height 1.85, display block
- .code-copy-btn: absolute top 8px left 10px, bg #1E3035, border 1px #2A4048, color #6AACB5, 6px radius, 4px 10px padding, 11px font; hover bg #2A4048 color #A8D8DC
- [data-lang]::before: language label, absolute top 10px right 14px, 10px, color #4A7A82, monospace, uppercase
- UL: padding-right 0, list-style none, grid gap 6px; li::before — "›" character, #0F6B73, 17px, position absolute right 4px
- OL: counter-reset, padding-right 0, grid gap 8px; li::before — circled number, 24x24px, #0F6B73 bg, white text, 11px 800 weight
- .ltr: direction ltr, unicode-bidi isolate, inline-block, Inter/Arial
- .metric-grid: repeat(auto-fit, minmax(150px, 1fr)), gap 12px, margin 28px 0
- .metric-card: white bg, 1px #E4DDD2, top border 3px #0F6B73, 10px radius, 14px 16px padding
- .metric-value: #0F6B73, 900 weight, 22px
- .metric-label: #5F6B6D, 12px
- Table: width 100%, collapse borders, margin 24px 0, white bg, 1px #E4DDD2, 10px radius overflow hidden; th: bg #F4EFE6, 800 weight; td/th: 12px 14px padding, min-width 130px
- .comparison-template: bg #fffaf1, border 1px #E4DDD2, 12px radius, 18px padding
- .risk-box: bg #C46A4D10, border 1px #C46A4D35, 12px radius, 18px 22px padding
- .agent-steps: counter-reset, gap 10px; .agent-step: white bg, 1px #E4DDD2, 10px radius, 14px 48px 14px 16px; ::before circled counter number
- .article-diagram-card: bg gradient #F4EFE6→#FFFFFF, border 1px #E4DDD2, 12px radius, 22px padding, shadow 0 12px 34px rgba(15,42,46,0.06)
- .insight-box: bg #0F6B7310, border 1px #0F6B7330, 10px radius, 20px 24px padding; .insight-title: 13px, #0F6B73, 700 weight
- .footnote-box: bg #F4EFE6, 8px radius, 16px 20px padding, 12px, #5F6B6D
- .cve-summary-card: gradient #EEF6F7→#E8F3F4, 1px rgba(15,107,115,0.18), 12px radius, 20px 24px padding, grid repeat(auto-fit, minmax(120px, 1fr))
- .security-alert: bg #C94C4D0A, border 1px #C94C4D30, right border 4px #C94C4D, radius 0 10px 10px 0, 16px 20px padding; .alert-title: 13px, 800 weight, #C94C4D
### 5.10 Premium Content Gating
- Article content with mask: `maskImage: linear-gradient(to bottom, black 40%, transparent 100%)`, max-height 320px, overflow hidden
- PremiumGateCard: gradient #0F2A2E→#1A3A40, 16px radius, 36px 32px padding, border 1px #D49A2A40
- Crown icon SVG
- Title "این مقاله برای اعضای ویژه" — 18px, #D49A2A, 700 weight
- Description text #A8B8BA
- Features list with checkmarks
- CTA button: gradient #D49A2A→#B8821E, white text, rounded
- Secondary login button: transparent, #A8B8BA border
### 5.11 Filter Bar (Article List)
- Category chips: "همه" + 7 category buttons
- Type chips: همه + تحلیل عمیق + راهنمای فنی + داده‌نما + پژوهش + راستی‌آزمایی‌شده + پرونده
- Sort chips: جدیدترین / پربازدیدترین / زمان مطالعه
- Chip states:
- Active: border 1.5px solid #0F6B73, bg #0F6B7312, color #0F6B73, weight 700
- Inactive: border 1px solid #E4DDD2, bg #fff, color #5F6B6D, weight 400
- Border-radius 20px (pill), padding 5px 12px, 12px font
- Scrollable horizontally on mobile (overflow-x auto, no scrollbar)
### 5.12 Newsletters
- NewsletterForm: max-width 460px, centered
- Email input + TeknavCAP captcha + submit button (#C46A4D bg)
- Success state: checkmark ✓ + "عضویت شما ثبت شد!" in #2F8F6B
### 5.13 Empty State
- Center alignment, padding 60px 24px
- Large circle icon "◎" 48px, 0.4 opacity
- Title 16px 600 weight, #263238
- Subtitle 13px, #5F6B6D
### 5.14 Skeleton Loader
- Multiple lines (configurable count), 16px default height
- Gradient shimmer: linear-gradient(90deg, #E4DDD2 0%, #F4EFE6 50%, #E4DDD2 100%)
- Background-size 200% 100%, shimmer animation 1.4s infinite
- Last line: 60% width for visual variety
- Inline `@keyframes shimmer` style tag for portability
### 5.15 Confirm Modal
- Fixed inset 0, z-index 500, centered flex
- Backdrop: rgba(0,0,0,0.45)
- Card: bg #FAF7F0, 12px radius, 32px padding, max-width 380px, 90% width, boxShadow 0 20px 60px rgba(0,0,0,0.2)
- Title "تأیید عملیات" 15px 600
- Message 13px, #5F6B6D
- Buttons: "انصراف" (#F4EFE6) + "تأیید و حذف" (#C94C4C) — right aligned, gap 10px
- ESC key to close
### 5.16 Toast System
- Fixed position: bottom 28px, left 24px, z-index 9999
- Stack: column gap 10px
- Each toast: padding 11px 20px, 8px radius, #fff text, 14px Vazirmatn
- Backgrounds: success #2F8F6B, error #C94C4C, warning #D08A22
- boxShadow 0 4px 20px rgba(0,0,0,0.18)
- Animation: slideUp 0.25s ease
- Auto-dismiss after 3200ms
- Direction rtl
### 5.17 Reading Progress Bar
- Fixed position: top 64px (below header), full-width, height 3px, z-index 99
- Track: #E4DDD2
- Fill: #0F6B73 with transition width 0.1s linear
- Synced to `(scrollTop / (scrollHeight - clientHeight)) * 100`
### 5.18 Author Avatar
- Circle, default size 40px
- Background: author's color or #0F6B73 fallback
- White text at size*0.32, weight 700
- Shows initials (author.initials || name.slice(0,2))
- Flex shrink 0
### 5.19 Badges
**CategoryBadge:**
- Inline-block, padding 3px 10px (small: 2px 8px)
- 4px radius, 12px font (small: 11px), weight 600
- Background: color + '18' opacity
- Color: full hex or #0F6B73 default
- Border: 1px solid (color + '30' opacity default)
**TypeBadge:**
- Inline-block, padding 3px 10px (small: 2px 8px)
- 3px radius, 11px font (small: 10px), weight 700, letter-spacing 0.03em
- Background + text from TYPE_COLORS map
**StatusBadge:**
- Inline-flex, gap 5px, padding 3px 10px
- 20px radius (pill), 11px, weight 600
- Dots: 6px circle, same color
- Background: color + '15', border: color + '30'
**RoleBadge:**
- Padding 2px 9px, 3px radius, 11px font, 700 weight
- Background: color + '18', text color
**RolePill (Profile page):**
- Inline-block, padding 3px 12px, 20px radius, 11px, 700 weight
- Colors per role (terracotta for admin, green for editor, gold for writer, blue for reviewer, muted for reader)
### 5.20 Button Styles
**iconBtnStyle:**
- background: none, border: none, cursor pointer
- Flex center, 36x36px, 8px radius
- Transition background 0.15s
**pillBtn:**
- border: none, cursor pointer
- padding 8px 18px, 8px radius
- 13px, Vazirmatn, weight 600
- Transition all 0.15s
- Inline-flex, gap 6px, align-items center
**inputStyle:**
- border 1px solid #E4DDD2, 8px radius
- padding 9px 14px, 13px font, Vazirmatn
- background #fff, color #263238
- outline none, width 100%
**Auth goldBtn:**
- width 100%, padding 13px 0, 10px radius
- Gold gradient background, #0F2A2E text
- 14px 700 weight, boxShadow 0 4px 16px rgba(200,149,28,0.22)
- Loaded state: bg #E8E2D8, color #B0B8BA, cursor not-allowed, no shadow
- CSS class .auth-gold-btn hover: opacity 0.91, translateY(-1px), stronger shadow
**Auth oauthBtnStyle:**
- Flex center, gap 10px, width 100%
- padding 11px 0, 10px radius
- border 1.5px solid #E4DDD2, bg #fff
- 13px weight 600, color #1A2E30
- CSS hover: border-color #C46A4D, bg #FFFCFB
**Auth cancelBtn:**
- flex 1, padding 12px 0, border 1.5px solid #E4DDD2
- 10px radius, transparent bg
- color #7B8C8E, 13px 600 weight
**Gold Buttons (auth page):**
- class .auth-gold-btn: hover opacity 0.91, translateY(-1px), boxShadow 0 7px 22px rgba(200,149,28,0.38)
- Disabled: cursor not-allowed
### 5.21 Input Fields
**AuthInput component:**
- Label: 12px, 600 weight, color #7B8C8E (error: #C94C4C), margin-bottom 6px
- Input wrapper: position relative
- Input: border 1.5px #E4DDD2 (error: #C94C4C), 10px radius, padding 13px 16px (or 13px 16px 13px 46px with suffix), 14px, bg #FAFAF8, color #1A2E30
- Focus: border-color #C8951C, bg #fff, boxShadow 0 0 0 3px rgba(200,149,28,0.1)
- Suffix: absolute left 14px, top 50%, transform translateY(-50%), color #9AA5A6
- Hint: 11px, color #9AA5A6
- Error: 11px, color #C94C4C
**PasswordStrength component:**
- 5-segment bar: 3px height, 2px radius per segment, color varies by score (≤2: #C94C4C, 3: #D08A22, ≥4: #2F8F6B)
- Chips: flex wrap, 10px font, 20px radius, 2px 8px padding
- Passed: bg rgba(47,143,107,0.09), color #2F8F6B, ✓ prefix
- Failed: bg #F2EFE9, color #9AA5A6, · prefix
- Criteria: ۸+ کاراکتر, حرف کوچک, حرف بزرگ, عدد, نماد
---
## 6. ANIMATIONS & TRANSITIONS
### 6.1 Keyframe Animations
| Name | Details | Usage |
|---|---|---|
| `fadeIn` | 0→1 opacity | Generic fade-in |
| `slideUp` | translateY(20px) + opacity 0 → 0 + 1 | Toast, modals, push prompts |
| `shimmer` | background-position 200%→-200% | Skeleton loader, diagram skeleton |
| `spin` | 0→360deg rotate | Loading spinner |
| `float-y` | translateY(0)→(-6)→(0), 3s | Gold star, streak widget, word bubbles |
| `goldShimmer` | background-position -200%→200%, 5s linear | Gold shimmer text |
| `pulseRing` | boxShadow expand from 0 to 14px to 0, 2.2s | Live indicator dot, hero badge pulse |
| `heroReveal` | opacity 0→1, filter blur(6px)→0, translateY(18px)→0 | Homepage hero elements (staggered 0.1s–1.35s delays) |
| `orbit` | 0→360deg rotate | Auth brand panel outer/inner rings |
| `orbitR` | 0→-360deg rotate | Auth brand panel middle ring |
| `tickerUp` | translateY(0)→(-50%), linear 22s | Auth brand topic ticker |
| `bgGrid` | background-position loop, 38s linear | Auth form grid background |
| `logoGlow` | boxShadow pulse, 4.5s ease-in-out | Auth logo glow |
| `fadeSlideUp` | opacity 0→1, translateY(16px)→0, 0.45s/0.25s | Auth cards and modals |
| `statReveal` | scale 0.75→1.05→1 + translateY, cubic-bezier | Brand panel stat numbers |
| `dividerExpand` | width 0→48px, opacity 0→1 | Brand panel divider |
| `blink` | opacity 1→0.3→1 | Cursor/indicator blink |
### 6.2 Transition Timings
| Duration | Easing | Usage |
|---|---|---|
| 0.15s | ease | Button hovers, nav items, link colors, chip states, filter changes |
| 0.18s | ease | Social button hovers, auth tab toggles, OAuth buttons |
| 0.2s | ease | Card shadows, hero CTA, general hovers, icon buttons |
| 0.22s | ease | Auth tab buttons |
| 0.25s | ease, cubic-bezier(.2,.8,.2,1) | Lift-on-hover, toast entrance, hero-tilt |
| 0.3s | linear/ease | Loading bar, scroll progress, header backdrop, card opacity |
| 0.4s | cubic-bezier(.2,.8,.2,1) | Hero tilt, stagger article row entrance |
| 0.5s | ease | Staggered card entrance (homepage) |
| 0.6s | cubic-bezier(.2,.8,.2,1) | Hero reveal animations |
| 0.7s | linear | Loading bar tick |
| 0.8s–3.2s | various | Auth brand panel parallax, delayed animations |
| 0.9s | cubic-bezier(.2,.8,.2,1) | Auth brand parallax glow |
### 6.3 Hover Effects Summary
- Cards: shadow elevation increase + translateY(-2px to -4px)
- Buttons: background fill, opacity change, slight lift
- Links: color change to #0F6B73, translateX(-4px) in footer
- Featured card: parallax tilt (perspective 900px, rotateX/Y up to ±6deg)
- Article rows: opacity 0.85
- Category cards: background tint
- Comparison/comany cards: shadow on hover
- Story cards: scale(1.03) + shadow
---
## 7. HOMEPAGE LAYOUT (Detailed)
Structure in order (top to bottom):
1. **Personalized Bar** (logged-in only): background #F4EFE6, borderBottom 1px #E4DDD2, flex wrap
- StreakWidget: gradient orange, 8px 14px padding, 12px radius, white text, float-y animation
- ContinueReadingBar: dark #263238 bg, horizontal scroll of in-progress articles with progress bars
2. **Hero Section**: light bg #F4F1EC, min-height 560px
- Neural network Canvas background (32 nodes, teal/terracotta/green palette, pulsing connections up to 130px distance)
- Radial gradient glows + subtle grid overlay (48px squares, 4% opacity lines, masked radial)
- Tagline badge "روایت عمیق فناوری" with pulse dot
- H1 "درک عمیق‌تر" (PelakFA) + gold-shimmer "دنیای فناوری"
- Subtitle "تحلیل‌های علمی، تخصصی و مستقل..."
- CTA buttons: "مشاهده همه مقاله‌ها →" (teal, shadow) + "هوش مصنوعی" (terracotta outline)
- Featured card sidebar: white, 4px gold gradient left accent, "مقاله ویژه" label + title + author/type/read time
- Mouse parallax tilt effect on featured card
- SVG wave divider (#ebe3d2 fill) at bottom for transition
3. **Stats Bar**: bg #ebe3d2, 40px padding
- 4 stats: مقالات منتشرشده ۱۸۰+, نویسنده فعال ۳, خواننده ماهانه ۴۵۰۰۰+, میانگین زمان مطالعه ۸ دقیقه
- CountUp animation (cubic ease-out, 1400ms) with Persian digit formatting + thousands separator
- Gold (#A8761B) numbers in PelakFA 900, 30px
- Vertical dividers between items
4. **Personalized Feed** (logged-in): "پیشنهاد برای شما" section
5. **Featured Article**: "مقاله منتخب" — FeaturedArticle component (two-column layout)
6. **Latest Articles**: "تازه‌ترین خبرها" with "مشاهده همه ←" link — 6 ArticleCards in grid
7. **Deep Analyses**: "تحلیل‌های عمیق" — ArticleRowCompact list items
8. **Popular**: "محبوب‌ترین‌ها" — 4 ArticleCards in grid
9. **Categories**: "دسته‌بندی‌ها" — category cards with 3px colored right border, description, article count
10. **Authors**: "نویسندگان تکناو" — author cards with avatar 56px, name, specialty, article count
11. **Newsletter**: "عضو خبرنامه تکناو شوید" — sand box with radial glows, form
---
## 8. ARTICLE IMAGES & THUMBNAILS
### 8.1 Diagram System
Articles do NOT use photographic images. Instead, every article has a `diagram` field (string type identifier) that maps to a `DiagramRenderer` or `LazyDiagram` component. These are interactive SVG/Canvas-based diagrams rendered inline.
**Diagram types observed:**
- `"pipeline"` — data/agent pipeline flow
- `"diagram-12"` — architecture diagram
- `"cyber"` — cybersecurity risk map
- `"orbit"` — market movement diagram
- Various category-specific diagrams per article
**Thumbnail rendering:**
- Homepage ArticleCard: 120px height container, #F4EFE6 bg, DiagramRenderer scaled to 0.7
- ArticleRow (list): 140px wide × 120px height, DiagramRenderer at 0.5 scale
- ArticleRowCompact (homepage deep analysis): 80×80px thumbnail, 0.55 scale
- Article hero diagram: full width, #F4EFE6 background, 12px radius, 24px padding
**Hero diagram (article detail):**
- Placed below article header
- Background #F4EFE6, 12px radius, 24px padding, 32px margin-bottom
- Label "نمودار تعاملی — با موس روی عناصر بروید" in 11px, #5F6B6D
- LazyDiagram loads on demand with lazy chunk loading
**Diagram skeleton (loading):**
- 100% width, min-height 120px
- 8px radius
- Shimmer gradient: #ebe3d2 → #f4efe6 → #ebe3d2
- shimmer animation 1.4s infinite
### 8.2 OG Images & Discover Hero
- OG images generated at build time: `/images/og/{slug}.jpg` (1200×630px)
- Optional `ogImage` field in article data for custom images
- Discover Hero image (optional): displayed as `<figure>` with 1200×630 aspect ratio, borderRadius 12px, border 1px #E4DDD2, object-fit cover
- Stories: article thumbnails use ogImage or `/images/og/{slug}.jpg`, shown at `filter: brightness(0.55)` with gradient overlay
### 8.3 Article Diagrams (Embedded Cards)
- `EmbeddedDiagramCard` component: title + subtitle + LazyDiagram
- Title: 13px (Persian) / 15px (English), 800 weight, #0F6B73
- Subtitle: 12px, #5F6B6D, line-height 1.8
- Card background: gradient #F4EFE6→#FFFFFF (Persian) or #FAFAFA solid (English)
- Border: 1px #E4DDD2 (Persian) or #E8E8E8 (English)
- Box-shadow: 0 12px 34px rgba(15,42,46,0.06) (Persian) or 0 2px 8px rgba(0,0,0,0.06) (English)
### 8.4 Quote Sharer Canvas Card
- Canvas 1080×1080px
- Dark gradient background: #0C1E22 → #0F3540
- Corner accent: #0F6B73 triangle (top-right, 220px)
- Subtle grid overlay: 60px grid lines at 3% opacity white
- Gold separator bar (#D49A2A): 5px wide, 80px tall, positioned at (80, 90)
- Logo: "تکناو" in 32px 700 weight, right-aligned at (W-60, 80)
- Tagline: "teknav.ir" in 16px, rgba(212,154,42,0.55), at (W-60, 106)
- Large quotation mark: "«" in 280px, rgba(212,154,42,0.18), at (W-40, 420)
- Quote text: white, 38px, 400 weight, RTL, wrapped at W-160 max width, 60px line-height
- Gold divider line after quote: 2px height, W-160 width
- Article title: rgba(255,255,255,0.65), 26px, 400 weight
- Author name: rgba(255,255,255,0.45), 22px, 400 weight, positioned at bottom
### 8.5 Story Pages (Generated Static)
- Full-screen CSS scroll-snap story format
- Each story has OG + Twitter Card meta
- Keyboard navigation supported
- Generated at build time into `dist/stories/{slug}/index.html`
### 8.6 Comparison Page Images
- No images — purely text-based comparison with pros/cons lists
- Item names in colored badges: first item green (#E8F5E9 bg, #2E7D32 text), second item orange (#FFF3E0 bg, #E65100 text)
- Arrow separator: "در برابر" text in #5F6B6D
### 8.7 Company Directory Images
- No images — company cards are text-only
- Company name, description (truncated 100 chars), tech stack tags, verified badge
---
## 9. AUTH PAGE DESIGN
### 9.1 Layout
- Full-viewport flex split: form column (flex:1) + brand panel (440px fixed width)
- Hidden at <880px (brand panel disappears, mobile logo appears)
- The auth-layout has class `auth-layout` (flex, min-height 100vh, rtl)
### 9.2 Form Column
- Background #FAF7F0 with subtle grid pattern (terracotta lines at 2.8% opacity, 52px grid size, bgGrid animation 38s)
- Radial vignette: `radial-gradient(ellipse 80% 55% at 50% 5%, transparent → rgba(250,247,240,0.55))`
- Content max-width 420px, centered, position relative z-index 1
- Heading with vertical accent bar (3.5px width, 30px height, gradient #C46A4D→rgba(200,149,28,0.6))
- Time-based greeting in PelakFA 800, 25px, #0F2A2E
### 9.3 Tab Switcher (Login / Signup)
- Background #EDE9E2, 12px radius, 4px padding
- Two tabs: "ورود" (login) / "ثبت‌نام" (signup)
- Active tab: white bg, boxShadow 0 1px 6px rgba(0,0,0,0.1), color #0F2A2E
- Inactive: transparent bg, color #9AA5A6
- CSS class `.auth-tab-btn`: flex 1, padding 10px 0, 13px 700 weight, 9px radius, transition 0.22s
### 9.4 Login Form
- Fields: identifier (email/username) + password + CAPTCHA
- Identifier: AuthInput with label "نام کاربری یا ایمیل", placeholder "@username یا you@example.com", LTR direction
- Password: AuthInput with label "رمز عبور", show/hide toggle (EyeIcon), "فراموشی رمز؟" link
- CAPTCHA: TeknavCAP custom component
- Submit: goldBtn "ورود به حساب" with loading spinner
- Forgot password link opens modal
### 9.5 Signup Form
- Fields: name + username + email/phone toggle + password + confirm password
- Name: "نام نمایشی", placeholder "مثال: علی رضایی"
- Username: English only, LTR, auto-lowercase, hint shows profile URL
- Identifier toggle: email/phone pill switcher (#F0EDE6 bg, white active pill)
- Password: EyeIcon toggle + PasswordStrength bar
- Confirm: checkmark icon when match (#2F8F6B)
- CAPTCHA + terms acceptance
- Submit: goldBtn "ایجاد حساب کاربری"
### 9.6 OAuth Buttons Section
- Conditionally rendered based on `GET /api/v1/auth/oauth/providers`
- Google button with SVG icon: "ادامه با Google"
- GitHub button with SVG icon: "ادامه با GitHub"
- Divider: "یا با ایمیل" text between lines
- CSS hover: border-color #C46A4D, bg #FFFCFB
### 9.7 Brand Panel (Dark Theme)
- Background: `#0B2226` (very dark teal)
- Giant watermark letter "ت" in 360px, 1.6% opacity, PelakFA
- Dot grid pattern (white dots at 3.2% opacity, 28px spacing)
- Parallax gold glow that follows cursor (300px circle, 14% opacity gold, transforms with mouse position)
- Terracotta accent glow at bottom-left
- Floating Persian tech words (هوش مصنوعی, ابر, امنیت, متن‌باز, پردازش, شبکه, داده, زیرساخت) at various positions with float-y animation
- Orbital logo: 100px square with dashed/solid orbiting rings (44s, 17s, 9s durations), gold gradient center with "ت" character
- Wordmark "تکناو" in 50px PelakFA, #FAF7F0, with "TEKNAV · IR" sub-label
- Animated divider line (gold gradient, expands from center)
- Tagline: "آخرین دانش فناوری، اول به فارسی"
- Live stats count-up: ۲۳+ مقاله, ۸۴۰۰ خواننده, ۶ سری
- Topic ticker: scrolling text list (8 Persian tech topics, 22s linear infinite, masked with linear gradient)
- Online pulse indicator: green dot with pulseRing animation + "در حال حاضر آنلاین"
### 9.8 Forgot Password Modal
- Centered modal with dark overlay (rgba(11,34,38,0.62))
- Card: bg #FAF7F0, 18px radius, 36px 32px padding, max-width 400px
- "بازیابی رمز عبور" title in PelakFA 18px 800, #1A2E30
- Email input + cancel/send buttons
- Sent state: message + close button
---
## 10. PROFILE PAGE DESIGN
### 10.1 Color Identity
Uses terracotta-centric palette (P object): terracotta #C45C3D, orange #E07A3A, green #3A7D5E. No teal on this page.
### 10.2 Hero Banner
- Gradient background: #FDF6EE → #F7EDE0 → #EEF5F0
- Border-bottom 1px #E4DDD2
- 3 decorative circles (terracotta 6%, green 7%, gold 6% opacity)
- Flex layout: avatar (110px) + info + action buttons
- AvatarUpload component: 110px circle, 3px terracotta border, boxShadow, upload overlay at bottom
- Name with verified expert badge (terracotta outline pill), RolePill
- @username in terracotta 13px 600
- Bio paragraph 14px, #5F6B6D, max-width 580px
- Education/credential info with graduation cap and scroll icons
- Expertise tags: green bg, green text, 20px radius pills
- Join date, article count, follower count, social links (X, LinkedIn)
- Follow/Edit buttons
### 10.3 Stats Bar (Writers)
- Background #F4EFE6 panel
- 3 stats with left borders: articles count, total views, total reactions
- Numbers in 22px 900 weight, terracotta
### 10.4 Badges Section
- White background, border-bottom
- Badge pills: gradient #F4EFE6→#FDFAF5, 1px #E4DDD2, 24px radius, 6px 14px padding, 12px 600 weight
- 8 types: ai_reader, data_reader, security_reader, hardware_reader, weekly_streak, monthly_streak, power_reader, early_adopter
### 10.5 Content Tabs
- "مقالات" (Articles) and "آمار و تحلیل" (Analytics) tabs
- Underline style: active has 2px terracotta bottom border
- Tab content: grid of ArticleMiniCard components (4px terracotta left border, white bg, title 15px 700, summary, views/reactions)
### 10.6 Writer Analytics Tab
- 3 summary cards: total views, reactions, comments — each with 3px colored top border
- 30-day sparkline SVG chart (terracotta line, 12% opacity fill)
- Per-article table with columns: title, views (terracotta), reactions (orange), comments, saved
### 10.7 Profile Settings Modal
- Full-screen overlay (rgba 0,0,0,0.5)
- Card: cream bg, 16px radius, 32px padding, max-width 440px, max-height 88vh scrollable
- Sections: display name, username (conditionally editable), bio, password change, email verification, phone OTP, 2FA toggle, browser push notifications, notification preferences (expandable table)
### 10.8 Notification Preferences Table
- Expandable panel (toggle open/close)
- Table with columns: event type | push | email | sms
- Events: comment, comment_reply, new_article, review_approved, review_revision, review_rejected, review_submitted, system
- Toggle buttons: 28×16px pill switches, green (#3A7D5E) when enabled, #CCC when disabled
---
## 11. COMPARISON PAGES
### 11.1 ComparisonsListPage
- Breadcrumb: تکناو › مقایسه‌ها
- Title "مقایسه‌های فنی تکناو" — 32px 800 weight, #0C1E22
- Search input (max-width 400px)
- Comparison cards: white bg, 12px radius, 1px #E4DDD2, 20px 24px padding, hover shadow
- Category badge colored pill (#fff text)
- Title 17px 700
- Item names: green pill (item1) + "در برابر" (in #5F6B6D) + orange pill (item2)
- Arrow "←" in #0F6B73
### 11.2 ComparisonPage (Detail)
- Card layout: flex wrap, two cards side by side
- Each card: white bg, 12px radius, 24px padding, border 1px #E4DDD2, flex 1 1 300px
- Item name: 20px 700, #0F6B73
- Summary paragraph 14px
- Pros (✓ green #2E7D32) and Cons (✗ red #C62828)
- Use cases: sand bg (#F8F5F0), flex row of two white bordered cards with item name labels
- Verdict: dark teal bg (#0F3540), #D49A2A title, white text
- Related glossary: white cards with teal border, term + english
- Related articles: white bordered cards with title + summary + arrow
- Vote widget (ComparisonVoteBar): localStorage-based, two-button layout for item1 vs item2
---
## 12. SEARCH PAGE
- Advanced search layout: 240px sidebar + results area
- Filters: category (dropdown), author (dropdown), content type (dropdown), clear button
- Search results: fade-in staggered animation, 24px padding, borderBottom
- Highlighted query terms: `<mark>` with background #D49A2A30, #263238 text
---
## 13. LOADING & ERROR STATES
### 13.1 Splash Loader (index.html)
- Full-screen fixed overlay (#FAF7F0 bg, z-index 9999)
- "تکناو" in 36px 900 weight, #0F6B73
- "TEKNAV" sub-label 11px, #5F6B6D, letter-spacing 0.15em
- Loading bar: 40px wide, 3px height, #E4DDD2 track, #0F6B73 fill, transition width 0.3s
- Auto-progress from 0→90% (8% every 120ms), then jumps to 100% on JS mount
- `window.__doneLoading()` called from main.jsx after React renders
- Class `.hidden` sets opacity 0 + pointer-events none (0.4s transition)
- HTML class `js` toggles visibility; no-JS fallback shows static content
### 13.2 Static Fallback (no-JS)
- Class `.static-fallback`: min-height 100vh, bg #FAF7F0, color #263238, rtl, padding 72px 20px, Vazirmatn
- Max-width 920px inner container
- Eyebrow "رسانه فارسی تحلیل فناوری" — #C45C3D, 13px, 800 weight
- H1 in #0F6B73, 36px
- H2 in #263238, 22px
- Lead paragraph #5F6B6D
- Link list items: border 1px #E4DDD2, 8px radius, white bg, 12px 14px padding; links in #C45C3D 800 weight
- Section "تکناو چیست؟" with explanatory paragraph
### 13.3 Network/API Error States
- Article 404: EmptyState + back-to-articles button
- Comments error: EmptyState "نظرها از API دریافت نشد"
- Article not found: EmptyState + return button
- Search empty: EmptyState "نتیجه‌ای یافت نشد"
- Category not found: EmptyState "دسته‌بندی یافت نشد"
- Profile not found: EmptyState "پروفایل یافت نشد"
- Comparison not found: EmptyState
- Company not found: EmptyState
- Generic loading: "در حال بارگذاری…" or SkeletonLoader
### 13.4 Auth Error States
- 401: invalid credentials message
- 429: rate limit warning
- 403: account suspended message
- 400: captcha invalid + refresh instruction
- 409: duplicate email/phone/username
- Rate limit: "تعداد تلاش‌های ناموفق از حد مجاز گذشت"
- OAuth errors: red error box (#FEF2F2 bg, #991B1B text) with "account_suspended" handling
---
## 14. WIDGET SYSTEM (Embed)
### 14.1 Architecture
- Separate Vite entry: `embed.html` → `src/embed.jsx` → `src/widgets/`
- URL routing: `/embed/{type}/{slug}`
- Types: `glossary`, `article-card`, `company`
- Third-party loader: `public/embed-loader.js` — creates sandboxed `<iframe>`
### 14.2 GlossaryWidget
- Background: light cream (#FAF7F0-like) with dark mode support (`prefers-color-scheme`)
- Header: term name in gold (#D49A2A) + English translation
- Summary paragraph
- Collapsible FAQs (`<details>/<summary>`)
- Footer link to Teknav
- Auto-resize via ResizeObserver + postMessage
### 14.3 ArticleCardWidget
- Hero image (OG image or generated) with category badge overlay
- Title + summary (120 chars)
- Author name + "خواندن در تکناو ↗" link
- Dark mode via static check
- Auto-resize
### 14.4 CompanyWidget
- Loading skeleton during fetch
- Header: company logo placeholder, name, verified badge, category pill
- Description paragraph
- Tech stack tags
- Footer: website link + "پروفایل در تکناو ↗"
- Empty/not-found state
- Dark mode + auto-resize
### 14.5 embed-loader.js (Third-party Script)
- Self-contained, pasted as `<script>` tag
- Reads `data-type`, `data-slug`, `data-width` attributes
- Creates sandboxed `<iframe>` pointing to `www.teknav.ir/embed/{type}/{slug}`
- Attributes: `loading="lazy"`, `sandbox="allow-scripts allow-popups allow-same-origin"`, `title`
- Listens for `postMessage` resize events
- Default width 480px
---
## 15. PWA & INSTALL
### 15.1 Service Worker
- Registered in index.html inline script on `window.load`
- Service worker file: `/service-worker.js`
- Push notification subscription via PushManager API + VAPID keys
### 15.2 InstallPrompt
- Listens for `beforeinstallprompt` event
- Prompt card: fixed bottom-100 right-24, z-index 500
- White bg, 16px 20px padding, 16px radius, 1px #E4DDD2, boxShadow
- "نصب اپلیکیشن تکناو" title, "دسترسی سریع‌تر و آفلاین به مقالات" subtitle
- Actions: "بعداً" (outline) + "نصب" (teal filled)
### 15.3 PushNotificationPrompt
- Appears if PushManager available, permission default, not dismissed
- Card: dark bg #1A2E30, 16px radius, 14px 18px padding, 1px #2A4045 border
- Bell icon + "اعلان‌های مرورگر" title + subtitle
- Actions: "بعداً" (dark outline) + "فعال‌سازی" (terracotta)
- Records dismissal to localStorage
### 15.4 Manifest
- `/manifest.json`
- Theme color: `#0F6B73`
- Icons: 512x512 PNG favicon
---
## 16. RESPONSIVE DESIGN
### 16.1 Breakpoints
| Breakpoint | Name | Changes |
|---|---|---|
| ≤768px | Tablet | Desktop nav hidden, mobile hamburger shown, article layout to single column |
| ≤640px | Small tablet | Featured article to single column, stats to 2-column, categories to 2-column, article cards to single column |
| ≤560px | Phone | Aggressive mobile adjustments (see below) |
| ≤880px | Auth break | Brand panel hidden, mobile logo appears |
| ≤900px | Article break | TOC sidebar hidden, article layout single column |
### 16.2 Mobile Specifics (<560px)
**Header:**
- Height 56px, padding 14px
- Action buttons smaller (38px min-height, 9px radius, 12px font)
- Auth actions hidden
**Homepage:**
- Hero padding 44px 16px 48px
- Sections padding 28px
- Featured card: single column
- Stats: 2-column grid
- Article grid: single column
- Categories grid: 2-column
- Authors grid: 2-column
- Newsletter padding 36px 20px
**Article List:**
- Padding-top 64px
- Row single column (no thumbnail)
- Title 17px, summary 13px
- Horizontal scroll for meta/chips (no scrollbar)
- Filter chips: nowrap, scrollable
**Article Detail:**
- Padding 22px 16px, single column
- Title clamp(20px,5vw,23px)
- Summary 14px
- Byline flex-wrap
- Author box: wrap
- Lead: 16px, padding 16px
**Code blocks:**
- Smaller padding, max-width calc(100vw - 32px)
- Inline code: word-break break-all
**CVE cards:** single column, no left border (bottom border instead)
**Tables:** overflow-x auto, font-size 13px, smaller cell padding
**Metric grid:** single column
**All content elements:** `max-width: 100vw`, `overflow-wrap: break-word`, `hyphens: auto` for headings
**Pre/table:** `overflow-x: auto` with scrollbar hidden (webkit)
### 16.3 Responsive Grid Patterns
Most grids use `auto-fill`/`auto-fit` with `minmax()` for intrinsic responsiveness. The `@media` queries override specific grid templates at breakpoints where the intrinsic sizing doesn't produce ideal layouts.
---
## 17. TEKRAG ENGLISH ARTICLE SYSTEM
### 17.1 Overview
The TekRAG article (slug: `tekrag-persian-data-centric-rag-benchmark`) is an English-language research article rendered with LTR layout and distinct styling.
### 17.2 Differences from Persian Articles
- `dir="ltr"`, `textAlign: left`
- Font family: `'Inter', Arial, sans-serif` (instead of Vazirmatn)
- Layout: TOC 220px + content 860px, centered (instead of 200px + 760px)
- Article type badges in English labels
- Reaction labels: "Helpful", "Excellent", "Valuable", "Important", "Thought-provoking"
- Comment section: English labels throughout
- Author box: "AUTHOR" label, English bio
- Breadcrumb: "Home" instead of "خانه"
- Diagram cards: #FAFAFA bg, #E8E8E8 border
- Blockquote: left border instead of right, 0 8px 8px 0 → 8px 0 0 8px
- Lists: padding-left instead of padding-right, bullet/ counter positions flipped
- H2/H3/p/li/td/th: direction ltr, text-align left
- Code blocks: pre-existing LTR (no change)
---
## 18. DIAGRAM & DATA VISUALIZATION
### 18.1 DiagramRenderer / LazyDiagram
- Renders interactive diagrams (SVG/Canvas-based)
- Types include: pipeline, diagram-12, cyber, orbit, category-specific diagrams
- Compact mode for thumbnails (scaled down)
- Lazy loaded via React.lazy + Suspense
- Animations: pulsing nodes, flowing connections, hover tooltips
- Canvas-based for neural network (HeroBackground on homepage)
### 18.2 Sparkline (Profile)
- Inline SVG polyline
- 120×36px default (500×56px for analytics)
- Configurable color (default #C45C3D)
- Area fill at 12% opacity
- Stroke width 2px, round line caps
### 18.3 Comparison Vote Bar
- localStorage-based voting
- Two buttons for item1 vs item2
- No API calls — purely client-side persistence
---
## 19. ICON SYSTEM
### 19.1 SVG Icons
React components render inline SVG elements for social media logos:
- Google (4-color Google logo SVG)
- GitHub (black GitHub icon SVG)
- Telegram (blue paper plane, #0088cc)
- WhatsApp (green phone, #25D366)
- X/Twitter (dark #14171A)
- LinkedIn (blue #0A66C2)
### 19.2 CSS Mask Icons
Class `.tek-icon` pattern for SVG icons from asset files:
- CSS: `display: inline-block`, `width: 1em`, `height: 1em`, `background-color: currentColor`, `mask: var(--i) center / contain no-repeat`
- Used via: `<span class="tek-icon" style={{ '--i': url(${icon}) }} aria-hidden />`
- Inherits text color, scales with font size
- Used icons: crown, thumbs-up, star, heart, flame, lightbulb, eye, graduation-cap, scroll, bot, chart-column, lock, laptop, zap, library, sprout, medal, share-2, clipboard-copy
### 19.3 Text-Based Icons
- "✕" for close buttons
- "✦" decorative star
- "◉" bullet/metric icon
- "›" list bullet and breadcrumb separator
- "←" / "→" directional arrows
- "▲" upvote indicator
- "✓" checkmark (success)
- "✗" cross (failure)
- "⊕" plus/save
- "♡" heart (reaction)
- "●" dot (reaction)
- "?" thinking reaction
- "◎" empty state icon
- "🔥" fire emoji (streak widget)
- "🔔" bell emoji (push prompt)
- "✉" mail emoji (newsletter)
---
## 20. MISCELLANEOUS DESIGN PATTERNS
### 20.1 Scrollbar Styling
- Width: 6px (both axes)
- Track: #FAF7F0
- Thumb: #E4DDD2 with 3px radius
- Thumb hover: #5F6B6D
- Mobile: scrollbar-width none for horizontal scroll containers
### 20.2 Focus Styles
- All interactive elements: `outline: 2px solid #0F6B73`, `outline-offset: 2px` on `:focus-visible`
### 20.3 Selection
- Browser default selection styling (not customized in CSS)
- QuoteSharer intercepts for 20–400 character selections within article container
### 20.4 Breadcrumb Pattern
- Consistent across all content pages: Home › Section › Current
- Home and section links in #0F6B73, clickable
- Current page in #263238 or #5F6B6D, truncated with ellipsis if long
- Separator: "›" character (not / or >)
- Typically in a #F4EFE6 strip with borderBottom
### 20.5 Premium/Membership Upsell
- Premium badge: dark bg #0F2A2E, gold text #D49A2A, "Premium" label
- Premium gating: mask gradient on article content + PremiumGateCard
- Membership page at `/membership`
- Membership success at `/membership/success`
### 20.6 Promoted Content
- Amber label: bg #FFF4D8, color #8A5A00, border 1px #D49A2A55
- Labeled "Promoted Content" in 10-11px 800 weight
### 20.7 Fact-checking & Correction
- Correction notice: amber bg, gold border, title "اصلاحیه و به‌روزرسانی"
- Fact-checked date shown on articles and comparison pages
- Fact-checked articles can have TypeBadge "راستی‌آزمایی‌شده"
### 20.8 Count-Up Number Formatting
- Persian digits: ۰۱۲۳۴۵۶۷۸۹
- Thousands separator: ٬ (Persian comma, U+066C)
- Animation: cubic ease-out (power of 3), configurable duration (default 1400ms for stats)
- Rendered via `toLocaleString('fa-IR')` for standard formatting
### 20.9 LTR Embeddings
- Code blocks: always LTR (`direction: ltr`, `text-align: left`)
- English text in Persian articles: wrapped in `.ltr` spans
- Email/password fields in auth: LTR with left-aligned text
- Metric values: LTR-safe (numbers)
- TekRAG article: entire page LTR
### 20.10 Toast Accessibility
- Fixed bottom-left in viewport (not blocking RTL content)
- Auto-dismiss after 3.2 seconds
- Color-coded by type (green success, red error, amber warning)
### 20.11 Modal Backdrops
- All modals use `rgba(0,0,0,0.45)` or darker for overlay
- Auth modals: `rgba(11,34,38,0.62)` (coordinated with dark brand)
- Clicking backdrop closes modal
- ESC key closes most modals
- Modal card z-index: 500-700 range
### 20.12 Accessibility Features
- `aria-label` on all icon buttons and nav sections
- `aria-current="page"` on active nav items
- `role="banner"` on header, `role="contentinfo"` on footer, `role="navigation"` on nav
- `role="dialog"`, `aria-modal="true"` on modals
- `role="search"` on search forms
- `aria-expanded` on expandable elements
- Focus-visible outlines on all interactive elements
- Semantic HTML: `<article>`, `<section>`, `<nav>`, `<header>`, `<footer>`, `<main>`, `<aside>`, `<figure>`, `<time>`
---
## 21. FILE & ARCHITECTURE SUMMARY
### 21.1 Module Responsibilities
| File | Primary Role | Design Significance |
|---|---|---|
| `index.html` | HTML shell, SEO meta, JSON-LD, splash loader, static fallback | First paint, branding, loading state |
| `src/main.jsx` | Vite entry, global CSS import, splash dismissal | Startup flow |
| `src/styles/global.css` | Fonts, reset, animations, RTL base, utilities, mobile overrides | Core visual foundation |
| `teknav-app.jsx` | Router, provider stack, error tracking | App shell, provider nesting |
| `teknav-ui.jsx` | Shared UI: Header, Footer, auth, nav, badges, toasts, modals, prompts | Consistent component library |
| `teknav-home.jsx` | Homepage layout, hero, stats, cards, author section | First impression |
| `teknav-articles.jsx` | Article list, detail, comments, Q&A, TOC, diagrams, reactions | Core reading experience |
| `teknav-pages.jsx` | All secondary pages (search, category, glossary, comparisons, etc.) | Content discovery |
| `teknav-auth.jsx` | Login/signup page, brand panel, OAuth, password reset | Auth UX |
| `teknav-profile.jsx` | User profile, settings, analytics, badges, history | User identity |
| `teknav-data.js` | Static seed data (articles, authors, categories, comparisons, companies) | Content reference |
| `teknav-store.js` | Legacy localStorage store (auth stubbed) | Legacy state |
| `src/lib/api.js` | fetch wrapper with CSRF, versioning, typed errors | Transport layer |
| `src/lib/content-api.js` | Public content API, in-memory article cache, fallback data | Data fetching |
| `src/lib/admin-api.js` | Admin/writer CRUD API | Content management |
| `src/lib/engagement-api.js` | Comments, reactions, history, push, notifications, follows | Social features |
| `src/lib/seo.jsx` | Dynamic JSON-LD + meta injection | SEO optimization |
| `src/lib/TeknavCAP.jsx` | Custom CAPTCHA widget | Security UX |
| `src/components/QuoteSharer.jsx` | Canvas quote card generator | Social sharing |
| `src/components/lazy-diagram.jsx` | Lazy-loaded diagram renderer | Visual content |
| `src/widgets/` | Embeddable widgets (glossary, article, company) | Third-party embed |
| `src/embed.jsx` | Widget iframe bootstrapper | Second Vite entry |
| `public/embed-loader.js` | Third-party iframe injection script | Embed distribution |
| `vite.config.js` | Build config, proxy, code splitting | Build architecture |
---
## 22. COMPLETE COLOR REFERENCES (Every Hex)
```
#0F6B73 — Primary teal (brand, buttons, links, active states)
#0F2A2E — Dark teal (premium bg, headings, auth bg)
#C46A4D — Terracotta (login btn, auth accents, profile primary)
#C45C3D — Profile terracotta (dark variant for profile page)
#D49A2A — Gold (shimmer, badges, premium, brand panel)
#A8761B — Dark gold (gradient endpoint)
#C8951C — Auth gold (button gradient, brand accents)
#F4C36A — Light gold (gradient midpoint)
#2F8F6B — Green (success, published, positive)
#3A7D5E — Profile green
#FAF7F0 — Cream (body bg, splash bg)
#F4EFE6 — Dark cream (panels, secondary surfaces)
#E4DDD2 — Border line
#ebe3d2 — Sand (footer, stats bar)
#263238 — Ink (body text, headings)
#5F6B6D — Muted (secondary text)
#9AA5A6 — Muted light (hints, placeholders)
#C94C4C — Red (error, danger, delete)
#B8821E — Dark gold (premium btn gradient)
#20343A — Dark dossier badge bg
#7B8C8E — Muted teal (auth labels)
#1A2E30 — Dark auth input text
#0B2226 — Auth brand panel bg
#EDE9E2 — Auth tab bar bg
#F0EDE6 — Auth signup toggle bg
#E8E2D8 — Auth gold disabled bg
#B0B8BA — Auth gold disabled text
#E07A3A — Profile orange accent
#E8F4EF — Light green (expertise tags)
#A87A10 — Gold dark (writer role text)
#5566AA — Blue (reviewer role text)
#0C1E22 — Near black (comparison page headings, quote bg)
#0F3540 — Dark teal (verdict section bg, quote card bottom)
#131F22 — Code block bg
#1E3035 — Code block border
#2A4048 — Code copy btn border/hover
#A8D8DC — Code text
#6AACB5 — Code copy btn text
#4A7A82 - Code language label
#0A5060 - Inline code text
#1A3035 - Lead paragraph text
#0F2A2E08 — Footer section headings
#1A3A40 - Premium gate gradient end
#A8B8BA - Premium gate description
#D08A22 - Warning toast
#FF9D6C - Streak widget gradient start
#C46A4D - Streak widget gradient end
#1565C0 - Software category blue
#6A1B9A - Hardware category purple
#C62828 - Security category red
#FFF4D8 - Promoted content bg
#8A5A00 - Promoted content text
#2E7D32 - Comparison item1 green text
#E65100 - Comparison item2 orange text
#E8F5E9 - Comparison item1 green bg
#FFF3E0 - Comparison item2 orange bg
#F8F5F0 - Comparison use cases sand bg
#FFF8EA - Correction notice amber bg
#FFFCFB - OAuth btn hover bg
#0F3540 - Comparison verdict section
#C0392B - CVE critical score
#1A7A50 - CVE patched status
#FEF2F2 - Auth OAuth error bg
#991B1B - Auth OAuth error text
#FCA5A5 - Auth OAuth error border
#C4C8C9 - Auth footer text
#FAFAFA - TekRAG diagram card bg
#E8E8E8 - TekRAG diagram card border
#F8F5F0 - Company profile claim bg
#2A4045 - Push prompt border
#8AA5A8 - Push prompt subtitle
#C8D8DA - Premium gate feature text
#F5F5DC - Not used
#0F6B7318 — Teal at 18% opacity (category badge bg)
#0F6B7312 — Teal at 12% opacity (active filter chip bg)
#0F6B7308 — Teal at 8% opacity (light hover tints)
#0F6B7330 — Teal at 30% opacity (category badge border)
#0F6B7340 — Teal at 40% opacity (active saved btn border)
#D49A2A55 — Gold at 55% opacity (promoted content border)
#D49A2A40 — Gold at 40% opacity (premium gate border)
#D49A2A0A — Gold at 10% opacity (blockquote bg)
#D49A2A30 — Gold at 30% opacity (search highlight)
#C46A4D10 — Terracotta at 10% opacity (risk box bg)
#C46A4D35 — Terracotta at 35% opacity (risk box border)
#C94C4D0A — Red at 10% opacity (security alert bg)
#C94C4D30 — Red at 30% opacity (security alert border)
#C46A4D18 — Terracotta at 18% opacity
#0F6B7310 — Teal at 10% opacity (insight box bg)
#E4DDD230 — Border at 30% opacity (status badges)
#F4EFE680 — Cream at 80% opacity (comment reply bg)
```
---
## 23. NAVIGATION & ROUTING DESIGN
### 23.1 SPA Routing Implementation
**No React Router.** Custom SPA router via `NavProvider` context:
- Reads `window.location.pathname` as primary source
- Legacy fallback: `window.location.hash` (strips `#/` prefix, rewrites to pathname)
- Strips trailing slashes (except root `/`)
- Exposes `{ page, navigate }` via `useNav()` hook
- `navigate(to)`: calls `history.pushState(null, '', to)`, updates state, scrolls to top
- Listens to `popstate` and `hashchange` events
- `getCurrentPage()` always returns clean path + search string
### 23.2 All Routes (37 total)
| Route | Component | Notes |
|---|---|---|
| `/` | HomePage | Featured, latest, popular, categories, authors, newsletter |
| `/en` | EnglishHomePage | English landing |
| `/articles` | ArticleListPage | Filtered, paginated, searchable |
| `/article/:slug` | ArticleDetail | Full article reader |
| `/category/:slug` | CategoryPage | Category hero + filtered articles |
| `/tag/:tag` | TagPage | Tag-filtered articles |
| `/glossary/:slug` | GlossaryPage | Term definition |
| `/topics/:slug` | TopicHubPage | Topic hub with series/authors |
| `/series/:slug` | SeriesPage | Series article list |
| `/newsletter` | NewsletterArchivePage | Archived campaigns |
| `/newsletter/:slug` | NewsletterIssuePage | Single issue display |
| `/search` | SearchPage | Advanced search with sidebar filters |
| `/search?q=...` | SearchPage | Pre-filled query |
| `/authors` | AuthorsListPage | Author directory |
| `/author/:slug` | AuthorProfilePage | Redirects to `/profile/@:username` |
| `/profile/@:username` | UserProfilePage | Public profile |
| `/login` | LoginPage | Auth (login/signup) |
| `/admin` | AdminPanel | Full CMS |
| `/writer` | WriterWorkspace | Writer dashboard |
| `/privacy` | PrivacyPolicyPage | Legal |
| `/terms` | TermsOfUsePage | Legal |
| `/about` | AboutPage | Static |
| `/contact` | ContactPage | Contact form |
| `/compare` | ComparisonsListPage | Comparisons directory |
| `/compare/:slug` | ComparisonPage | Side-by-side comparison |
| `/stories` | StoriesListPage | Story cards grid |
| `/directory` | DirectoryListPage | Company directory |
| `/directory/:slug` | CompanyProfilePage | Company detail |
| `/tools` | ToolsPage | Tool listing |
| `/tools/nlp-normalizer` | NlpNormalizerPage | Client-side NLP tool |
| `/tools/rag-calculator` | RagCalculatorPage | RAG parameter calculator |
| `/tekrag-persian` | TekRagHubPage | Benchmark hub |
| `/jobs` | JobsPage | Job board |
| `/courses` | CoursesPage | Course catalog |
| `/membership` | MembershipPage | Premium subscription |
| `/membership/success` | MembershipSuccessPage | Post-payment |
Routes excluded from Header/Footer: `/admin`, `/login`, `/en`
### 23.3 Page Transition Flow
- All page transitions: instant (no router-level animation)
- Card-level entrance: IntersectionObserver-based staggered reveals
- Article list items: fadeIn + translateY with per-item delay
- Hero elements: sequential heroReveal with increasing delays (0.1s, 0.35s, 0.6s, 0.85s, 1.1s, 1.35s)
---
## 24. INTERACTIVE COMPONENT STATE DIAGRAMS
### 24.1 NotificationBell
```
States: idle → loading → open → reading → closed
- idle: bell icon, no unread count shown
- loading: fetching GET /api/v1/auth/notifications?limit=20 on mount
- unread count: badge shows "N" in red circle (overflow: "9+")
- open: dropdown panel (320px, white, 12px radius, shadow)
- reading: clicking item → marks read via PATCH → navigates to article
- live: EventSource SSE stream `/api/v1/auth/notifications/stream` pushes new notifications
- closed: clicking outside or toggling button
```
### 24.2 ReadingListModal
```
States: closed → loading → loaded → adding → done
- closed: hidden
- loading: SkeletonLoader 3 lines during GET /api/v1/auth/lists
- loaded: list of reading list cards (white bg, 1px border, 10px radius)
- adding: POST to add article to list → toast "به لیست اضافه شد"
- create: form at bottom to create new list + auto-add
- done: modal closes via onDone callback
```
### 24.3 StreakWidget
```
States: hidden (no user/no streak) → visible
- null/0 streak: returns null (hidden)
- streak > 0: gradient orange card with fire emoji
- "N روز مطالعه متوالی!" in bold, "به یادگیری ادامه دهید" subtitle
- float-y animation infinite
- boxShadow 0 4px 15px rgba(196,106,77,0.3)
```
### 24.4 ContinueReadingBar
```
States: hidden → visible
- null/empty continueReading: returns null
- populated: dark bar (#263238) with horizontal scroll of in-progress articles
- each article: title (truncated) + 2px progress bar (teal fill on dark track)
- label "ادامه مطالعه:" in orange (#FF9D6C)
- clicking navigates to article
```
### 24.5 Article Reactions
```
States: idle → active (per reaction type)
- idle: button bg #F4EFE6, text #263238, border #E4DDD2
- active: bg #0F6B7318, text #0F6B73, border #0F6B7340
- toggle: POST /api/v1/articles/:id/reactions → res.active boolean
- 5 types: helpful, star, heart, fire, thinking (Persian) / helpful, excellent, valuable, important, thought-provoking (English)
- toast confirmation on each toggle
```
### 24.6 Article Save
```
States: unsaved → saved → list-modal
- unsaved: ⊕ ذخیره, bg #F4EFE6
- saved: ✓ ذخیره‌شده, bg #0F6B7318, text #0F6B73
- toggle: POST /api/v1/articles/:id/save → sets listModalOpen true
- English: Save / Saved
```
### 24.7 Comment Upvote & Like
```
Comment upvote:
- idle: ▲ N, bg #F4EFE6
- active: ▲ N, bg #0F6B7318, color #0F6B73, border #0F6B7340
- POST /api/v1/comments/:id/upvote → res.upvoted + res.upvoteCount
Comment like:
- idle: transparent bg, #5F6B6D text
- active: bg #0F6B7318, color #0F6B73, border #0F6B7330
- POST /api/v1/comments/:id/like → res.liked + res.likeCount
```
### 24.8 Follow Writer
```
States: idle → following
- idle: "دنبال کردن" button, terracotta bg 8%, terracotta border
- following: "دنبال می‌کنی", green bg, green text, green border
- toggle: POST/DELETE /api/v1/writers/:username/follow
- count updates in UI
```
### 24.9 Comment Flag
```
States: idle → flagged
- click → POST /api/v1/comments/:id/flag
- toast "گزارش نظر ثبت شد"
- requires authentication
- triggers comment list refresh
```
### 24.10 Push Notification Toggle (Profile)
```
States: disabled → enabled → blocked
- disabled: show "فعال‌سازی" button (green bg)
- enabled: show "غیرفعال‌سازی" button (white bg, terracotta text)
- blocked: show info message (notification permission denied)
- transition: requestPermission → PushManager.subscribe → POST /api/v1/auth/push/subscribe
```
### 24.11 OAuth Flow
```
States: start → redirect → callback → error/success
1. Click "ادامه با Google/GitHub"
2. `window.location.href = /api/v1/auth/oauth/{provider}/start`
3. Backend redirects to OAuth provider
4. Callback returns with hash fragment: `#?error={code}` or successful session
5. Error: shown in red box with specific message
6. Success: page reloads with authenticated user
```
---
## 25. FORM DESIGN DETAILS
### 25.1 Login Form Complete
```
Layout (top to bottom):
1. Identifier input (email or @username)
- label: "نام کاربری یا ایمیل" (12px, 600, #7B8C8E)
- placeholder: "@username یا you@example.com"
- inputProps: { type: 'text', autocomplete: 'username', style: { direction: 'ltr', textAlign: 'left' } }
2. Password input
- label: "رمز عبور" (same style)
- "فراموشی رمز؟" link (right-aligned, 12px, underline, #9AA5A6, hover #C46A4D)
- placeholder: "••••••••"
- suffix: EyeIcon toggle (16x16 SVG, #9AA5A6)
- autoComplete: 'current-password'
3. TeknavCAP captcha widget
- onChange callback sets { captchaId, userSolution }
4. Submit button
- goldBtn style (full-width, gold gradient, 13px padding, 10px radius)
- Text: "ورود به حساب"
- Loading: spinner (14px circle, 2px border, spin animation) + "در حال ورود..."
- Disabled: opacity-based
5. Switch prompt
- "حساب ندارید؟ ثبت‌نام کنید"
- "ثبت‌نام کنید" is a link-style button (#C46A4D, underline, hover #C8951C)
```
### 25.2 Signup Form Complete
```
Layout (top to bottom):
1. Name input
- label: "نام نمایشی"
- placeholder: "مثال: علی رضایی"
- autoComplete: 'name'
2. Username input
- label: "نام کاربری"
- hint: "فقط حروف لاتین، عدد، نقطه و زیرخط" / shows "@username" preview
- placeholder: "ali_rezaei"
- auto-lowercase, strips @ prefix
- LTR direction
3. Identifier toggle + input
- Toggle: pill UI (#F0EDE6 bg, 8px radius, 3px padding)
- "ایمیل" (active: white bg, shadow)
- "موبایل" (active: white bg, shadow)
- Email: type='email', placeholder "you@example.com"
- Phone: type='tel', placeholder "09123456789"
4. Password input
- label: "رمز عبور"
- placeholder: "••••••••"
- EyeIcon toggle
- autoComplete: 'new-password'
- PasswordStrength component shown when password non-empty
5. Confirm password input
- label: "تکرار رمز عبور"
- placeholder: "••••••••"
- Error when mismatch: "رمزها تطابق ندارند" (#C94C4C)
- Suffix checkmark when match (SVG polyline, #2F8F6B)
6. TeknavCAP captcha
7. Terms acceptance text
- "با ثبت‌نام، شرایط استفاده و سیاست حریم خصوصی تکناو را می‌پذیرید."
- Terms/privacy links: #C46A4D, underline
8. Submit button
- goldBtn style
- Text: "ایجاد حساب کاربری"
- Loading: spinner + "در حال ثبت‌نام..."
```
### 25.3 Forgot Password Modal Form
```
1. Email input (LTR, direction ltr)
- label: "ایمیل"
- placeholder: "you@example.com"
2. Action buttons
- "انصراف" (cancelBtn style: border 1.5px #E4DDD2, transparent bg, #7B8C8E)
- "ارسال لینک" (goldBtn style, flex:1)
- Loading: disabled with "…"
3. Sent state
- Message: "اگر این ایمیل در سیستم ثبت شده باشد، لینک بازنشانی برای شما ارسال خواهد شد."
- CTA: "بستن" (goldBtn)
```
### 25.4 CAPTCHA (TeknavCAP)
- Custom CAPTCHA widget (not reCAPTCHA)
- Imported from `src/lib/TeknavCAP.jsx`
- Usage pattern: `<TeknavCAP onChange={setCaptcha} />`
- Callback receives `{ captchaId, userSolution }`
### 25.5 Contact Form (teknav-pages.jsx)
- Uses raw contact-form handling; no backend contact route is currently registered in `backend/src/routes/`
- Not a component exported from teknav-ui — embedded within ContactPage
### 25.6 Job Submission Form (teknav-pages.jsx)
- `contentApi.submitJob(payload)` — POST /api/v1/jobs
- Used within JobsPage component
### 25.7 Newsletter Subscription Form
```
States: idle → submitting → done
- idle: email input + CAPTCHA + submit button
- submitting: validation checks (email format, captcha) → contentApi.subscribeNewsletter()
- done: checkmark + "عضویت شما ثبت شد!" + "جدیدترین مقاله‌های تکناو را در ایمیل دریافت خواهید کرد."
Error states:
- Invalid email: "لطفاً یک ایمیل معتبر وارد کنید"
- No captcha: "لطفاً کد امنیتی را وارد کنید"
- 429: "تعداد درخواست‌ها از حد مجاز گذشت"
- 400: "کد امنیتی نامعتبر است"
- Generic: "خطا در ثبت عضویت خبرنامه"
- Already subscribed: "این ایمیل قبلاً ثبت شده است" (warning toast)
```
---
## 26. ADMIN PANEL DESIGN (src/admin/index.js)
### 26.1 Overview
- Re-exported from `teknav-admin.jsx` via `export { AdminPanel, WriterWorkspace, actionBtn } from './src/admin/index.js'`
- Hidden from Header/Footer (excluded via `isAdmin` check)
- Role-based access: admin, editor, writer, reviewer
- All data from backend API only (no mock data)
### 26.2 Notable Features (from Phase 9/10 context)
- Article editor with SEO fields (title, metaDescription, keywords, ogTitle, ogDescription)
- Comparison article template
- Correction submission workflow
- Verified author management
- Review workflow (approval/revision/rejection)
- Newsletter campaign builder
- Article series management
- Media library with upload
- Analytics dashboards (writer, editor, admin)
---
## 27. TOOLS PAGES DESIGN
### 27.1 ToolsPage
- Tool listing with cards
- Links to `/tools/nlp-normalizer` and `/tools/rag-calculator`
### 27.2 NlpNormalizerPage
- Client-side Persian text normalization tool
- No server API calls — pure JavaScript processing
- Input text area → normalized output
### 27.3 RagCalculatorPage
- RAG (Retrieval-Augmented Generation) parameter calculator
- Chunk size, overlap, token simulation
- Client-side numeric computation
### 27.4 TekRagHubPage
- Academic benchmark hub for Persian RAG evaluation
- Links to HuggingFace, Zenodo, GitHub
- Citation information
- Static content from TeknavData + TekRAG article
---
## 28. NEWSLETTER ARCHIVE & ISSUE PAGES
### 28.1 NewsletterArchivePage
- Lists all past newsletter campaigns
- Each item: title + date + preview
- Click navigates to `/newsletter/:slug`
### 28.2 NewsletterIssuePage
- Renders newsletter HTML body
- Full content display (not truncated)
---
## 29. JOBS & COURSES PAGES
### 29.1 JobsPage
- Job listing fetched from `contentApi.listJobs()`
- Job submission form via `contentApi.submitJob()`
- Each job card: title, company, location, type, description
### 29.2 CoursesPage
- Course catalog from `contentApi.listCourses()`
- Cards with course title, instructor, duration, description
### 29.3 MembershipPage
- Premium subscription/payment page
- API calls: raw `fetch('/api/v1/membership/*')`
---
## 30. COMMENT SYSTEM DESIGN
### 30.1 Comment List
- Threaded comments: parent + replies with indentation
- Each comment: white bg card, 10px radius, 14px padding, 1px #E4DDD2
- Header: author name (#0F6B73 if clickable, #263238 if not) + @username + time
- Actions: upvote ▲ N, report, like/reply buttons
- Replies: bg #FAF7F0, 2px #E4DDD2 right border, 0 8px 8px 0 radius
### 30.2 Comment Form
- Textarea (min-height 90px, resizable vertical) + character counter N/1000
- Submit: pillBtn teal bg
- Reply state: shows "پاسخ به {name}" with cancel button (#C94C4C)
- Unauthenticated: info box "برای نظر دادن وارد شوید." (#F4EFE6 bg)
### 30.3 Q&A Section
- Similar structure to comments
- Questions listed with answer thread
- Reply button per question
- Answered questions have indented answer cards
### 30.4 Comment Moderation (Admin)
- Bulk moderation via admin API
- Flag/unflag, delete, approve
- Flagged comments listing
---
## 31. READING LIST SYSTEM
### 31.1 Reading List Modal
- Article-level access via bookmark button
- Lists all user's reading lists
- Create new list inline
- Add article to existing list
- Auto-add to new list on creation
### 31.2 Reading List CRUD (Backend API)
- GET /api/v1/auth/lists — list all
- POST /api/v1/auth/lists — create
- DELETE /api/v1/auth/lists/:id — delete
- POST /api/v1/auth/lists/:id/items — add article
- DELETE /api/v1/auth/lists/:id/items/:itemId — remove
- PUT /api/v1/auth/lists/:id/reorder — reorder items
---
## 32. FOLLOW SYSTEM
### 32.1 Writer Follows
- Follow/unfollow toggle on profile page
- Button state: "دنبال کردن" (terracotta outline) / "دنبال می‌کنی" (green filled)
- Follower count display
- Following list on own profile
### 32.2 Topic Follows
- Topic hubs have follow/unfollow toggle
- `POST /api/v1/topics/:slug/follow`
- `DELETE /api/v1/topics/:slug/follow`
- Guest push notification subscription per topic
### 32.3 Following List (Profile)
- Shown on own profile page
- List of followed writers with name + @username
- Click navigates to writer's profile
---
## 33. READING HISTORY
### 33.1 History Recording
- Scroll-based: on article detail page, listens to scroll
- Triggers at >5% scroll progress
- POST /api/v1/auth/history with articleId + progress (0–1 ratio)
- Recorded once per scroll event
### 33.2 History Display (Profile)
- Own profile: shows last 5 items in sidebar
- Each item: article title (truncated) + time
- "پاک کردن تاریخچه" button with confirm dialog
- DELETE /api/v1/auth/history to clear all
---
## 34. NOTIFICATION SYSTEM
### 34.1 Notification Types
| Type | Trigger | Display Text |
|---|---|---|
| `comment` | User comments on your article | "{name} برای مقاله شما نظر گذاشت" |
| `comment_reply` | User replies to your comment | "{name} به نظر شما پاسخ داد" |
| `new_article` | Writer you follow publishes | "مقاله تازه از {name}" |
| `review_approved` | Editor approves revision | UI-specific |
| `review_revision` | Editor requests revision | UI-specific |
| `review_rejected` | Editor rejects article | UI-specific |
| `review_submitted` | Writer submits for review | UI-specific |
| `system` | System notifications | UI-specific |
### 34.2 Notification Display
- Bell icon in header with unread count badge
- Dropdown: max 20 items, scrollable
- Unread items: bg #F4EFE6, weight 900
- Read items: bg #fff, weight 600
- All items: title + article title (payload)
- "خواندن همه" button marks all read
- Empty state: "اعلانی وجود ندارد."
### 34.3 Live Notifications
- EventSource SSE: `/api/v1/auth/notifications/stream`
- Pushes new notifications in real-time
- Reconnects on error (automatic EventSource behavior)
### 34.4 Notification Preferences
- Per-event-type + per-channel (push, email, SMS)
- Toggle UI: 28×16px pill switches
- Green (#3A7D5E) for enabled, #CCC for disabled
---
## 35. SEO & META DESIGN
### 35.1 SeoManager Component
- Returns null (no visible output)
- Injects meta tags, JSON-LD, link tags into `<head>`
- Re-runs on route change via `useNav().page`
- Fetches page data async with static fallback
### 35.2 JSON-LD Schemas
| Schema type | Page types | Key fields |
|---|---|---|
| Organization / NewsMediaOrganization | Global | name, url, logo, sameAs, contactPoint |
| WebSite | Global | name, url, inLanguage, searchAction |
| NewsArticle / TechArticle / ScholarlyArticle | Article detail | headline, datePublished, dateModified, author, image, wordCount, timeRequired |
| CollectionPage | Category, Tag, Topic, Series, Author archive | name, description, numberOfItems |
| ProfilePage | Author / @username profile | mainEntity (Person) |
| Person | Author, article author | name, knowsAbout, alumniOf, credential, interactionStatistic |
| BreadcrumbList | All content pages | itemListElement (home → section → page) |
| ItemList | Tagged/topic article lists | itemListElement (up to 15 articles) |
| DefinedTerm | Glossary pages | name, description, sameAs (wikidata) |
| FAQPage | Articles with FAQs, glossary, topic hubs | mainEntity (Question/Answer) |
| CreativeWork | Benchmark articles | identifier, version, citationUrls, researchQuestions |
| ImageObject | Logo, article images | url, width, height |
| SpeakableSpecification | Article, WebPage | xpath for title/description |
### 35.3 Meta Tags
| Tag | Pattern |
|---|---|
| `description` | Category/article/author description |
| `keywords` | Article keywords or category keywords |
| `robots` | `index,follow,max-image-preview:large` |
| `canonical` | Full URL with www |
| `alternate hreflang` | fa-IR |
| `og:locale` | fa_IR |
| `og:type` | article / website |
| `og:title` | Page title |
| `og:description` | Page description |
| `og:url` | Full canonical URL |
| `og:image` | /images/og/{slug}.jpg or default |
| `og:image:width/height` | 1200 / 630 |
| `twitter:card` | summary_large_image |
| `twitter:title/description/image` | Same as OG |
### 35.4 Academic Citation Meta
For scholarly articles (TekRAG benchmark):
- `citation_title`, `citation_author`, `citation_publication_date`
- `citation_online_date`, `citation_pdf_url`
---
## 36. ENGAGEMENT ANALYTICS
### 36.1 Tracked Events
- Share clicks: `POST /api/v1/analytics/events` with `{ type: 'share_clicked', articleId, topic, metadata: { channel } }`
- Channels: telegram, whatsapp, x, linkedin, copy, quote_card (via QuoteSharer)
### 36.2 Writer Analytics
- Overview: total views, reactions, comments
- 30-day views sparkline (date + view count pairs)
- Per-article table: title, views, reactions, comments, saved
- Separate endpoint for overview vs per-article data
### 36.3 Article View Tracking
- `contentApi.trackEvent()` for custom events
- Reading progress recorded via history API
- Scroll depth tracked as continuous progress (0–1)
---
## 37. ERROR TRACKING (Self-hosted)
### 37.1 Client Error Capture
- `window.onerror` + `window.onunhandledrejection` listeners in InnerApp
- Payload: `{ message, source, stack, path, userAgent }`
- Sent via `navigator.sendBeacon('/api/v1/errors', ...)` or `fetch POST /api/v1/errors`
- Uses `keepalive: true` for reliability during page unload
### 37.2 Admin Error Viewing
- `adminApi.getClientErrors()` — list captured errors
- Available in admin dashboard
---
## 38. CDN & ASSET CONSTRAINTS
### 38.1 Zero CDN Policy
- All fonts: self-hosted at `/fonts/Vazirmatn-*.ttf` and `/fonts/PelakFA-*.woff`
- All icons: local SVG files in `src/assets/icons/`
- All images: generated at build time into `dist/` (OG images, article pages)
- Build script rejects any CDN URL in `dist/`
### 38.2 Build-time Asset Pipeline
```
seo:sitemap → og:images → vite build → check-no-cdn → check-responsive
→ generate-article-pages → generate-web-stories → generate-comparison-pages
→ generate-company-pages → generate-en-page → generate-author-pages
→ generate-semantic-pages → compress-dist
```
### 38.3 SVG Inline Policy
- SVGs under `src/assets/icons/` are never base64-inlined
- Custom `assetsInlineLimit` function returns `false` for icons directory
- Ensures CSS `mask` property works with real file URLs
### 38.4 Code Splitting
- Vendor chunks: vendor-react, vendor-three, vendor-d3, vendor
- Separate entry: `embed.html` for widget iframes
- Lazy-loaded: `LazyDiagram` component via React.lazy
---
## 39. COMPLETE NAV ITEM SPECIFICATION
### 39.1 Desktop Header Nav (9 items)
Order (left to right in RTL — visually displayed right to left):
| # | Label | Path | Active State Color | Weight |
|---|---|---|---|---|
| 1 | خانه | / | #0F6B73 | 700 |
| 2 | هوش مصنوعی | /category/ai | #0F6B73 | 700 |
| 3 | علم داده | /category/data | #0F6B73 | 700 |
| 4 | استارتاپ | /category/startup | #0F6B73 | 700 |
| 5 | امنیت | /category/security | #0F6B73 | 700 |
| 6 | سخت‌افزار | /category/hardware | #0F6B73 | 700 |
| 7 | نرم‌افزار | /category/software | #0F6B73 | 700 |
| 8 | آینده فناوری | /category/future | #0F6B73 | 700 |
| 9 | نویسندگان | /authors | #0F6B73 | 700 |
Inactive: color #263238, weight 400
### 39.2 Mobile Drawer Nav (9 items + auth)
- Same items stacked vertically
- Additional: auth buttons at bottom (profile, admin, logout OR login)
### 39.3 Footer Link Sections
**Categories (5):**
1. هوش مصنوعی
2. علم داده
3. امنیت سایبری
4. سخت‌افزار
5. نرم‌افزار
**Tools (5):**
1. مقایسه‌های فنی → /compare
2. استوری‌ها → /stories
3. دایرکتوری شرکت‌ها → /directory
4. واژگان تخصصی → /glossary/ai
5. ابزارهای تکناو → /tools
**Teknav (5):**
1. درباره ما → /about
2. تیم نویسندگان → /authors
3. قوانین حریم خصوصی → /privacy
4. شرایط استفاده → /terms
5. تماس با ما → /contact
### 39.4 Social Links (Footer)
- توییتر (Twitter/X)
- لینکدین (LinkedIn)
- تلگرام (Telegram)
Hover: background fill #0F6B73, text white, translateY(-2px)
---
## 40. HTML ELEMENT REFERENCE
### 40.1 Inline Style Element Injection
Multiple components inject `<style>` tags for scoped CSS:
- `teknav-ui.jsx` Header: nav responsiveness, animations, scrollbar styling
- `teknav-home.jsx`: heroReveal keyframe, responsive grid overrides
- `teknav-articles.jsx`: article CSS (~100 lines), TOC responsive, TekRAG overrides
- `teknav-auth.jsx`: AuthStyles component (~60 lines)
- `teknav-pages.jsx`: search layout responsive
- `teknav-profile.jsx`: profile responsive
### 40.2 Dynamic Head Injection (SeoManager)
- Direct DOM manipulation: `document.querySelector('head')` append/remove
- Meta tags: create/update via `document.querySelector('meta[name="..."]')`
- JSON-LD: create/remove `<script type="application/ld+json">`
- Link tags: canonical, alternate, RSS
- HTML attributes: `lang`, `dir` on `<html>`
### 40.3 IntersectionObserver Usage
Used in 7 locations:
1. Homepage ArticleCard: stagger entry animation (threshold 0.1)
2. Homepage CountUp: trigger counter animation (threshold 0.4)
3. ArticleRow: stagger entry (threshold 0.05)
4. TableOfContents: active heading tracking (rootMargin -20% 0% -70% 0%)
5. useViewportPrefetch: prefetch article data (rootMargin 100px)
6. GlossaryPage: similar card animation
7. SearchPage results: fade-in staggered
---
## 41. TEXT DIRECTION & LOCALIZATION
### 41.1 RTL Conventions
- `direction: rtl` on all major containers
- `text-align: right` for body text
- `padding-right` / `padding-left` for list bullets
- `border-right` for blockquotes, accent bars
- `marginInlineStart` / `marginInlineEnd` for logical properties
- `insetInlineEnd` for absolute positioning
- Footer hover: `transformOrigin: 'right'`, `translateX(-4px)` (moves left = forward in RTL)
- Breadcrumb: right-to-left order (Home › Section › Page)
- Share buttons: `borderInlineStart` for left separator
- Auth form: `padding-right` for vertical accent bar
### 41.2 LTR Overrides
- Code blocks: force LTR
- English text spans: `.ltr` class with `unicode-bidi: isolate`
- TekRAG article: entire page LTR
- Email/URL/username inputs: LTR with left alignment
- Numbers: always LTR-safe (Persian digit formatting via locale)
### 41.3 Mixed Content
- Persian articles may contain English terms, code, URLs
- English terms rendered inline via `unicode-bidi: isolate`
- Code blocks always LTR regardless of article direction
---
## 42. PERSIAN DIGIT FORMATTING
### 42.1 Conversion Pattern
```javascript
// Persian digit mapping
'۰۱۲۳۴۵۶۷۸۹'[d] // for each digit character
// Full formatting
toLocaleString('fa-IR')
→ adds Persian digits
→ adds Persian thousands separator (٬)
→ adds Persian decimal separator (/)
```
### 42.2 Usage Locations
- Article view counts
- Comment counts
- Reaction counts
- Stats bar numbers
- Profile analytics numbers
- Search result counts
- Category article counts
- Reading time
- Unread notification badge
---
## 43. BUILD & DEVELOPMENT CONFIGURATION
### 43.1 Vite Dev Server
- Port: 3009
- Host: 0.0.0.0
- Strict port
- Proxy: `/api` → `http://localhost:3010` (Fastify backend)
### 43.2 Vite Build
- Target: es2020
- Sourcemaps: true
- CSS code split: true
- Manual chunks: vendor-react, vendor-three, vendor-d3, vendor
- Two entry points: `index.html` (SPA) + `embed.html` (widgets)
- Output: `dist/` directory
### 43.3 Preview Server
- Port: 4173 (Vite default preview)
- Host: 0.0.0.0
### 43.4 Environment Variables
- `VITE_API_BASE` — override API base URL (e.g., `http://localhost:3010` in dev)
---
## 44. DATA FLOW DESIGN PATTERNS
### 44.1 Fallback Architecture
```
App renders → use seed data (TeknavData) as initial state
→ fetch API data in useEffect
→ on success: replace state with API data
→ on failure: keep seed data (silent)
→ loading state: use SkeletonLoader
```
### 44.2 Caching Strategy
- In-memory: `articleCache` Map in `content-api.js` for `getArticle(slug)`
- First call: fetch + store in Map
- Subsequent calls: return cached value
- LocalStorage: `teknav-store.js` for legacy data (version-checked, auto-purge)
- No Service Worker article cache mentioned beyond push notifications
### 44.3 Optimistic Updates
- Comment upvote/like: immediately flip UI state, let API confirm
- Follow/unfollow: update UI immediately, revert on error
- Article save: toggle UI immediately
---
## 45. RESPONSIVE IMAGE & DIAGRAM BEHAVIOR
### 45.1 Diagram Scaling
- Homepage cards: 0.7 scale
- Article list rows: 0.5 scale
- Full article: 1.0 scale (full-size interactive)
- Mobile: overflow-x auto for wide diagrams
### 45.2 Image Loading
- `loading="lazy"` for story images, OG images
- `loading="eager"` for hero discover image
- `fetchPriority="high"` for hero/hero images
- `decoding="async"` for all images
### 45.3 Aspect Ratios
- OG images: 1200×630 (≈1.9:1)
- Discover hero: 1200/630 aspect-ratio via `aspectRatio: '1200 / 630'`
- Story cards: padding-bottom 177% (9:16 portrait)
- Quote card: 1080×1080 (1:1 square)
---
## 46. COMPONENT SIZE SPECIFICATIONS
### 46.1 Fixed Dimensions
| Element | Width | Height | Notes |
|---|---|---|---|
| Header | 100% | 64px (desktop), 56px (mobile) | Fixed/sticky |
| Footer | 100% | auto | Padding 56px 24px 28px |
| Reading progress | 100% | 3px | Fixed top:64px |
| Article card thumbnail | 100% | 120px | Overflow hidden |
| Article row thumbnail | 140px | 120px | Fixed aspect |
| Compact row thumbnail | 80px | 80px | Fixed square |
| Avatar (article) | 40px | 40px | Circle |
| Avatar (featured) | 36px | 36px | Circle |
| Avatar (author section) | 56px | 56px | Circle |
| Avatar (article author box) | 64px | 64px | Circle |
| Avatar (profile page) | 110px | 110px | Circle |
| AuthorAvatar default | 40px | 40px | Configurable via size prop |
| Streak widget | auto | auto | 8px 14px padding |
| Toast container | auto | auto | Fixed bottom:28 left:24 |
| Notification badge | min 17px | 17px | Red circle |
| Loading bar | 40px | 3px | Splash screen |
| Verification status dot | 6px | 6px | Circle |
| Login/Register btn | auto | auto | 8px 18px padding |
| Scrollbar | 6px | 6px | Both axes |
### 46.2 Minimum Dimensions
| Element | Min | Notes |
|---|---|---|
| Search input | 200px | Newsletter form |
| Comparison card | 300px | flex-basis |
| Use case card | 280px | flex-basis |
| Article content | 760px max | No minimum |
| Auth form content | 420px max | No minimum |
| Category diagram | 320px | flex-basis |
| Mobile drawer | 280px / 84vw | Which is smaller |
---
## 47. CARD & PANEL BACKGROUND VARIATIONS
| Surface | Background | Border | Radius | Usage |
|---|---|---|---|---|
| White card | `#fff` | 1px `#E4DDD2` | 12px | ArticleCard, category cards, comment cards |
| Cream panel | `#F4EFE6` | none | 0 | Stats bar, article breadcrumb, search filter bar |
| Sand panel | `#ebe3d2` | none | 0 | Footer, newsletter box |
| Light sidebar card | `#fff` | 1px `#E4DDD2` | 16px | Hero featured card |
| Diagram container | `#F4EFE6` | none | 8/12px | Thumbnails, hero diagram |
| Insight box | `#0F6B7310` | 1px `#0F6B7330` | 10px | Article content callouts |
| Risk box | `#C46A4D10` | 1px `#C46A4D35` | 12px | Article risk warnings |
| Code block | `#131F22` | 1px `#1E3035` | 10px | Code examples |
| Correction notice | `#FFF8EA` | 1px `#D49A2A55` | 12px | Article corrections |
| Security alert | `#C94C4D0A` | 1px `#C94C4D30` | 0/10px | Security warnings |
| Premium gate | `#0F2A2E`→`#1A3A40` | 1px `#D49A2A40` | 16px | Gated content |
| Verdict section | `#0F3540` | none | 12px | Comparison verdict |
| Use cases panel | `#F8F5F0` | none | 12px | Comparison use cases |
| Company profile | `#0C1E22` | none | 16px | Company header |
| Notification dropdown | `#fff` | 1px `#E4DDD2` | 12px | Notification bell |
| Quote tooltip | `#0F3540` | 1px `#D49A2A` | 8px | Quote sharer |
| Series banner | `#0F6B7308` | 1px `#0F6B7330` | 10px | Article series nav |
| CVE summary | `#EEF6F7`→`#E8F3F4` | 1px `rgba(15,107,115,0.18)` | 12px | CVE data cards |
| Profile analytics card | `#fff` | 1px `#E4DDD2` | 12px | Profile summary cards |
| Own profile grid | `#fff` | 1px `#E4DDD2` | 12px | History + following |
| Comparison card | `#fff` | 1px `#E4DDD2` | 12px | Side-by-side compare |
| Story card overlay | gradient black→transparent | none | 0 | Bottom gradient on story images |
| Bubble word | `rgba(250,247,240,0.07)` border | 20px radius | Auth brand panel |
---
## 48. LOADING STATES (Per Component)
| Component | Loading UI | Error UI | Empty UI |
|---|---|---|---|
| ArticleListPage | SkeletonLoader | Seed data fallback | EmptyState |
| ArticleDetail | Seed data initially | EmptyState + return btn | N/A |
| CategoryPage | Seed data initially | EmptyState | EmptyState |
| SearchPage | SkeletonLoader 5 lines | EmptyState | EmptyState "نتیجه‌ای یافت نشد" |
| Comments | "در حال بارگذاری نظرها..." | EmptyState | EmptyState "هنوز نظری ثبت نشده است" |
| Q&A | "در حال بارگذاری..." | Toast error | "هنوز پرسشی ثبت نشده است" |
| Profile | "در حال بارگذاری…" | EmptyState | EmptyState |
| NotificationBell | No loading state | Empty dropdown | "اعلانی وجود ندارد" |
| Reading lists | SkeletonLoader 3 lines | Toast error | Empty list (no text) |
| NewsletterForm | Submit button spinner | Toast error | N/A |
| Auth forms | Button spinner | Toast error | N/A |
| ForgotPassword | Button spinner | Toast error | Sent state message |
| GlossaryWidget | Static data only | N/A | N/A (slug lookup) |
| ArticleCardWidget | Static data only | N/A | N/A |
| CompanyWidget | SkeletonLoader | Empty/not-found state | Empty/not-found state |
| MembershipPage | Button opacity 0.7 | Toast error | Non-logged-in redirect |
| MembershipSuccessPage | None (static) | N/A | N/A |
| NewsletterArchivePage | "در حال بارگذاری..." | Silent fail | EmptyState |
| NewsletterIssuePage | "در حال بارگذاری..." | EmptyState | EmptyState |
| SeriesPage | "در حال بارگذاری..." | EmptyState | EmptyState |
| JobsPage | None (initial []) | Silent fail | EmptyState |
| CoursesPage | None (initial []) | Silent fail | Empty grid |
| ContactPage | Button text change | Toast | Sent state card |
| NLP Normalizer | None (client-side) | N/A | N/A (always rendered) |
| RAG Calculator | None (client-side) | N/A | "هنوز نتیجه‌ای محاسبه نشده" (implicit) |
| Topics/Hubs | Static data | Silent fail | EmptyState |
| Glossary detail | Static data | EmptyState | EmptyState |
| Admin Dashboard | PanelState loading | PanelState error | PanelState empty |
| Admin ArticleList | PanelState loading | PanelState error | EmptyState "موردی مطابق فیلترها یافت نشد" |
| Admin ArticleEditor | N/A (form) | Validation errors | N/A |
| Admin Comments | PanelState loading | PanelState error | PanelState empty |
| Admin Users | PanelState loading | PanelState error | PanelState empty |
| Admin Media | PanelState loading | PanelState error | PanelState empty |
| Admin Categories | PanelState loading | PanelState error | PanelState empty |
| Admin Tags | PanelState loading | PanelState error | PanelState empty |
| Admin Analytics | PanelState loading | PanelState error | "هنوز داده‌ای ثبت نشده" |
| Admin Reviews | PanelState loading | PanelState error | "در انتظار بررسی نیست" |
| Admin Newsletter | PanelState loading | PanelState error | PanelState empty |
| Admin Series | PanelState loading | PanelState error | PanelState empty |
| Admin Jobs | PanelState loading | PanelState error | PanelState empty |
| Admin SEO Audit | PanelState loading | PanelState error | "مشکلی یافت نشد" |
| RevisionDrawer | "در حال بارگذاری…" | N/A (close button) | "هنوز نسخه‌ای ذخیره نشده است" |
| ArtifactStudio | N/A (toolbar) | Upload error message | "هنوز دیاگرامی انتخاب نشده" (preview empty) |
```
---
## 49. ADMIN PANEL COMPLETE DESIGN
### 49.1 Admin Sidebar (AdminDashboard)
**Background:** `linear-gradient(180deg, #073F45 0%, #0F6B73 52%, #0A3136 100%)`
**Width:** 256px (fixed)
**Padding:** 22px 0
**Box shadow:** `-14px 0 40px rgba(15,42,46,0.16)`
**Min height:** 100%
**Logo area:** padding `0 22px 22px`, border-bottom `1px solid rgba(250,247,240,0.14)`
- "تکناو": font-size `24px`, font-weight `900`, color `#fff`, font-family `PelakFA,Vazirmatn`
- "پنل تولید محتوا": font-size `12px`, color `rgba(255,255,255,0.72)`
**Nav items:** padding `18px 12px`, flex: 1
- Each button: flex, align-items center, gap `12px`, width `100%`, text-align right, padding `12px 14px`, margin-bottom `6px`, border-radius `12px`
- Active: background `rgba(250,247,240,0.96)`, border `1px solid rgba(250,247,240,0.95)`, color `#0F6B73`, font-weight `800`, box-shadow `0 12px 28px rgba(0,0,0,0.18)`
- Inactive: background transparent, color `rgba(255,255,255,0.74)`, font-weight `600`
- Font: `13px`, Vazirmatn
- Icon container: `15px`, `26x26px`, border-radius `8px`, inline-flex
- Active bg: `#0F6B73` + `14` opacity
- Inactive bg: `rgba(255,255,255,0.10)`
**User footer:** padding `16px 20px`, border-top `1px solid rgba(250,247,240,0.14)`
- Name: `12px`, color `rgba(255,255,255,0.72)`
- RoleBadge component
### 49.2 Admin Topbar (AdminPanel)
**Background:** `rgba(250,247,240,0.86)`
**Backdrop filter:** `blur(14px)`
**Border bottom:** `1px solid #E4DDD2`
**Padding:** `0 28px`
**Min height:** `64px`
**Flex:** space-between, align-items center
**Left side:**
- Mobile hamburger: `background: none; border: 1px solid #E4DDD2; borderRadius: 8; padding: 6px 10px; cursor: pointer; fontSize: 18; color: #0F2A2E`
- Title: `fontSize: 14; fontWeight: 800; color: #0F2A2E`
- Subtitle: `fontSize: 11; color: #5F6B6D; marginTop: 2`
**Right side buttons:**
- "مقاله جدید": pillBtn + background `#0F6B73`, color `#fff`, fontSize `12`
- "بازگشت به سایت": pillBtn + background `#0F6B73`+12 opacity, color `#0F6B73`, fontSize `12`
- "خروج": pillBtn + background `#C94C4C18`, color `#C94C4C`, fontSize `12`
### 49.3 Admin Panel Main Layout
**Outer container:** `minHeight: 100vh; display: flex; background: linear-gradient(135deg, #FAF7F0 0%, #F3EEE4 100%); fontFamily: Vazirmatn,sans-serif; direction: rtl`
**Content area:** `flex: 1; padding: 30px clamp(18px, 3vw, 38px); overflowY: auto`
**Section heading:** `fontSize: 22; fontWeight: 900; color: #0F2A2E; margin: 0 0 20px; fontFamily: 'PelakFA','Vazirmatn',sans-serif`
**Tab routing (18 tabs):** dashboard, articles, create, users, authors, media, comments, analytics, reviews, newsletter, series, categories, tags, seo-audit, jobs, client-errors, activity, roles
### 49.4 Dashboard Stats Grid (DashboardStats)
**Grid:** `display: grid; gridTemplateColumns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; marginBottom: 28px`
**Stat card:**
- Background: `#fff`
- Border: `1px solid #E4DDD2`
- Border radius: `12px`
- Padding: `20px 20px`
- Top border: `3px solid ${color}`
- Value: `fontSize: 24; fontWeight: 900; color: ${color}; marginBottom: 4`
- Label: `fontSize: 13; color: #5F6B6D`
**Colors by stat type:**
- Published articles: `#2F8F6B` (green)
- Pending review: `#D08A22` (amber)
- Drafts: `#5F6B6D` (gray)
- Total views: `#0F6B73` (teal)
- Users: `#3A7D5E` (medium green)
- Media: `#C46A4D` (terracotta)
- Needs revision: `#C94C4C` (red)
**Role-based stat sets:** admin (6 cards), editor (3 cards), writer (3 cards)
### 49.5 Live Admin Feed (LiveAdminFeed)
**Container:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 18px; marginBottom: 20`
**Header:** flex, space-between
- "وضعیت زنده": `fontSize: 14; color: #0F2A2E`
- Status dot: `8px`, border-radius `50%`
- Connected: `background: #2F8F6B` with pulseRing animation
- Disconnected: `background: #C94C4C`
- Text: "متصل" or "قطع"
**Stats grid:** `gridTemplateColumns: repeat(auto-fit, minmax(100px, 1fr)); gap: 12px; marginBottom: 16`
- Box: `background: #FAF7F0; padding: 12px; borderRadius: 8; textAlign: center`
- Value: `fontSize: 20; fontWeight: 900`
- Value colors: total=`#0F6B73`, users=`#2F8F6B`, guests=`#D49A2A`, comments=`#C46A4D`
- Label: `fontSize: 11; color: #5F6B6D`
**Events:** border-top `1px solid #E4DDD2`
- Each event: `fontSize: 11; color: #5F6B6D; background: #F4EFE6; padding: 6px 10px; borderRadius: 6`
- Actor: `fontWeight: 600; color: #0F2A2E`
### 49.6 Activity Log (ActivityLog)
**Each row:** `display: flex; gap: 14px; padding: 14px 0; borderBottom: 1px solid #E4DDD2; direction: rtl; alignItems: flex-start`
- Color dot: `8px` circle, border-radius `50%`, margin-top `6px`, flex-shrink `0`
- Colors: publish `#2F8F6B`, submit `#D49A2A`, draft `#5F6B6D`, approve `#2F8F6B`, reject `#C94C4C`, user `#0F6B73`, tag `#C76D4A`, category `#D49A2A`, edit `#0F6B73`, role `#C76D4A`, delete `#C94C4C`, author `#C76D4A`, upload `#2F8F6B`, media `#C46A4D`, schedule `#D49A2A`
- User name: `fontWeight: 600; color: #263238; fontSize: 13`
- Action: `color: #5F6B6D; fontSize: 13`
- Target: `color: #0F6B73; fontSize: 13`
- Time: `fontSize: 11; color: #5F6B6D; whiteSpace: nowrap; flexShrink: 0`
**CSV export:** pillBtn + background `#0F6B7318`, color `#0F6B73`, fontSize `12`, textDecoration `none`
### 49.7 Role Metrics Panel (RoleMetricsPanel)
**Grid:** `gridTemplateColumns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px`
- Card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 18px 20px; borderTop: 3px solid ${color}`
- Value: `fontSize: 24; fontWeight: 900; color; marginBottom: 4`
- Label: `fontSize: 12; color: #5F6B6D`
**Live coverage subsection:**
- Container: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16`
- Title: `fontSize: 13; fontWeight: 800; color: #0F2A2E; marginBottom: 10`
- Event badges: `background: #F4EFE6; border: 1px solid #E4DDD2; borderRadius: 999px; padding: 5px 10px; fontSize: 12; color: #0F2A2E`
**Auto-refresh:** every 15s via adminApi.getPanelMetrics()
**SSE:** `/api/v1/admin/stream` for real-time event push
### 49.8 Admin Article List (ArticlesManagement)
**Filters row:** search input (inputStyle, maxWidth 260), status dropdown (inputStyle, maxWidth 180), freshness dropdown (inputStyle, maxWidth 180)
- Status options: همه وضعیت‌ها, منتشرشده, پیش‌نویس, در انتظار بررسی, نیازمند اصلاح, زمان‌بندی‌شده
- Freshness options: همه تازگی‌ها, به‌روز, نیاز به بازنگری, بازنگری برنامه‌ریزی‌شده, آرشیو
**Table:**
- Container: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; overflow: hidden`
- Scrollable wrapper: `overflowX: auto`
- Table: `width: 100%; borderCollapse: collapse; fontFamily: Vazirmatn,sans-serif; fontSize: 13; direction: rtl`
- Column headers: `background: #F4EFE6; borderBottom: 1px solid #E4DDD2; padding: 12px 16px; textAlign: right; color: #5F6B6D; fontWeight: 600; whiteSpace: nowrap`
- Columns: عنوان, نویسنده, دسته, وضعیت, بازدید, تاریخ, اقدام
- Body rows: alternating `#fff` / `#FDFBF7`, `borderBottom: 1px solid #E4DDD2`
- Title cell (280px max-width): `fontWeight: 600; color: #263238; cursor: pointer`, truncated 50 chars
- Review note: `padding: 5px 9px; background: rgba(200,149,28,0.10); border: 1px solid rgba(200,149,28,0.28); borderRadius: 6; fontSize: 11; color: #7A5A00; lineHeight: 1.7`
**Action buttons (actionBtn style):**
- Approve: background `#2F8F6B18`, color `#2F8F6B`, "تأیید"
- Reject: background `#C94C4C18`, color `#C94C4C`, "رد"
- Submit: background `#D49A2A18`, color `#D49A2A`, "ارسال"
- Edit: background `#0F6B7318`, color `#0F6B73`, "ویرایش"
- Delete: background `#C94C4C18`, color `#C94C4C`, "حذف"
**Pagination:** when > 15 items
- Toggle: `background: none; border: 1px solid #E4DDD2; borderRadius: 8; padding: 7px 20px; cursor: pointer; fontSize: 12; color: #5F6B6D`
### 49.9 Article Editor (ArticleEditor)
**Flow label:** "جریان تولید: نوشتن → Artifact → بازبینی → انتشار" — `fontSize: 11; color: #0F6B73; fontWeight: 800; marginBottom: 4`
**Title h2:** `fontSize: 24; fontWeight: 900; color: #0F2A2E; fontFamily: 'PelakFA','Vazirmatn',sans-serif`
**Online editors indicator:**
- `background: #FFF8F0; border: 1px solid #F5C97A; borderRadius: 20; padding: 4px 10px; fontSize: 11; color: #7A5A00`
- Editor avatars: `width: 22px; height: 22px; borderRadius: 50%; background: #E07A3A; color: #fff; fontSize: 9; fontWeight: 800; border: 2px solid #fff`
**Review note banner:**
- `background: linear-gradient(135deg, #FFF8F0, #FFF3E0); border: 1px solid rgba(200,149,28,0.35); borderRadius: 10; padding: 12px 16px; marginBottom: 20`
- Title: "بازخورد ویراستار" — `fontSize: 12; fontWeight: 800; color: #7A5A00`
- Note: `fontSize: 13; color: #5A4000; lineHeight: 1.8`
**Editor grid:** `gridTemplateColumns: 0.9fr 1.1fr; gap: 24`
**Left column (metadata):**
- Card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 16; padding: 22; boxShadow: 0 10px 34px rgba(15,42,46,0.05)`
- Section dividers: `fontSize: 11; fontWeight: 800; color: #0F6B73; letterSpacing: 0.08em; paddingBottom: 8; borderBottom: 1px solid #E4DDD2`
- Sections: "اطلاعات پایه", "نشانه‌گذاری", "زمان‌بندی"
- Fields: عنوان (input), زیرعنوان (input), خلاصه (textarea), دسته‌بندی (select), نویسنده (select), نوع محتوا (select: تحلیل عمیق, راهنمای فنی, داده‌نما, پژوهش, پرونده, خبر فوری), زمان مطالعه (number), برچسب‌ها (input)
- Toggle switches: premiumOnly, sponsored, featured
- Label: `display: flex; alignItems: center; gap: 8; fontSize: 13; color: #263238`
- Toggle: `width: 44px; height: 24px; borderRadius: 12; border: none; cursor: pointer`
- On: `background: #0F6B73`
- Off: `background: #D0CCC5`
- Knob: `position: absolute; top: 3; width: 18px; height: 18px; borderRadius: 50%; background: #fff; transition: inset-inline-start 0.2s; insetInlineStart: 23` (on) or `3` (off)
**SEO section (collapsible):**
- Toggle: `width: 100%; background: none; border: none; cursor: pointer; padding: 10px 0 8px; display: flex; justifyContent: space-between`
- Arrow: `▴` (open) or `▾` (closed)
- Fields: slug, metaDescription (textarea), keywords, ogTitle, ogDescription (textarea), ogImage, canonicalPath
**Right column (content):** HtmlEditor + ArtifactStudio
**Preview mode:**
- `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 32`
- Title: `fontSize: 28; fontWeight: 900; color: #263238; margin: 16px 0 8px; lineHeight: 1.4`
- Subtitle: `fontSize: 18; color: #5F6B6D; lineHeight: 1.6; fontWeight: 500`
- Content: `fontSize: 16; lineHeight: 2; color: #263238` — dangerouslySetInnerHTML
**Action buttons:**
- Published + admin: "بروزرسانی و انتشار" (green `#2F8F6B`), "تبدیل به پیش‌نویس", "زمان‌بندی مجدد"
- Published + writer: "ذخیره پیش‌نویس", "ارسال برای بررسی مجدد"
- Draft: "ذخیره پیش‌نویس" (beige), "ارسال برای بررسی" (teal `#0F6B73`), "زمان‌بندی انتشار" (gold `#D49A2A`)
- Cancel: "انصراف" (gray `#5F6B6D`)
- All: pillBtn + `padding: 10px 24px`
- Dirty indicator: `fontSize: 11; color: #C94C4C; fontWeight: 700` → "● ذخیره نشده · Ctrl+S"
**Field helper (Basic Field):**
- Label: `fontSize: 13; fontWeight: 600; color: #5F6B6D; display: block; marginBottom: 6`
- Input: inputStyle
- Error: `fontSize: 12; color: #C94C4C; marginTop: 4`
### 49.10 Artifact Studio (ArtifactStudio)
**Outer section:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 16; overflow: hidden; boxShadow: 0 14px 40px rgba(15,42,46,0.06)`
**Gradient header:** `padding: 18px; background: linear-gradient(135deg, #0F6B73 0%, #073F45 100%); color: #fff`
- Sub-label: "Artifact Writing" — `fontSize: 11; opacity: 0.76; marginBottom: 4`
- Title: "کتابخانه دیاگرام و ابزار کدنویسی" — `fontSize: 18; fontWeight: 900`
**Mode toggle:** `background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.18); borderRadius: 10; padding: 3`
- Labels: "قالب‌ها" and "کد اختصاصی"
- Active: `background: #fff; color: #0F6B73`
- Inactive: `background: transparent; color: #fff`
- Style: `border: 0; borderRadius: 8; padding: 7px 13px; cursor: pointer; fontWeight: 800; fontSize: 12`
**Upload bar:**
- `borderBottom: 1px solid #E4DDD2; background: #F8FBFA; display: flex; alignItems: center; justifyContent: space-between; gap: 12`
- Text: `fontSize: 12; color: #5F6B6D; lineHeight: 1.7`
- Button: pillBtn, background `#0F6B73` (or `#5F6B6D` when busy), color `#fff`
- Max file size: 12MB
**Library mode (diagram gallery):**
- Two-column grid: `gridTemplateColumns: 1.1fr 0.9fr; gap: 16`
- Left pane: `gridTemplateColumns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10; maxHeight: 360; overflowY: auto`
- Each diagram button:
- Selected: `border: 1px solid #0F6B73; background: #0F6B73+10 opacity; boxShadow: 0 8px 24px rgba(15,107,115,0.12); borderRadius: 12; padding: 12`
- Unselected: `border: 1px solid #E4DDD2; background: #fff; borderRadius: 12; padding: 12`
- Preview: `height: 56px; borderRadius: 10; marginBottom: 9; overflow: hidden; background: #F4F0EA; display: flex; alignItems: center; justifyContent: center`
- Diagram scaled: `transform: scale(0.33); transformOrigin: center; width: 400px; pointerEvents: none`
- Label: `fontSize: 12; fontWeight: 800; color: #0F2A2E; lineHeight: 1.5`
- Right pane: `background: #F4EFE6; border: 1px solid #E4DDD2; borderRadius: 14; padding: 14`
- Heading: `fontSize: 12; fontWeight: 800; color: #0F6B73; marginBottom: 10`
- Preview: `background: #fff; borderRadius: 12; padding: 10; minHeight: 180`
**Code mode:**
- Two-column grid: `gridTemplateColumns: 1fr 1fr; gap: 16`
- Language toggle (mermaid, plantuml, d2):
- Active: `background: #0F6B73+18 opacity; color: #0F6B73`
- Inactive: `background: #F4EFE6; color: #5F6B6D`
- Textarea: inputStyle + `direction: ltr; textAlign: left; fontFamily: Consolas, monospace; lineHeight: 1.6; resize: vertical`
- Insert button: pillBtn + `background: #0F6B73; color: #fff; marginTop: 10`
- Right pane code preview: `background: #101A1C; color: #DDEBE9; borderRadius: 14; padding: 16; minHeight: 290; direction: ltr; border: 1px solid rgba(15,107,115,0.45)`
- Header: `color: #8CCFD2; fontSize: 11`
- Code: `whiteSpace: pre-wrap; fontSize: 12; lineHeight: 1.7`
- Empty: `color: #4A6A6C`
**210 total diagram choices:** 18 base types + 192 generated (diagram-001 through diagram-192)
### 49.11 HTML Editor (HtmlEditor)
**Toolbar:** `display: flex; flexWrap: wrap; alignItems: center; gap: 4; padding: 7px 10px; background: #F9F7F4; border: 1px solid #E4DDD2; borderRadius: 8px 8px 0 0; direction: ltr`
- Toolbar button (TB): `padding: 4px 9px; border: 1px solid #D4C9B8; borderRadius: 5; cursor: pointer; background: #fff; color: #263238; fontFamily: Vazirmatn or monospace; fontSize: 11-12`
- Hover: `background: #EFE9E0; color: #C46A4D; borderColor: #C8951C; transition: all 0.12s`
- Buttons: B (bold), I (italic), H2, H3, link icon (SVG), «» (blockquote), </> (inline code), { } (code block), ≡ (bullet list), 1. (numbered list), — (hr)
- Separator: `width: 1px; alignSelf: stretch; background: #D4C9B8; margin: 2px 3px`
- Image upload label: SVG icon + "تصویر", same hover styling
- WebP checkbox: `fontSize: 11; color: #5F6B6D`
**Textarea:**
- inputStyle + `resize: vertical; lineHeight: 1.8; direction: rtl; borderTop: none; borderBottom: none; borderRadius: 0; fontFamily: monospace; fontSize: 13`
- Rows: 18
- Ctrl+B (bold) and Ctrl+I (italic) shortcuts
**Footer bar:** `display: flex; gap: 16; padding: 5px 12px; background: #F9F7F4; border: 1px solid #E4DDD2; borderTop: none; borderRadius: 0 0 8px 8px; fontSize: 11; color: #8A9A9B; direction: ltr`
- Shows word count + character count (Persian locale)
### 49.12 Revision Drawer (RevisionDrawer)
**Overlay:** `position: fixed; inset: 0; z-index: 700; display: flex; alignItems: stretch; justifyContent: flex-end`
- Backdrop: `position: absolute; inset: 0; background: rgba(0,0,0,0.45)`
- Drawer: `width: 100%; maxWidth: 520px; background: #FAF7F0; boxShadow: -8px 0 40px rgba(0,0,0,0.18); direction: rtl; flex column`
**Header:** `padding: 20px 24px; borderBottom: 1px solid #E4DDD2; display: flex; justifyContent: space-between; alignItems: center`
- Title: "تاریخچه نسخه‌ها" — `fontSize: 18; fontWeight: 900; color: #263238`
- Close: `background: none; border: none; fontSize: 20; cursor: pointer; color: #5F6B6D` (✕)
**Body:** `flex: 1; overflowY: auto; padding: 16px 24px`
- Each revision: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 10; padding: 10px 14px; cursor: pointer`
- Selected: `background: #F0F9F4; border: 1px solid #3A7D5E`
- Title: `fontSize: 13; fontWeight: 700; color: #263238; marginBottom: 3; overflow: hidden; textOverflow: ellipsis; whiteSpace: nowrap`
- Meta: `fontSize: 11; color: #5F6B6D` — "date · author · status"
- Pagination: `display: flex; gap: 8; justifyContent: center; marginTop: 16`
- "قبلی" / "بعدی" buttons: pillBtn style, fontSize `12`
- Page indicator: `fontSize: 12; color: #5F6B6D`
**Preview:** `marginTop: 20; background: #fff; border: 1px solid #E4DDD2; borderRadius: 10; padding: 16`
- Content: `fontSize: 13; color: #263238; lineHeight: 1.8; maxHeight: 300; overflowY: auto; whiteSpace: pre-wrap; wordBreak: break-word`
**Restore footer:** `padding: 16px 24px; borderTop: 1px solid #E4DDD2`
- Button: pillBtn; width 100%; background `#3A7D5E`; color `#fff`; padding `12px 0`; fontSize `14`
- Text: "بازیابی این نسخه" (or "…" when restoring)
### 49.13 User Management (UserManagement)
**Table:** Same style as ArticleList table
- Columns: نام, ایمیل, نقش, وضعیت, مقاله‌ها, اقدام
- Avatar: AuthorAvatar with size 32
- Name: `fontWeight: 600; color: #263238`
- Email: `direction: ltr; color: #5F6B6D; fontSize: 12`
- Role select: `border: 1px solid #E4DDD2; borderRadius: 6; padding: 3px 8px; fontSize: 12; fontFamily: Vazirmatn`
- Status: active = `color: #2F8F6B` "فعال", suspended = `color: #C94C4C` "غیرفعال"
- Actions: "جزئیات" (teal), "غیرفعال"/"فعال" (red/green)
**User Detail Modal:**
- Backdrop: `rgba(0,0,0,0.45)`
- Panel: `background: #FAF7F0; borderRadius: 14; padding: 32; maxWidth: 420; width: 90%; boxShadow: 0 20px 60px rgba(0,0,0,0.2)`
- Avatar size 60
- Info grid: `gridTemplateColumns: 1fr 1fr; gap: 12`
- Info box: `background: #F4EFE6; borderRadius: 8; padding: 12`
- Label: `fontSize: 11; color: #5F6B6D`
- Value: `fontSize: 14; fontWeight: 600; color: #263238`
- Close: pillBtn `background: #F4EFE6; color: #263238; width: 100%`
### 49.14 Category Management (CategoryManagement)
**Add form:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 24; marginBottom: 24`
- Name input (maxWidth 200), description input (flex:1; minWidth 200), color picker (`width: 48; height: 40; border: 1px solid #E4DDD2; borderRadius: 8; padding: 2`), submit (pillBtn `background: #0F6B73; color: #fff`)
**Category grid:** `gridTemplateColumns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14`
- Card: `background: #fff; border: 1px solid ${color}30; borderRadius: 10; padding: 16px 18px; borderRight: 4px solid ${color}`
- Name: `fontSize: 14; fontWeight: 700; color: #263238`
- Count: `fontSize: 11; color: #5F6B6D`
- Delete: actionBtn + `background: #C94C4C18; color: #C94C4C`
### 49.15 Tags Management (TagsManagement)
**Add + search:** new tag input (inputStyle, maxWidth 220), add button (pillBtn `background: #0F6B73; color: #fff`), search input (inputStyle, maxWidth 200)
**Tag chips:** `display: flex; gap: 10; flexWrap: wrap`
- Chip: `background: #F4EFE6; border: 1px solid #E4DDD2; borderRadius: 20; padding: 5px 14px; display: flex; alignItems: center; gap: 8`
- Name: `fontSize: 13; color: #263238`
- Count: `fontSize: 11; color: #5F6B6D`
- Delete X: `background: none; border: none; cursor: pointer; color: #C94C4C; fontSize: 14`
### 49.16 Authors Management (AuthorsManagement)
**Form card:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 24; marginBottom: 24`
- 2-column grid rows (name+slug, specialty+initials+color)
- Bio textarea: inputStyle + `minHeight: 80; resize: vertical`
- Save/cancel: pillBtn
**Author card grid:** `gridTemplateColumns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16`
- Card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 20; borderRight: 4px solid ${color}`
- Avatar: `width: 48px; height: 48px; borderRadius: 50%; background: ${color}18; fontSize: 16; fontWeight: 700; color: ${color}`
- Name: `fontSize: 15; fontWeight: 700; color: #263238`
- Specialty: `fontSize: 11; color: #5F6B6D; marginTop: 2`
- Bio: `fontSize: 12; color: #5F6B6D; lineHeight: 1.6`
- Actions: edit (teal) + delete (red) via actionBtn
### 49.17 Media Library (MediaLibrary)
**Filters:** Search input (maxWidth 260), mime type select (maxWidth 180)
**Media grid:** `gridTemplateColumns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16`
- Card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; overflow: hidden`
- Preview area: `height: 138px; background: #F4EFE6; display: flex; alignItems: center; justifyContent: center`
- Image: `width: 100%; height: 100%; objectFit: cover` (lazy loading)
- Info: `padding: 14px`
- Filename: `fontSize: 13; fontWeight: 700; color: #263238; whiteSpace: nowrap; overflow: hidden; textOverflow: ellipsis`
- Size: `fontSize: 11; color: #5F6B6D; marginTop: 6` → "X KB · W×H"
- Actions: "کپی URL" (teal, actionBtn), "حذف" (red, actionBtn, admin only)
### 49.18 Comments Moderation (CommentsModeration)
**Filter:** Checkbox "فقط گزارش‌شده" + "حذف همه گزارش‌شده" button (red actionBtn)
**Table:** Same pattern as ArticleList
- Columns: وضعیت, نظر, مقاله, کاربر, تاریخ, اقدام
- Comment body: `fontSize: 13; color: #263238; lineHeight: 1.7; whiteSpace: nowrap; overflow: hidden; textOverflow: ellipsis; maxWidth: 280`
- Action buttons: "حذف" (red), "رفع گزارش" (teal), approve (green), reject (red)
- Bulk actions: "حذف انتخاب‌شده‌ها" button
- Selection: checkbox per row
### 49.19 Writer Workspace (WriterWorkspace)
**Header area:** `background: linear-gradient(160deg, #F2EBE3 0%, #FAF7F0 55%); borderBottom: 1px solid #E4DDD2; padding: 24px clamp(16px,3vw,44px) 0; maxWidth: 1280; margin: 0 auto`
**Greeting badge:** `display: inline-flex; alignItems: center; gap: 6; fontSize: 11; color: #C46A4D; fontWeight: 700; background: #FAF0EB; padding: 4px 12px; borderRadius: 20; border: 1px solid rgba(196,106,77,0.22); letterSpacing: 0.05em`
- Text: "✦ استودیوی نویسنده · تکناو"
**Greeting h1:** `fontSize: 28; fontWeight: 900; color: #1A2E30; fontFamily: 'PelakFA','Vazirmatn',sans-serif; lineHeight: 1.2`
- Time-based: شب بخیر (h<6 or h>=21), صبح بخیر (h 6-11), ظهر بخیر (h 12-16), عصر بخیر (h 17-20)
**Action buttons:** "✦ مقاله جدید" (wwPrimaryBtn), "پنل کامل" (wwGhostBtn → /admin), "سایت" (wwGhostBtn), "خروج" (wwDangerBtn)
**Writer button styles:**
- wwPrimaryBtn: `padding: 10px 22px; borderRadius: 10; border: none; background: #C46A4D; color: #fff; fontSize: 13; fontWeight: 700; boxShadow: 0 3px 12px rgba(196,106,77,0.25); display: inline-flex; alignItems: center; gap: 6`
- wwGhostBtn: `padding: 9px 16px; borderRadius: 10; border: 1px solid #E4DDD2; background: #fff; color: #1A2E30; fontSize: 13; fontWeight: 600`
- wwDangerBtn: `padding: 9px 16px; borderRadius: 10; border: none; background: rgba(201,76,76,0.08); color: #C94C4C; fontSize: 13; fontWeight: 600`
- wwLinkBtn: `background: #FAF0EB; border: none; cursor: pointer; color: #C46A4D; fontSize: 11; fontWeight: 700; padding: 3px 10px; borderRadius: 6`
**Tab bar:** `display: flex; gap: 0; overflowX: auto`
- Tabs: آمار من (◈), تحلیل‌ها (▤), نوشتن/ویرایش (✦), نوشته‌ها (◉), نظرها (◎)
- Active: `color: #C46A4D; borderBottom: 2.5px solid #C46A4D`
- Inactive: `color: #7B8C8E; borderBottom: 2.5px solid transparent`
- Padding: `11px 22px`, fontSize `13`, fontWeight `700`, transition `0.18s`
**Content area:** `maxWidth: 1280; margin: 0 auto; padding: 28px clamp(16px,3vw,44px)`
**Writer color palette (WW):**
- terra: `#C46A4D`, terraLight: `#FAF0EB`, terraBorder: `rgba(196,106,77,0.22)`
- gold: `#C8951C`, goldLight: `#FBF6E8`
- ink: `#1A2E30`, muted: `#7B8C8E`, faint: `#9AA5A6`
- cream: `#FAF7F0`, border: `#E4DDD2`
- success: `#3A7D5E`, successLight: `#EFF8F4`
- purple: `#7B5EA7`, purpleLight: `#F5F0FB`
**Writing Tip Card:**
- Container: `background: linear-gradient(135deg, #FAF0EB 0%, #FBF6E8 100%); border: 1px solid rgba(196,106,77,0.22); borderRadius: 12; padding: 14px 16px; display: flex; gap: 12; alignItems: flex-start`
- Icon box: `width: 36px; height: 36px; borderRadius: 10; background: linear-gradient(135deg, rgba(196,106,77,0.14), rgba(200,149,28,0.1)); display: flex; alignItems: center; justifyContent: center; fontSize: 16; color: #C46A4D`
- Label: "نکته نویسندگی" — `fontSize: 10; fontWeight: 700; color: #C46A4D; letterSpacing: 0.1em`
- Nav buttons: `background: #FAF0EB; color: #C46A4D; fontSize: 11; padding: 2px 7px; borderRadius: 6` (‹ and ›)
- Tip text: `fontSize: 12.5; color: #1A2E30; lineHeight: 1.85`
- Auto-rotate: every 7 seconds, fade transition opacity `0.35s`
**Weekly Chart (WeeklyChart):**
- Bars: `display: flex; alignItems: flex-end; gap: 5px; height: 48px`
- Today bar: `linear-gradient(to top, #C46A4D, rgba(196,106,77,0.45))`
- Other bars: `linear-gradient(to top, #E4DDD2, #EDE9E2)`
- Transition: `height 0.5s ease`
- Day labels: Persian week abbreviations (ش, ی, د, س, چ, پ, ج)
**Writer Analytics (WriterAnalyticsPanel):**
- Table: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 24`
- Title: "عملکرد نوشته‌های من" — `fontSize: 16; color: #1A2E30; fontWeight: 900`
- Columns: عنوان مقاله, بازدید, واکنش, نظر, روند اخیر
- Rows: alternating `#fff` / `#FDFBF7`, `borderBottom: 1px solid #E4DDD2`
- Sparkline (inline SVG 80x20): stroke `#C46A4D`, strokeWidth `1.5`, dot fill `#C46A4D`, r `2.5`
- Expanded sparkline: 560x80 viewBox, area gradient `#C46A4D` 22%→1%, stroke `2`, end dot r `3.5`
- Footer total: `borderTop: 2px solid #E4DDD2; background: #FAF7F0; fontWeight: 700; color: #C46A4D`
### 49.20 Admin Panel Responsive Behavior
**At max-width 640px:**
- Sidebar hidden by default (`.admin-sidebar { display: none }`)
- `.open` class shows sidebar as fixed overlay: z-index `300`, width `280px`, overflow-y auto
- `.admin-overlay` shown (rgba(0,0,0,0.4))
- Topbar title font-size `12px`
**At max-width 768px:**
- Dashboard 2-column grid collapses to 1 column
**At max-width 980px:**
- Editor grid collapses to single column
- Artifact studio grid collapses to single column
---
## 50. ENGLISH HOMEPAGE (teknav-en.jsx)
### 50.1 Global Shell
**Background:** `#FAF7F0`, text color `#132326`
**Font stack:** `-apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Arial, sans-serif`
**Direction:** `ltr`, language `en`
### 50.2 Sticky Header
**Background:** `rgba(250,247,240,0.94)`, backdrop-filter `blur(14px)`
**Border bottom:** `1px solid #E4DDD2`
**Padding:** `0 28px`, height `60px`
**Logo "Teknav":** `fontSize: 22; fontWeight: 900; color: #0F2A2E; letterSpacing: -0.02em`
**"ENGLISH" badge:** `fontSize: 10; color: #C46A4D; fontWeight: 700; letterSpacing: 0.14em`
**Nav links:** `fontSize: 13; fontWeight: 500; color: #4A5A5C`
**"Persian site" button:** transparent bg, border `1px solid #0F6B73`, color `#0F6B73`, borderRadius `7px`, padding `6px 14px`, fontSize `12px`, fontWeight `600`
### 50.3 Hero Section
**Background:** `#F4F1EC`, min-height `520px`
**Radial glows:** teal (480px, top-right) + terracotta (340px, bottom-left) at 9% opacity
**Grid pattern:** 48px grid, 3.5% opacity lines, radial masked
**Content grid:** `1.3fr / 0.7fr`, gap `48px`, padding `80px 28px 72px`
**Pill badge:** background `rgba(15,107,115,0.08)`, border `1px solid rgba(15,107,115,0.22)`, color `#0F6B73`, padding `6px 16px`, borderRadius `999px`, fontSize `11px`, fontWeight `700`
- Dot: `6px`, borderRadius `50%`, background `#0F6B73`, enPulse animation
**H1:** `clamp(36px, 5.5vw, 62px)`, fontWeight `800`, color `#0F2A2E`, lineHeight `1.12`, letterSpacing `-0.02em`
**Gradient span:** `linear-gradient(90deg, #0F6B73, #D49A2A)`, `-webkit-background-clip: text`
**Subtitle:** `fontSize: 16; color: #4A5A5C; lineHeight: 1.85; maxWidth: 580`
**Primary CTA ("Browse research"):** bg `#0F6B73`, color `#fff`, padding `13px 28px`, borderRadius `9px`, fontWeight `700`, boxShadow `0 6px 20px rgba(15,107,115,0.28)`
**Secondary CTA ("Read TekRAG-Persian"):** bg `rgba(196,106,77,0.08)`, color `#A8512E`, border `1px solid rgba(196,106,77,0.4)`, padding `13px 26px`, borderRadius `9px`
**Featured card:** bg `#fff`, border `1px solid #E4DDD2`, borderRadius `14px`, padding `22px 24px`, boxShadow `0 12px 38px rgba(15,42,46,0.08)`
- Left accent: `4px`, `linear-gradient(180deg, #D49A2A, #C46A4D)`
- "FEATURED ARTICLE": `fontSize: 10; color: #C46A4D; fontWeight: 700; letterSpacing: 0.1em`
- Title: `fontSize: 16; fontWeight: 700; color: #0F2A2E; lineHeight: 1.55`
- Meta author in `#0F6B73`
**SVG wave divider:** fill `#ebe3d2`, height `42px`
### 50.4 Stats Bar
**Background:** `#ebe3d2`, padding `36px 24px`
**Grid:** 4-column, gap `16px`, separator lines
**Stat number:** `fontSize: 28; fontWeight: 900; color: #A8761B`
**Stat label:** `fontSize: 12; color: #4A5A5C; fontWeight: 500`
### 50.5 English Article Cards
**Standard card:** borderRadius `12px`, border `1px solid #E4DDD2`, padding `22px`, boxShadow `0 2px 10px rgba(0,0,0,0.04)`
- Thumbnail: height `110px`, bg `#F4EFE6`, borderRadius `8px`, scale `0.68`
- H3: `fontSize: 14; fontWeight: 700; color: #263238; lineHeight: 1.5`
- Summary: `fontSize: 12; color: #5F6B6D; lineHeight: 1.7`
- Footer: `fontSize: 11; color: #8A9A9C`
**Grid:** `repeat(3, minmax(0,1fr))`, gap `18px`
### 50.6 "Most Read" Section
- Rank number: `fontSize: 32; fontWeight: 900; color: #E4DDD2; minWidth: 40px; font-variant-numeric: tabular-nums`
- Title: `fontSize: 15; fontWeight: 700; color: #263238; lineHeight: 1.45`
- Thumbnail: `72x72px`, bg `#F4EFE6`, borderRadius `8px`, scale `0.52`
### 50.7 "Topics We Cover" Section
**Grid:** `repeat(auto-fill, minmax(200px,1fr))`, gap `12px`
- Card: bg `#fff`, border `1px solid {cat.color}30`, border-left `3px solid {cat.color}`, borderRadius `10px`, padding `18px 16px`
### 50.8 Writers Section
**Grid:** `repeat(auto-fill, minmax(260px,1fr))`, gap `16px`
- Card: borderRadius `12px`, padding `22px`, hover translateY(-3px) + shadow
- Avatar: `48x48px`, borderRadius `50%`, bg `#0F6B7322`, color `#0F6B73`, fontSize `20px`
- Name: `fontSize: 15; fontWeight: 700`
- Bio: `fontSize: 12; color: #5F6B6D; lineHeight: 1.75`
### 50.9 Newsletter CTA (English)
**Background:** `#ebe3d2`, borderRadius `18px`, padding `52px 40px`
**Label:** `fontSize: 11; color: #A8512E; fontWeight: 700; letterSpacing: 0.1em; uppercase`
**Heading:** `clamp(20px, 2.5vw, 30px)`, fontWeight `800`, color `#0F2A2E`
**Button:** bg `#0F6B73`, hover `#0d5c63`, color `#fff`, borderRadius `9px`, padding `13px 26px`
### 50.10 English Footer
**Background:** `#0F2A2E` (dark teal), text color `#C8D4D5`
**Padding:** `40px 28px`, max-width `1240px`
**Logo:** `fontSize: 22; fontWeight: 900; color: #FAF7F0`
**Tagline:** `fontSize: 12; color: #7A9A9C`
**Nav links:** `color: #A8C0C2; fontSize: 13`, hover `#FAF7F0`
**Copyright:** `fontSize: 12; color: #4A6A6C`
### 50.11 English Animations
**enReveal:** opacity `0→1`, filter `blur(5px)→0`, translateY(16px)→(0)
**enPulse:** opacity `1→0.5→1`, scale `1→1.4→1`, 2.2s
### 50.12 English Hero Canvas
**28 nodes** with teal/terracotta/green palette
**Connection distance:** `< 120px`, stroke `rgba(15,107,115, 0.15 * (1-d/120))`, lineWidth `0.7`
**Pulse:** `0.45 + 0.18 * sin(t + phase)` on alpha
**CountUp:** 1400ms, cubic ease-out, IntersectionObserver threshold 0.4
---
## 51. DIAGRAM SYSTEM COMPLETE REFERENCE (teknav-diagrams.jsx)
### 51.1 Shared Diagram Properties
- All SVGs: `width="100%"` with viewBox
- Font: `Vazirmatn, sans-serif`
- Diagram colors: `#0F6B73` (teal), `#D49A2A` (gold), `#C76D4A`/`#C46A4D` (terracotta), `#2F8F6B` (green), `#5F6B6D` (muted), `#E4DDD2` (border), `#F4EFE6` (cream bg), `#20343A` (tooltip bg), `#FAF7F0` (light text), `#263238` (dark text), `#C94C4C` (red)
- Tooltip pattern: `rect` rx `4`, fill `#20343A`, opacity `0.9`, fontSize `9px`, fill `#FAF7F0`
- Hover: nodes enlarge, opacity increases, cursor pointer
- Animation: setInterval 40-100ms, requestAnimationFrame equivalent
### 51.2 NeuralNetworkDiagram (420×280)
- 4 layers: ورودی (x=60), پنهان ۱ (x=160), توجه (x=260), خروجی (x=360)
- Node counts: 4, 3, 3, 2
- Node colors: `['#0F6B73', '#D49A2A', '#C76D4A', '#2F8F6B']`
- Connections: `stroke="#E4DDD2" strokeWidth="1" opacity="0.6"`
- Pulse dots: `fill="#D49A2A"` radius 3, traveling
- Nodes: `r=10` (hover `r=13`), opacity `0.85` (hover `1`), transition `0.15s`
- Tick interval: 80ms
### 51.3 DataPipelineDiagram (700×180 / 480×140)
- 7 steps: Raw → Clean → Label → Feature → Train → Eval → Output
- Step colors: `#5F6B6D`, `#D49A2A`, `#C76D4A`, `#0F6B73`, `#2F8F6B`, `#D49A2A`, `#0F6B73`
- Center line: `stroke="#E4DDD2" strokeWidth="2"`
- Animated dots: 4 dots, `fill="#D49A2A"`, radius 4, opacity 0.8
- Step circles: radius 22 (hover 26), opacity 0.85 (hover 1)
- Tick interval: 60ms
### 51.4 CyberSecurityDiagram (400×300)
- Center: `cx=200, cy=150`, dashed spinning ring `r=55`, `stroke="#2F8F6B" strokeWidth=2.5`, `strokeDasharray="8 4"`, animation `spin 20s linear infinite`
- 6 threats at 60° intervals, radius 90
- Colors: `#C94C4C`, `#D08A22`, `#C76D4A` repeating
- Connection lines: dashed pulsing `6 3` or `3 6`, opacity 0.7
- Threat nodes: `r=8` (hover `r=10`), opacity `0.75` (hover `1`)
- Tick interval: 100ms
### 51.5 StartupGrowthDiagram (400×200+30)
- S-curve: 5 milestones, `stroke="#0F6B73" strokeWidth="2.5"`, `strokeLinecap="round"`
- Area fill: `fill="#0F6B73" opacity="0.08"`
- Milestone dots: `r=7`, `fill="#D49A2A"`
- Animation: 0→100 in 100 steps at 20ms intervals (2s total)
- Growth: `y = H - padY - Math.pow(t, 1.8) * (H - padY*3)`
### 51.6 HardwareChipDiagram (400×220)
- Chip rect: `x=10, y=20, w=380, h=190, rx=8`, fill `#F4EFE6`
- 5 blocks: Memory (gold), Processor (teal), AI Accelerator (clay), Data Bus (green), Memory Controller (gray)
- Block: `80x40` or `80x80`, `rx=5`, opacity 0.85
- Animated pulse dots traveling data routes
- Tick interval: 70ms
### 51.7 FutureTimelineDiagram (480×120+20)
- 5 milestones: 2025–2035
- Dots: `r=10` (hover `r=14`), colors: teal, gold, clay, green, teal
- Year labels: `fontSize: 10; fontWeight: 700`
- Labels: `fontSize: 8.5`
### 51.8 SoftwareArchDiagram (420×250)
- 6 modules in layered architecture
- Module: `100x36`, `rx=6`, opacity 0.85
- Arrow marker: `#E4DDD2`, `M0,0 L6,3 L0,6 Z`
### 51.9 WaveStreamDiagram (480×160)
- 3 data streams: gold (amp=28, freq=0.022), terracotta (amp=20, freq=0.03), green (amp=24, freq=0.018)
- Gradients for fade edges
- Animated dot per stream: `r=4`
- Tick interval: 40ms
### 51.10 OrbitDiagram (280×220)
- Center: AI nucleus, `r=22`, fill `#20343A`
- 3 orbits: r=40 (gold, 0.04), r=65 (terracotta, -0.025), r=90 (green, 0.016)
- Dashed `4 6`, opacity 0.35
- Tick interval: 50ms
### 51.11 GeneratedDiagram (520/320 × 210/150)
- 5-color palette
- 6-12 nodes radially, radius 48-90px
- Full connection graph, line width varies 0.5-3.5
- Nodes: `r=6-9`, opacity 0.9
- Pulsing outer rings
- Tick interval: 50ms
### 51.12 BrainDiagram (400/300 × 260/180)
- Radial glow: `radialGradient` #0F6B73 at 30% opacity
- 8 nodes in brain-like pattern
- Connections: distance < 100px
- Pulsing nodes: `r = Math.sin(tick*0.1 + i) * 3 + 6`
- Tick interval: 60ms
### 51.13 DatabaseDiagram (320×200)
- 3 cylinder stacks: gray (h=40), gold (h=60), teal (h=50)
- Cylinder: rect + top/bottom ellipse
- Curved path: dashed `5 5`, animated stroke-dashoffset
- Tick interval: 50ms
### 51.14 CloudDiagram (400×220)
- Cloud path: fill `#F4EFE6`, stroke `#0F6B73`, strokeWidth 2
- 3 server blocks: `30x15`, `rx=3`, pulsing gold/gray
- Tick interval: 80ms
### 51.15 QuantumDiagram (400×200)
- 2 circles: `r=30`, dashed `4 4`, `stroke="#2F8F6B"`
- 2 orbiting electrons: `r=6`, `fill="#2F8F6B"`, opposite phases
- Tick interval: 40ms
### 51.16 VlaDiagram (400×220)
- Center: `160x80`, `rx=10`, fill `#F4EFE6`, stroke `#C76D4A`
- Vision/Language/Action lines
- Tick interval: 50ms
### 51.17 DnaDiagram (320×200)
- 10 rungs, spacing 15px
- Left: `r=5`, fill `#C76D4A`; Right: `r=5`, fill `#0F6B73`
- Sinusoidal motion: `Math.sin(tick*0.1 + i*0.8) * 40`
- Tick interval: 60ms
### 51.18 FusionDiagram (320×200)
- Outer ring: `r=50`, dashed `5 5`, `stroke="#D49A2A"`, rotating 4s
- Pulsing core: `r = 20 + sin(tick*0.2)*5`
- Tick interval: 40ms
### 51.19 SatelliteDiagram (320×200)
- Earth: `r=30`, fill `#0F6B73` opacity 0.6
- Orbit ellipse: `rx=80, ry=40`
- Satellite: `16x8`, rotating with `tick*1.7`
- Tick interval: 50ms
### 51.20 BlockchainDiagram (400×150)
- 4 blocks: `60x50`, `rx=6`, fill `#F4EFE6`, stroke `#2F8F6B`
- Dashed connecting arrows
- Static (no tick)
### 51.21 TekRagThreeDiagram (3D Three.js)
- 3 variants: corpus, retrieval, evaluation
- WebGLRenderer, antialias, alpha, pixel ratio capped at 2, SRGBColorSpace
- PerspectiveCamera(45, aspect, 0.1, 100)
- Lighting: AmbientLight(0xffffff, 0.7), DirectionalLight(0xffffff, 1.4), DirectionalLight(0xd49a2a, 0.8) rim
- 3D palette: teal `0x0f6b73`, gold `0xd49a2a`, clay `0xc76d4a`, green `0x2f8f6b`, ink `0x20343a`, line `0xe4ddd2`, red `0xc94c4c`, cream `0xf4efe6`
- BoxGeometry + MeshStandardMaterial, roughness 0.48, metalness 0.12
- Hover labels via raycasting
- Drag rotation, auto-rotation `+= 0.003`
- Canvas bg: `radial-gradient(circle at 50% 20%, #ffffff 0%, #f4efe6 42%, #e9f2f2 100%)`
- Legend pills: border `1px solid #E4DDD2`, borderRadius `999px`, bg `#fff`
---
## 52. WIDGET SYSTEM DESIGN
### 52.1 GlossaryWidget
**Max-width:** 480px, direction: rtl
**Light theme:**
- Card: bg `#fff`, border `1px solid #E4DDD2`, color `#263238`, borderRadius `12px`, overflow hidden
- Header: bg `#0C1E22` (dark teal)
- Footer: bg `#F8F5F0`, border-top `1px solid #E4DDD2`
- Term (Persian): color `#D49A2A`, fontWeight `700`, fontSize `16px`
- English term: color `rgba(255,255,255,0.5)`, fontSize `12px`
- Summary: `fontSize: 14; lineHeight: 1.9`
- FAQ question: color `#0F6B73`
- FAQ answer: color `#5F6B6D`
- Link: color `#0F6B73`
**Dark theme:**
- Card: bg `#0C1E22`, border `1px solid rgba(255,255,255,0.1)`, color `#E4DDD2`
- Header: bg `#061014`
- Footer: bg `#061014`, border-top `1px solid rgba(255,255,255,0.08)`
- Summary: color `rgba(255,255,255,0.85)`
- FAQ question: color `#D49A2A`
- FAQ answer: color `rgba(255,255,255,0.6)`
- Link: color `#D49A2A`
### 52.2 ArticleCardWidget
**Max-width:** 480px, direction: rtl, borderRadius `12px`, overflow hidden
**Image section:** height `180px`, overflow hidden
- Image: 100%×100%, object-fit cover, loading lazy
- Category badge: bg `#0F6B73`, color `#fff`, fontSize `11px`, fontWeight `700`, padding `3px 10px`, borderRadius `20px`, positioned bottom-right
- Read time badge: bg `rgba(0,0,0,0.55)`, color `#fff`, fontSize `11px`, borderRadius `20px`, positioned top-left
**Content section:** padding `16px 20px`
- H3: `fontSize: 16; fontWeight: 700; lineHeight: 1.6`
- Light: color `#0C1E22`
- Dark: color `#fff`
- Summary: `fontSize: 13; lineHeight: 1.8`, truncated 120 chars
- Light: color `#5F6B6D`
- Dark: color `rgba(255,255,255,0.6)`
**Footer:** border-top `1px solid #E4DDD2` / `rgba(255,255,255,0.08)`, padding `10px 20px`, bg `#F8F5F0` / `#061014`
- Author name: `fontSize: 12`
- Link: `fontSize: 12; color: #D49A2A; fontWeight: 600` → "خواندن در تکناو ↗"
### 52.3 CompanyWidget
**Same scaffolding** as ArticleCardWidget
**Loading state:** padding `24px`, flex gap `12px`
- Skeleton avatar: `40x40px`, borderRadius `8px`, bg `#E4DDD2` / `rgba(255,255,255,0.08)`
- Skeleton lines: height `14px`/`10px`, borderRadius `4px`, width `60%`/`40%`
**Header:** bg `#061014` / `#0C1E22`, padding `16px 20px`
- Logo: `40x40px`, borderRadius `8px`, bg `#fff`, padding `4px`
- Company name: color `#fff`, fontWeight `700`, fontSize `16px`
- Verified badge: color `#D49A2A`, fontSize `11px`
- Category pill: bg `rgba(212,154,42,0.15)`, color `#D49A2A`, borderRadius `20px`
**Body:** padding `16px 20px`
- Description: `fontSize: 14; lineHeight: 1.9`
- Light: `#263238`
- Dark: `rgba(255,255,255,0.8)`
- Tech tags: flex wrap, gap `6px`
- Light: bg `#E4DDD2`, color `#263238`
- Dark: bg `rgba(255,255,255,0.08)`, color `rgba(255,255,255,0.7)`
**Footer:** link color `#D49A2A` (always)
### 52.4 Widget Resize Protocol
All widgets use `ResizeObserver` on `#widget-root` and send `postMessage({ type: 'resize', height })` to parent `*` whenever the height changes.
### 52.5 embed-loader.js
- Reads `data-type`, `data-slug`, `data-width` attributes
- Creates sandboxed `<iframe>` pointing to `www.teknav.ir/embed/{type}/{slug}`
- Attributes: `loading="lazy"`, `sandbox="allow-scripts allow-popups allow-same-origin"`, `title`
- Listens for `postMessage` resize events, adjusts iframe height dynamically
- Default width 480px
- Error: console.warn if `data-slug` missing
### 52.6 Widget Error States
- GlossaryWidget: term not found — empty details
- ArticleCardWidget: article not found — empty card
- CompanyWidget: company not found — `<EmptyState>` with not-found message
- Generic widget error: red text `#C62828`, `fontFamily: 'Vazirmatn,sans-serif'`, padding `20px`, direction `rtl`
---
## 53. SEO MANAGER DESIGN (seo.jsx)
### 53.1 Operation
- `SeoManager` component renders `null` (no DOM output)
- On page change (via `useNav().page`), fetches async data with static fallback
- Injects meta tags, JSON-LD, link tags into `document.head`
- All previous SEO elements cleaned before re-injection
### 53.2 Meta Tags Injected (30+)
**Standard SEO:** `description`, `keywords`, `robots`, `googlebot`, `bingbot`, `author`, `language`
**Academic citation:** `citation_title`, `citation_author`, `citation_publication_date`, `citation_online_date`, `citation_lastdate`, `citation_journal_title`, `citation_language`, `citation_public_url`, `citation_keywords`, `citation_reference` (up to 20)
**Dublin Core:** `DC.title`, `DC.creator`, `DC.date`, `DC.language`, `DC.identifier`
**Open Graph:** `og:locale`, `og:site_name`, `og:type`, `og:title`, `og:description`, `og:url`, `og:image`, `og:image:width`, `og:image:height`
**Twitter Card:** `twitter:card` (summary_large_image), `twitter:title`, `twitter:description`, `twitter:image`
**Link:** `canonical`, `alternate` hreflang
### 53.3 JSON-LD Schemas (15 types)
All wrapped in `@graph` array. Site-wide base graph (Organization + WebSite) present on every page. Additional schemas per page type:
- Article: NewsArticle + TechArticle [+ ScholarlyArticle], CreativeWork (benchmark), FAQPage, BreadcrumbList
- Category: CollectionPage, BreadcrumbList
- Tag: CollectionPage, ItemList, BreadcrumbList
- Glossary: DefinedTerm, FAQPage, BreadcrumbList
- Topic Hub: CollectionPage, FAQPage, ItemList, BreadcrumbList
- Series: CollectionPage, ItemList, BreadcrumbList
- Author/Profile: ProfilePage, Person, BreadcrumbList
- Listing pages: CollectionPage (articles, authors, newsletter, jobs, courses, membership)
- Newsletter issue: Article, BreadcrumbList
- Search: base graph only
- Fallback/home: WebPage
### 53.4 Wikidata Entity Mapping
26 Persian/English terms → Wikidata URLs. Examples:
- `هوش مصنوعی` → Q11660
- `rag` → Q108745802
- `امنیت سایبری` → Q3510502
- `quantum computing` → Q11190
- `deep learning` → Q197536
### 53.5 Constants
- `SITE_URL`: `VITE_SITE_URL` env or `https://www.teknav.ir`
- `SITE_NAME`: `تکناو`
- `DEFAULT_TITLE`: `تکناو | تحلیل فناوری، هوش مصنوعی و امنیت سایبری`
- `DEFAULT_IMAGE`: `{SITE_URL}/images/og/default.jpg`
---
## 54. CAPTCHA WIDGET (TeknavCAP.jsx)
### 54.1 Visual Design
**Container:** `direction: rtl`, flex row, gap `12px`, flexWrap wrap, marginBottom `8px`
**CAPTCHA image area:**
- Border: `2px solid #E4DDD2`, borderRadius `8px`, padding `8px`
- Background: `#fff`
- Cursor: pointer (click to refresh)
- Min dimensions: 200×80px
- Centered content
- Title: "برای تازه‌سازی کلیک کنید"
**Refresh button:**
- Background: `#0F6B73`, color `#fff`
- Border: none, borderRadius `8px`
- Padding: `10px 16px`
- Font: `13px`, Vazirmatn, weight `600`
- Opacity: `0.6` when loading
- Text: "↻ تازه‌سازی"
**Input field:**
- Full width, `padding: 10px 14px`
- Border: `1px solid #E4DDD2`, borderRadius `8px`
- Font: `14px`, monospace, `letterSpacing: 0.1em`, centered
- Focus: border-color `#0F6B73`
- Placeholder: "کد امنیتی را وارد کنید"
- Max length: 10, dir="ltr"
**Loading text:** `fontSize: 13; color: #5F6B6D` — "در حال بارگذاری..."
**Error text:** `fontSize: 12; color: #C94C4C` — "خطا در بارگذاری کپچا"
### 54.2 Interaction Flow
1. On mount: fetches `/api/v1/teknav-cap/generate`
2. Click image: refreshes captcha
3. Refresh button click: same
4. Input change: calls `onChange({ captchaId, userSolution })`
5. Error: displays message, logs to console
---
## 55. ICON SYSTEM (icon.jsx)
### 55.1 Function: iconNode(value, style)
- If `value` ends with `.svg`: renders `<span className="tek-icon" style={{ '--i': url("{value}"), ...style }} />`
- If `value` is anything else (text, emoji, symbol): returns value unchanged
### 55.2 CSS Behavior
- `.tek-icon`: `display: inline-block`, `width: 1em`, `height: 1em`, `background-color: currentColor`, `mask: var(--i) center / contain no-repeat`
- Inherits text color, scales with font size
- Icons are single-color, adaptive to surrounding text
### 55.3 Imported SVG Icons
34 SVG files in `src/assets/icons/`: bell, book-open, bookmark, bot, chart-column, clipboard-copy, crown, database, eye, flame, globe, graduation-cap, heart, image, laptop, library, lightbulb, link, lock, mail, map-pin, medal, pen-line, pencil, ruler, scroll, settings, share-2, sprout, square-pen, star, thumbs-up, triangle-alert, waves, zap
---
## 56. PAGES LAYOUT COMPLETE REFERENCE (teknav-pages.jsx)
### 56.1 SearchPage
**Layout:** two-column: sidebar (240px) + results, gap 32px
**Filters:** category (select), author (select), type (select), clear button
**Highlight:** `<mark>` with background `#D49A2A30`, color `#263238`, borderRadius `2px`
**Search result:** `padding: 24px 0`, borderBottom `1px solid #E4DDD2`, fadeIn animation
### 56.2 CategoryPage
**Hero:** gradient `linear-gradient(135deg, ${cat.color}18 0%, #F4EFE6 100%)`
**Grid:** 1fr 320px (text + diagram), responsive at 768px
**Category badge:** color+20 bg, full color text, 4px radius
**H1:** clamp(28px,5vw,42px), 900 weight
**Stats:** flex gap 32, wrap
**Diagram card:** white bg, 12px radius, 20px padding, shadow
### 56.3 AuthorsListPage
**H1:** 32px, 900 weight
**Grid:** repeat(auto-fill, minmax(300px,1fr)), gap 20px
**Card:** white bg, 14px radius, 24px padding, hover translateY(-3px) + shadow
**Avatar:** 60px
**Verified badge:** fontSize 10, bg `#0F6B7314`, border `#0F6B7330`, borderRadius 999
**Bio:** truncated to 120 chars
### 56.4 TagPage
**H1:** 30px, 900 weight
**Articles list:** same pattern as CategoryPage article list
### 56.5 GlossaryPage
**Hero:** gradient `linear-gradient(135deg,#FFFFFF 0%,#F4EFE6 100%)`
**Grid:** `1.1fr 0.9fr` (content + sidebar), responsive at 850px
**FAQs card:** white bg, 8px radius, border 1px #E4DDD2
**FAQ item:** borderTop divider, padding 14px 0
**Related terms:** pill buttons in flex wrap
**Topic button:** white bg, 8px radius, 18px padding
### 56.6 TopicHubPage
**Topic hero** with follow toggle + guest push subscription
**FAQs section** with Question/Answer pairs
**Series section** listing related series
**Authors section** listing topic authors
**Related articles section**
### 56.7 SeriesPage
**H1:** 30px, 900 weight
**Article list:** grid gap 14px
**Position circle:** 36px, borderRadius 999, bg `#0F6B73`, color `#fff`, weight 900
**Loading:** min-height 60vh, centered
### 56.8 NewsletterArchivePage
**H1:** 32px, 900 weight
**List:** grid gap 14px
**Item:** white bg, 10px radius, 18px padding
**Subject:** 18px, 800 weight
**Date:** fontSize 12, color `#5F6B6D`
### 56.9 NewsletterIssuePage
**Article:** maxWidth 760px, centered
**Content body:** fontSize 16, lineHeight 2, color #263238, white bg, 12px radius, 24px padding, dangerouslySetInnerHTML
### 56.10 JobsPage
**Grid:** 1fr 360px (list + form), responsive at 850px
**Job card:** white bg, 12px radius, 18px padding
**Form:** white bg, 12px radius, 18px padding, grid gap 10px
**Form fields:** company, title (required), location, remote checkbox, contactEmail, url, description (required, minHeight 110px)
### 56.11 CoursesPage
**H1:** 32px, 900 weight
**Grid:** repeat(auto-fit, minmax(260px,1fr)), gap 16px
**Card:** white bg, 12px radius, 20px padding
**Level:** color #0F6B73, fontSize 12, weight 800
**Price:** color #D49A2A, weight 900
### 56.12 MembershipPage
**Premium banner:** bg `#0F6B7318`, border `#0F6B7340`, 12px radius
**Feature grid:** repeat(auto-fit, minmax(240px,1fr)), gap 16px
**Subscribe button:** gradient `#D49A2A→#B8821E`, color `#fff`, 14px, 700 weight, borderRadius 10px, padding 14px 36px
### 56.13 MembershipSuccessPage
**Crown icon:** fontSize 56px
**H1:** 26px, 900 weight
**Home button:** pillBtn, bg #0F6B73, color #fff
### 56.14 Legal Pages (shared.jsx)
**LegalPage:** maxWidth 820px, heading h1 28px 800 weight, gold accent bar (3px, 48px, #D49A2A), content card (white bg, 12px radius, 36px 40px padding, fontSize 14, color #374549)
**LegalSection:** marginBottom 32px, h2 16px 700 weight, borderRight 3px solid #0F6B73, paddingRight 10px
### 56.15 AboutPage
**Sections:** bullet points with `#0F6B73` dot indicators (8px circle)
**Buttons:** primary teal btn + outline teal btn
### 56.16 ContactPage
**Contact cards grid:** repeat(auto-fit, minmax(200px,1fr))
**Form:** grid, name+email row 1fr 1fr, inputs bg #FAF7F0, border #D8D0C4, borderRadius 8px, padding 11px 14px
**Submit:** bg #0F6B73, color #fff, pillBtn
**Success state:** checkmark 56px, h2 22px 800 weight
### 56.17 PrivacyPolicyPage / TermsOfUsePage
**7 sections each**, each with LegalSection
List style: `disc`, paddingRight 20px
### 56.18 ToolsPage
**Tool listing** with cards linking to NLP normalizer and RAG calculator
### 56.19 NlpNormalizerPage
**Textarea style:** `width: 100%; minHeight: 180; background: #FAF7F0; border: 1px solid #D8D0C4; borderRadius: 8; padding: 12px 16px; fontSize: 14; fontFamily: Vazirmatn; color: #263238; lineHeight: 1.7; resize: vertical`
**Options panel:** bg #FAF7F0, border 1px #E4DDD2, 10px radius, 18px padding
**Options grid:** repeat(auto-fit, minmax(200px,1fr)), checkbox accentColor #0F6B73
**Button:** bg #0F6B73 + outline cancel btn
**Citation:** borderTop divider, code block bg #FAF7F0, monospace
### 56.20 RagCalculatorPage
**Textarea:** same style as NlpNormalizer
**Settings panel:** bg #FAF7F0, border 1px #E4DDD2, 10px radius, 18px padding
**Parameter grid:** repeat(auto-fit, minmax(180px,1fr))
**Number inputs:** `padding: 10px 12px; border: 1px solid #D8D0C4; borderRadius: 8; fontSize: 14`
**Results section:** stats grid (3 columns), chunk list with numbered headers
**Chunk card:** border 1px #E4DDD2, 10px radius, header bg #FAF7F0
### 56.21 TekRagHubPage
**Benchmark hub** with citations, links to HuggingFace/Zenodo/GitHub
**Static content** from TeknavData + TekRAG article
### 56.22 DirectoryListPage
**H1:** clamp(22px,4vw,30px), color #0C1E22
**Grid:** repeat(auto-fill, minmax(280px,1fr)), gap 16px
**Card:** white bg, 12px radius, 20px padding, hover shadow
**Verified badge:** bg #E8F5E9, color #2E7D32, borderRadius 20px
**Tech tags:** bg #F4EFE6, color #263238, borderRadius 20px
### 56.23 CompanyProfilePage
**Hero:** bg #0C1E22, 16px radius, 28px padding
**Company name:** clamp(20px,4vw,28px), color #fff, 800 weight
**Verified badge:** bg #D49A2A, color #0C1E22, borderRadius 20px
**Description:** color rgba(255,255,255,0.8), fontSize 15px
**Website button:** bg #0F6B73, color #fff, borderRadius 8px
**Tech tags:** bg #E4DDD2, color #263238, borderRadius 20px
**Claim card:** bg #F8F5F0, 12px radius, 24px padding
### 56.24 ComparisonsListPage
**H1:** clamp(22px,4vw,32px), color #0C1E22
**Search:** inputStyle, maxWidth 400px
**List:** flex column, gap 14px
**Card:** white bg, 12px radius, 20px 24px padding, hover shadow
**Category pills:** bg per CATEGORY_COLORS map, color #fff, borderRadius 20px
**Item badges:** green (E8F5E9 bg, #2E7D32 text) / orange (FFF3E0 bg, #E65100 text)
### 56.25 ComparisonPage (Detail)
**ComparisonVoteBar:** bg #F8F5F0, 12px radius, 20px 24px padding
- Vote buttons: flex 1, 9px 16px padding, borderRadius 8px, fontWeight 700
- Item1 active: bg #0F6B73, color #fff, border 2px solid #0F6B73
- Item2 active: bg #D49A2A, color #fff, border 2px solid #D49A2A
- Inactive: white bg, border 2px solid #E4DDD2
- Share button: bg #0C1E22, color #D49A2A, borderRadius 8px; shared: bg #2E7D32, color #fff
**Cards:** flex 1 1 300px, white bg, 12px radius, 24px padding, border 1px #E4DDD2
- h2: fontSize 20, 700 weight, color #0F6B73
- Pros: ✓ green (#2E7D32)
- Cons: ✗ red (#C62828)
**Use cases:** bg #F8F5F0, 12px radius, 24px padding
**Verdict:** bg #0F3540, color #fff, h2 #D49A2A
**Glossary terms:** white bg, border 1px #0F6B73, 8px radius
**Related articles:** white bg, border 1px #E4DDD2, 8px radius
### 56.26 StoriesListPage
**Grid:** repeat(auto-fill, minmax(160px,1fr)), gap 14px
**Card:** borderRadius 14px, overflow hidden, bg #0C1E22, paddingBottom 177%
**Image:** absolute, inset 0, object-fit cover, brightness 0.55
**Badge:** "▶ استوری", bg rgba(15,107,115,0.85), borderRadius 20px
**Bottom overlay:** gradient transparent→rgba(5,20,25,0.95)
**Category:** fontSize 11, color #D49A2A, 700 weight
**Title:** fontSize 12, color #fff, 600 weight
---
## 57. COMPLETE API ENDPOINT REFERENCE
### 57.1 Public Endpoints
| Path | Method | Module |
|---|---|---|
| `/api/v1/articles` | GET | content-api |
| `/api/v1/articles/:slug` | GET | content-api |
| `/api/v1/articles/:slug/related` | GET | content-api |
| `/api/v1/articles/:slug/comments` | GET | engagement-api |
| `/api/v1/articles/:slug/comments` | POST | engagement-api |
| `/api/v1/articles/:slug/qa` | GET | engagement-api |
| `/api/v1/articles/:slug/qa` | POST | engagement-api |
| `/api/v1/qa/questions/:id/answers` | POST | engagement-api |
| `/api/v1/articles/:id/reactions` | POST | content-api |
| `/api/v1/articles/:id/save` | POST | content-api |
| `/api/v1/comments/:id/like` | POST | engagement-api |
| `/api/v1/comments/:id/upvote` | POST | engagement-api |
| `/api/v1/comments/:id/flag` | POST | engagement-api |
| `/api/v1/series` | GET | content-api |
| `/api/v1/series/:slug` | GET | content-api |
| `/api/v1/search` | GET | content-api |
| `/api/v1/search/semantic` | POST | RAG/search |
| `/api/v1/rag/:slug` | GET | RAG/search |
| `/api/v1/categories` | GET | content-api |
| `/api/v1/categories/:slug` | GET | content-api |
| `/api/v1/authors` | GET | content-api |
| `/api/v1/authors/:slug` | GET | content-api |
| `/api/v1/jobs` | GET/POST | content-api |
| `/api/v1/courses` | GET | content-api |
| `/api/v1/newsletter` | POST | content-api |
| `/api/v1/newsletter/archive` | GET | content-api |
| `/api/v1/newsletter/archive/:slug` | GET | content-api |
| `/api/v1/analytics/events` | POST | content-api |
| `/api/v1/auth/me` | GET | auth |
| `/api/v1/auth/login` | POST | auth |
| `/api/v1/auth/logout` | POST | auth |
| `/api/v1/auth/signup` | POST | auth |
| `/api/v1/auth/2fa/verify` | POST | auth |
| `/api/v1/auth/oauth/:provider/start` | GET | auth |
| `/api/v1/auth/oauth/providers` | GET | auth |
| `/api/v1/auth/forgot-password` | POST | auth |
| `/api/v1/auth/reset-password` | POST | auth |
| `/api/v1/auth/email/verify/request` | POST | profile |
| `/api/v1/auth/email/verify/confirm` | POST | auth |
| `/api/v1/auth/otp/send` | POST | profile |
| `/api/v1/auth/otp/verify` | POST | profile |
| `/api/v1/auth/profile` | PUT | profile |
| `/api/v1/auth/avatar` | POST | profile |
| `/api/v1/auth/2fa` | PUT | profile |
| `/api/v1/auth/history` | GET/POST/DELETE | engagement-api |
| `/api/v1/auth/streaks` | GET | engagement-api |
| `/api/v1/auth/notifications` | GET | engagement-api |
| `/api/v1/auth/notifications/read-all` | POST | engagement-api |
| `/api/v1/auth/notifications/:id/read` | PATCH | engagement-api |
| `/api/v1/auth/notifications/:id` | DELETE | engagement-api |
| `/api/v1/auth/notifications/stream` | SSE | engagement-api |
| `/api/v1/auth/notifications/preferences` | GET/PUT | engagement-api |
| `/api/v1/auth/lists` | GET/POST | engagement-api |
| `/api/v1/auth/lists/:id` | DELETE | engagement-api |
| `/api/v1/auth/lists/:id/items` | POST | engagement-api |
| `/api/v1/auth/lists/:id/items/:itemId` | DELETE | engagement-api |
| `/api/v1/auth/lists/:id/reorder` | PUT | engagement-api |
| `/api/v1/auth/analytics/overview` | GET | engagement-api |
| `/api/v1/auth/analytics/articles` | GET | engagement-api |
| `/api/v1/auth/analytics/article/:slug` | GET | engagement-api |
| `/api/v1/auth/badges` | GET | engagement-api |
| `/api/v1/auth/push/vapid-key` | GET | engagement-api |
| `/api/v1/auth/push/subscribe` | POST | engagement-api |
| `/api/v1/auth/push/unsubscribe` | DELETE | engagement-api |
| `/api/v1/push/vapid-key` | GET | engagement-api |
| `/api/v1/push/guest-subscribe` | POST | engagement-api |
| `/api/v1/push/guest-unsubscribe` | DELETE | engagement-api |
| `/api/v1/profile/:slug` | GET | profile |
| `/api/v1/writers/:username/follow` | POST/DELETE | engagement-api |
| `/api/v1/writers/:username/followers` | GET | engagement-api |
| `/api/v1/topics/:slug/follow` | POST/DELETE | engagement-api |
| `/api/v1/topics/:slug/followers` | GET | engagement-api |
| `/api/v1/auth/following` | GET | engagement-api |
| `/api/v1/directory/companies` | GET | directory |
| `/api/v1/directory/companies/:slug` | GET | directory |
| `/api/v1/directory/companies/:companyId/claim` | POST | directory |
| `/api/v1/lms/paths` | GET | LMS |
| `/api/v1/lms/paths/:slug` | GET | LMS |
| `/api/v1/lms/me` | GET | LMS |
| `/api/v1/lms/quiz/:quizId/submit` | POST | LMS |
| `/api/v1/wiki/proposals` | POST | wiki |
| `/api/v1/glossary/proposals` | POST | wiki |
| `/api/v1/membership/status` | GET | membership |
| `/api/v1/membership/subscribe` | POST | membership |
| `/api/v1/membership/callback` | GET | membership |
| `/api/v1/errors` | POST | error tracking |
| `/api/v1/csp-report` | POST | error tracking |
| `/api/v1/teknav-cap/generate` | GET | captcha |
| `/api/v1/teknav-cap/verify` | POST | captcha |
| `/api/v1/health` | GET | backend |
| `/api/v1/ready` | GET | backend |
### 57.2 Admin Endpoints
| Path | Method | Module |
|---|---|---|
| `/api/v1/admin/dashboard` | GET | admin-api |
| `/api/v1/admin/health` | GET | admin-api |
| `/api/v1/admin/panel-metrics` | GET | admin-api |
| `/api/v1/admin/writer/dashboard` | GET | admin-api |
| `/api/v1/admin/analytics` | GET | admin-api |
| `/api/v1/admin/analytics/content` | GET | admin-api |
| `/api/v1/admin/analytics/newsletter` | GET | admin-api |
| `/api/v1/admin/analytics/engagement` | GET | admin-api |
| `/api/v1/admin/seo/audit` | GET | admin-api |
| `/api/v1/admin/articles` | GET/POST | admin-api |
| `/api/v1/admin/articles/:id` | PATCH/DELETE | admin-api |
| `/api/v1/admin/articles/:id/publish` | POST | admin-api |
| `/api/v1/admin/articles/:id/schedule` | POST | admin-api |
| `/api/v1/admin/articles/:id/corrections` | POST | admin-api |
| `/api/v1/admin/articles/:id/review` | PUT | admin-api |
| `/api/v1/admin/articles/:id/revisions` | GET | revisions |
| `/api/v1/admin/articles/:id/revisions/:revId` | GET | revisions |
| `/api/v1/admin/articles/:id/revisions/:revId/restore` | POST | revisions |
| `/api/v1/admin/articles/:id/heartbeat` | POST | presence |
| `/api/v1/admin/articles/:id/presence` | GET | presence |
| `/api/v1/admin/categories` | GET/POST | admin-api |
| `/api/v1/admin/categories/:id` | PATCH/DELETE | admin-api |
| `/api/v1/admin/tags` | GET/POST | admin-api |
| `/api/v1/admin/tags/:id` | DELETE | admin-api |
| `/api/v1/admin/authors` | GET/POST | admin-api |
| `/api/v1/admin/authors/:id` | PUT/DELETE | admin-api |
| `/api/v1/admin/users` | GET | admin-api |
| `/api/v1/admin/users/:id` | PATCH | admin-api |
| `/api/v1/admin/comments` | GET/DELETE | admin-api |
| `/api/v1/admin/comments/bulk` | POST | admin-api |
| `/api/v1/admin/comments/:id` | DELETE | admin-api |
| `/api/v1/admin/comments/:id/unflag` | PUT | admin-api |
| `/api/v1/admin/media` | GET | admin-api |
| `/api/v1/admin/media/:id` | DELETE | admin-api |
| `/api/v1/admin/uploads` | POST | admin-api |
| `/api/v1/admin/activity` | GET | admin-api |
| `/api/v1/admin/activity/export.csv` | GET | admin-api |
| `/api/v1/admin/reviews` | GET | admin-api |
| `/api/v1/admin/newsletter/subscribers` | GET | admin-api |
| `/api/v1/admin/newsletter/campaigns` | GET/POST | admin-api |
| `/api/v1/admin/newsletter/campaigns/:id/send` | POST | admin-api |
| `/api/v1/admin/series` | GET/POST | admin-api |
| `/api/v1/admin/series/:id` | PATCH/DELETE | admin-api |
| `/api/v1/admin/jobs` | GET | admin-api |
| `/api/v1/admin/jobs/:id` | PATCH | admin-api |
| `/api/v1/admin/errors` | GET | admin-api |
| `/api/v1/admin/errors/digest` | POST | admin-api |
| `/api/v1/admin/security/events` | GET | admin-api |
| `/api/v1/admin/directory/claims` | GET | admin-api |
| `/api/v1/admin/directory/claims/:id` | PATCH | admin-api |
| `/api/v1/admin/wiki/proposals` | GET | admin-api |
| `/api/v1/admin/wiki/proposals/:id` | PATCH | admin-api |
| `/api/v1/metrics` | GET | admin-api |
| `/api/v1/admin/stream` | SSE | admin-stream |
---
## 58. DIFF VIEWER COMPONENT (diff-viewer.jsx)
### 58.1 Visual Design
**Container:** `white-space: pre-wrap; direction: rtl; text-align: right; font-family: monospace; padding: 1rem; background-color: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 8px; line-height: 1.6`
**Inline spans:**
- Added text: `color: #10b981` (emerald green), `background: rgba(16, 185, 129, 0.1)`, `padding: 2px 4px`, `border-radius: 4px`
- Removed text: `color: #ef4444` (red), `background: rgba(239, 68, 68, 0.1)`, `text-decoration: line-through`, `padding: 2px 4px`, `border-radius: 4px`
- Unchanged: `color: inherit`, `background: transparent`
**Algorithm:** Uses `diff` library's `diffWordsWithSpace`
---
## 59. KNOWLEDGE GRAPH COMPONENT (knowledge-graph.jsx)
### 59.1 Visual Design
**Container:** `overflow: hidden; border-radius: 12px; border: 1px solid var(--border-color); background-color: var(--bg-surface)`
**SVG:** `width: 100%; height: auto; display: block`
**D3 Force Simulation (800×600 default):**
- Link distance: 100
- Charge strength: -300
- Links: `stroke: var(--border-color)`, `stroke-opacity: 0.6`
- Nodes: `r=8`, `stroke: #fff`, `stroke-width: 1.5`
- Group 1: `fill: var(--primary-color)` (#0F6B73)
- Other: `fill: var(--brand-muted)`
- Labels: `font-size: 12px`, `fill: var(--text-color)`, `text-anchor: middle`, `dy=-12`
- Title tooltips (native SVG title)
- Drag: alphaTarget 0.3 with pinning
---
## 60. DIRECTORY PANEL (DirectoryPanel.jsx)
### 60.1 Visual Design
**Container:** `padding: 2rem; max-width: 1200px; margin: 0 auto; direction: rtl`
**Header:** flex justify-between, H1 "دایرکتوری فناوری و استارتاپ‌ها"
**Grid:** `grid gap-6 md:grid-cols-2 lg:grid-cols-3`
**Card:** `p-6 bg-bg-surface border border-border rounded-xl shadow-sm hover:shadow-md transition-shadow flex flex-col`
**Logo:** `w-16 h-16 rounded-lg object-cover` (or fallback with first char)
**Company name:** `text-xl font-bold`
**Industry:** `text-sm text-brand-muted`
**Description:** `text-sm mb-6 flex-grow`
**Website link:** `text-xs px-2 py-1 bg-border rounded hover:bg-brand hover:text-white transition-colors`
**Claimed badge:** `mt-auto pt-4 border-t border-border/50 text-xs text-brand-muted flex items-center gap-2` with green dot
**Empty:** `col-span-full py-12 text-center text-brand-muted border-2 border-dashed border-border rounded-xl`
---
## 61. LMS PANEL (LmsPanel.jsx)
### 61.1 Visual Design
**Container:** `padding: 2rem; max-width: 1000px; margin: 0 auto; direction: rtl`
**Header:** H1 "دوره‌های آموزشی و مسیرهای یادگیری"
**Certificates section:** `mb-8 p-6 bg-green-900/20 border border-green-500/30 rounded-xl`
- H2: "گواهینامه‌های شما" — `text-green-400`
- Grid: `md:grid-cols-2`
**Learning paths section:** H2 "مسیرهای یادگیری"
- Grid: `md:grid-cols-2`
- Card: `p-6 bg-bg-surface border border-border rounded-xl shadow-sm`
- Module list with order badges: `w-6 h-6 rounded-full bg-brand/10 text-brand flex items-center justify-center text-xs`
- Button: `w-full py-2 bg-brand text-white rounded-lg font-medium` → "شروع یادگیری"
---
## 62. SERVICE WORKER DESIGN (service-worker.js)
### 62.1 Cache
- **Cache name:** `teknav-v5`
- **Pre-cached:** `/`, `/index.html`, `/manifest.json`, `/favicon.png`
### 62.2 Strategy (Network-first with cache fallback)
- Article pages (`/article/*`, `/`, `/articles`): fetch → cache success → fallback cache → fallback /index.html
- API articles (`/api/v1/articles`): network-only
- HTML pages (Accept: text/html): fetch → cache → fallback → /index.html
- Everything else: cache-first → network
### 62.3 Push Notifications
- Icon: `/icons/icon-192x192.png`
- Badge: `/icons/badge-72x72.png`
- Direction: `rtl`, lang: `fa`
- Default title: "تکناو", body: "", url: "/"
- Click: focuses/navigates to data.url
---
## 63. PWA MANIFEST (manifest.json)
- `name`: `"تکناو"`
- `short_name`: `"Teknav"`
- `description`: `"تحلیل فناوری، هوش مصنوعی و امنیت سایبری"`
- `display`: `"standalone"`
- `display_override`: `["window-controls-overlay", "standalone", "browser"]`
- `background_color`: `"#FAF7F0"` (matches page background)
- `theme_color`: `"#0F6B73"` (primary teal)
- `icons`: one entry — `512×512`, `image/png`, purpose `"any maskable"`, src `"/favicon.png"`
---
## 64. COMPLETE CSS ANIMATION SPEED REFERENCE
| Animation | Duration | Delay | Timing | Instances |
|---|---|---|---|---|
| heroReveal | 0.6–0.7s | 0.1s–1.35s (staggered) | cubic-bezier | Hero elements (6 elements) |
| slideUp | 0.25s–0.45s | 0 | ease / cubic-bezier | Toasts, modals, dropdowns |
| fadeIn | 0.3s | idx * 40ms | ease | Search results |
| shimmer | 1.4s | 0 | linear infinite | Skeleton loaders (all) |
| spin | 0.7s | 0 | linear infinite | Loading spinners |
| float-y | 3s | varies | ease-in-out infinite | Auth word bubbles |
| goldShimmer | 5s | 0 | linear infinite | Gold shimmer text |
| pulseRing | 2.2s | 0 | ease-in-out infinite | Live indicators |
| orbit | 44s / 9s | 0 | linear infinite | Auth rings |
| orbitR | 17s | 0 | linear infinite | Auth middle ring |
| tickerUp | 22s | 0 | linear infinite | Topic ticker |
| bgGrid | 38s | 0 | linear infinite | Auth bg grid |
| logoGlow | 4.5s | 0 | ease-in-out infinite | Auth logo |
| statReveal | 0.55s | 0–0.33s staggered | cubic-bezier | Brand stats |
| dividerExpand | 1.2s | 0.3s | ease | Auth divider |
| blink | 0.8s | 0 | ease-in-out infinite | Cursor |
| enReveal | 0.6–0.7s | 0.1–0.55s staggered | ease | English hero |
| enPulse | 2.2s | 0 | ease-in-out infinite | English pulse dot |
| CSS spin (diagram) | 20s / 4s | 0 | linear infinite | Diagram rings |
| Chart bar | 0.5s | 0 | ease | WeeklyChart bars |
| Article card entry | 0.4–0.5s | idx*60–100ms | ease | Cards staggered |
| Article row entry | 0.4s | idx*60ms | ease | List entries |
| WritingTip fade | 0.35s | 0 | ease | Tip transitions |
| SSE reconnect | 0–3s | varies | -- | Auto |
---
## 65. ADMIN ANALYTICS PANELS (AnalyticsPanel.jsx)
### 65.1 SEO Audit Panel (SeoAuditPanel)
**Summary badge:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 10; padding: 10px 18px; fontSize: 14; fontWeight: 700; color: BRAND.ink`
- Text: "{totalIssues} مشکل یافت شد در {issuesCount} مقاله"
- All-clear: `color: #2F8F6B; fontWeight: 700; fontSize: 14` — "✓ همه مقاله‌ها سالم هستند"
**Table:** Same admin table pattern
- Columns: مقاله, مشکلات, شدت
- Each issue row: alternating `#fff` / `#FDFBF7`
- Article title: clickable button, `color: BRAND.primary`, `fontWeight: 700`, `fontFamily: Vazirmatn`
- Issue pills: `background: s.bg; border: 1px solid s.color+33; borderRadius: 6; padding: 2px 8px; fontSize: 11; fontWeight: 600`
- Severity pill: `background: sev.bg; color: sev.color; border: 1px solid sev.color+33; borderRadius: 6; padding: 4px 10px; fontSize: 11; fontWeight: 700`
- Pagination: "قبلی" page "بعدی" with opacity 0.5 when disabled
**Severity levels (SEO_SEVERITY):**
- error: label "خطا", color `#C94C4C`, bg `#FEF2F2`
- warning: label "هشدار", color `#C8951C`, bg `#FFFBEB`
- info: label "پیشنهاد", color `#0F6B73`, bg `#F0FDFA`
**Missing field to severity mapping:**
- error: metaDescription, ogTitle, ogDescription
- warning: keywords, ogImage, canonicalPath
- info: everything else
### 65.2 Engagement Analytics Panel (EngagementAnalyticsPanel)
**Weekly bar chart:**
- Container: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 18`
- Bars: `display: flex; gap: 4; alignItems: flex-end; height: 100`
- Bar: `width: 100%; background: BRAND.primary (#0F6B73); borderRadius: 4px 4px 0 0; height: value%`
- Labels: rotated -35deg, fontSize 9, color `#5F6B6D`
**Event type table:**
- Columns: نوع رویداد, تعداد, درصد
- Percent: "X٪" or "—"
- Empty: `<EmptyState title="هنوز رویدادی ثبت نشده است" />`
**Top 5 articles:**
- Each row: `display: flex; justifyContent: space-between; padding: 8px 0; borderBottom: 1px solid #E4DDD2`
- Title: `fontWeight: 800; color: BRAND.ink`
- Count: `fontSize: 12; color: #5F6B6D`
### 65.3 Phase 9 Analytics Panel (Phase9AnalyticsPanel)
**Tab buttons:**
- Active: `background: BRAND.primary; color: #fff; border: 1px solid BRAND.primary`
- Inactive: `background: transparent; color: #5F6B6D; border: 1px solid #E4DDD2`
- Style: `borderRadius: 8; padding: 6px 16px; fontSize: 12; fontWeight: 600`
**Overview tab:**
- Stats grid: `repeat(auto-fit,minmax(160px,1fr)); gap: 12`
- Cards: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16`
- Label: `fontSize: 12; color: #5F6B6D`
- Value: `fontSize: 24; fontWeight: 900; color: BRAND.primary`
- Stats displayed: comments, saves, newsletter subscribers
**Top articles section:**
- Container: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 18`
- H3: `margin: 0; fontSize: 15; color: BRAND.ink`
- Each article: `display: flex; justifyContent: space-between; padding: 10px 0; borderBottom: 1px solid #E4DDD2`
- Title: `fontSize: 13; fontWeight: 800; color: BRAND.ink`
- Views: `fontSize: 12; color: #5F6B6D`
### 65.4 Jobs Moderation Panel (JobsPanel)
**Filter:** select with inputStyle, width 160
- Options: همه وضعیت‌ها, در انتظار, تأیید شده, رد شده
**Status labels/colors:**
- pending: #D49A2A, "در انتظار"
- approved: #0F6B73, "تأیید شده"
- rejected: #C46A4D, "رد شده"
**Status badge:** `background: statusColor+22; color: statusColor; borderRadius: 6; padding: 2px 10px; fontWeight: 700; fontSize: 12`
**Table:** Same admin table pattern, columns: شرکت, عنوان, موقعیت, وضعیت, تاریخ, عملیات
- Action: "تأیید" button (background `#0F6B7318`, color `#0F6B73`) / "رد" button (background `#C46A4D18`, color `#C46A4D`)
**Empty:** "هیچ آگهی یافت نشد" — centered, padding 40
**Loading:** "در حال بارگذاری..."
### 65.5 Client Errors Panel (ClientErrorsPanel)
**Daily error bar chart:**
- Container: `background: #fff; border: 1px solid BRAND.line; borderRadius: 12; padding: 20`
- 30-day bars: `display: flex; alignItems: flex-end; gap: 3; height: 60`
- Each bar: `flex: 1; height: calculated; background: #C46A4D88; borderRadius: 2; minWidth: 4`
**Top errors list:**
- Each: `borderBottom: 1px solid BRAND.line; padding: 8px 0; display: flex; justifyContent: space-between`
- Message: `fontSize: 12; word-break: break-all`
- Count: `color: #C46A4D; fontWeight: 700` — "{count} بار"
- Date: `color: BRAND.muted`
**Recent errors:**
- Each: `borderBottom: 1px solid BRAND.line; padding: 8px 0; fontSize: 12`
- Message: `color: BRAND.ink`
- Meta: `color: BRAND.muted; display: flex; gap: 12`
**Empty states:** "خطایی ثبت نشده است"
**Error state:** "خطا در بارگذاری اطلاعات"
**Loading:** "در حال بارگذاری..."
---
## 66. NEWSLETTER PANEL (NewsletterPanel.jsx)
### 66.1 Layout
**Grid:** `display: grid; gap: 18; direction: rtl`
### 66.2 Subscriber Count
`background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16`
Text: "مشترکان واقعی API: {count}"
### 66.3 Create Campaign Form
`background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16; display: grid; gap: 10`
- Subject input: inputStyle, placeholder "موضوع کمپین", dir rtl
- Body textarea: inputStyle + minHeight 140, placeholder "HTML خبرنامه", dir rtl
- Submit: pillBtn + background BRAND.primary, color #fff, justifySelf start, text "ذخیره کمپین"
### 66.4 Campaign List
Each campaign card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16`
- Subject: `fontWeight: 900; color: BRAND.ink`
- Status: `fontSize: 12; color: #5F6B6D; margin: 6px 0 12px` — "ارسال‌شده به X" or "آماده ارسال"
- Send button: pillBtn + background BRAND.primary, color #fff, text "ارسال"
---
## 67. REVIEW PANEL (ReviewsPanel.jsx)
### 67.1 Layout
Each review card: `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16; marginBottom: 12; direction: rtl`
- Article title: `fontWeight: 900; color: BRAND.ink; marginBottom: 4`
- Status line: `fontSize: 12; color: #5F6B6D; marginBottom: 12` — "{status} · {reviewer name}"
**Action buttons:** flex wrap, gap 8
- "تأیید": pillBtn + background `#0F6B73`, color `#fff`
- "نیاز به اصلاح": pillBtn + background `#F4EFE6`, color `#C46A4D`, border `1px solid #E4DDD2`
- "رد": pillBtn + background `#C94C4C`, color `#fff`
**Empty:** PanelState with title "موردی در گردش بررسی وجود ندارد"
---
## 68. SERIES MANAGEMENT PANEL (SeriesPanel.jsx)
### 68.1 Layout
**Grid:** `display: grid; gap: 18; direction: rtl`
**Create form:** `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16; display: grid; gap: 10`
- Title input: inputStyle, placeholder "عنوان سری", dir rtl
- Description textarea: inputStyle + minHeight 80, placeholder "توضیح کوتاه", dir rtl
- Submit: pillBtn + background BRAND.primary, color #fff, justifySelf start, text "ایجاد سری"
**Series list:** each card `background: #fff; border: 1px solid #E4DDD2; borderRadius: 12; padding: 16`
- Title: `fontWeight: 900; color: BRAND.ink`
- Meta: `fontSize: 12; color: #5F6B6D; marginTop: 4` — "{N} مقاله · /series/{slug}"
- Empty: `<EmptyState title="هنوز سری مقاله‌ای در API نیست" />`
---
## 69. SIDEBAR ITEMS COMPLETE (Shared.jsx)
### 69.1 Admin Role (17 items)
| ID | Label | Icon |
|---|---|---|
| dashboard | داشبورد | ◈ |
| articles | مدیریت مقاله‌ها | ◉ |
| create | مقاله جدید | ⊕ |
| users | مدیریت کاربران | ◐ |
| authors | مدیریت نویسندگان | penLineIcon |
| media | کتابخانه رسانه | ▣ |
| comments | نظرها | ◌ |
| analytics | تحلیل محتوا | ▤ |
| reviews | گردش بررسی | ◇ |
| newsletter | خبرنامه | mailIcon |
| series | سری مقاله‌ها | ▥ |
| categories | دسته‌بندی‌ها | ⬡ |
| tags | برچسب‌ها | ⬟ |
| seo-audit | ممیزی SEO | ◈ |
| jobs | آگهی‌های شغلی | ◑ |
| client-errors | خطاهای کلاینت | triangleAlertIcon |
| activity | گزارش فعالیت | ◷ |
### 69.2 Editor Role (11 items)
dashboard, articles, create, authors, media, comments, analytics, reviews, newsletter, series, categories
### 69.3 Writer Role (5 items)
dashboard, create, articles, analytics, reviews
### 69.4 Reviewer Role (3 items)
dashboard, articles, reviews
### 69.5 BRAND Colors (Shared.jsx)
| Key | Hex |
|---|---|
| primary | #0F6B73 |
| primaryDark | #073F45 |
| ink | #0F2A2E |
| muted | #5F6B6D |
| cream | #FAF7F0 |
| panel | #F4EFE6 |
| line | #E4DDD2 |
| gold | #D49A2A |
| terracotta | #C46A4D |
### 69.6 Diagram Choices
- 18 base diagrams: neural, pipeline, growth, cyber, chip, arch, timeline, wave, orbit, brain, database, cloud, quantum, vla, dna, fusion, satellite, blockchain
- 192 generated diagrams: diagram-001 through diagram-192
- Total: 210 choices
### 69.7 Role Names
| Role | Persian |
|---|---|
| admin | مدیر کل |
| editor | سردبیر |
| writer | نویسنده |
| reviewer | بازبین |
---
## 70. TEKNAV-PAGES COMPLETE EXPORT MAP (index.js)
All 27 page components exported from `src/pages/index.js`:
SearchPage, CategoryPage, TagPage, GlossaryPage, AuthorsListPage, AuthorProfilePage, SeriesPage, TopicHubPage, NewsletterArchivePage, NewsletterIssuePage, JobsPage, CoursesPage, MembershipPage, MembershipSuccessPage, PrivacyPolicyPage, TermsOfUsePage, AboutPage, ContactPage, ToolsPage, NlpNormalizerPage, RagCalculatorPage, TekRagHubPage, ComparisonPage, DirectoryListPage, CompanyProfilePage, ComparisonsListPage, StoriesListPage
Plus 4 exported from `teknav-pages.jsx` directly: SearchPage, CategoryPage, TagPage, GlossaryPage (and everything else above)
---
## 71. AUTHOR PROFILE PAGE RENDER (AuthorProfilePage.jsx)
### 71.1 Hero Section
**Background:** `linear-gradient(135deg,#20343A,#0F2830)` — dark teal gradient
**Padding:** `48px 24px`
**Layout:** flex, gap 28, wrap
**Avatar:** AuthorAvatar size 96
**Name:** `fontSize: 28; fontWeight: 900; color: #FAF7F0; display: flex; alignItems: center; gap: 10; flexWrap: wrap`
**Verified badge:** `fontSize: 12; color: #D49A2A; background: rgba(212,154,42,0.12); border: 1px solid rgba(212,154,42,0.45); borderRadius: 999; padding: 3px 10px`
**Verification note:** `color: #CFE2DD; fontSize: 12; marginBottom: 8`
**Specialty:** `fontSize: 14; color: #D49A2A; fontWeight: 600; marginBottom: 10`
**Bio:** `fontSize: 14; color: #90A4AE; lineHeight: 1.8; margin: 0 0 16px; maxWidth: 520`
**Stats:** flex gap 24
- Number: `fontSize: 22; fontWeight: 800; color: #D49A2A`
- Label: `fontSize: 12; color: #90A4AE; marginRight: 4`
### 71.2 Articles Section
**Max-width:** 900, padding 32px 24px
**H2:** `fontSize: 20; fontWeight: 700; color: #263238; margin: 0 0 24px`
**Empty:** `<EmptyState title="مقاله‌ای منتشر نشده" />`
### 71.3 Note
This component immediately redirects via `navigate(/profile/@${username})`, so it serves as a transitional page. The full UI is rendered by the UserProfilePage component.
---
## 72. AUTHORS LIST PAGE COMPLETE (AuthorsListPage.jsx)
### 72.1 Layout
**Outer:** paddingTop 80, bg #FAF7F0, minHeight 100vh
**Inner:** maxWidth 1100, padding 0 24px, direction rtl
**Header:** paddingTop 32, paddingBottom 32, borderBottom 1px solid #E4DDD2
- H1: fontSize 32, fontWeight 900, color #263238
- Subtitle: fontSize 15, color #5F6B6D
### 72.2 Author Cards
**Grid:** `repeat(auto-fill, minmax(300px, 1fr))`, gap 20, padding 32px 0
**Card:** bg #fff, border 1px #E4DDD2, borderRadius 14, padding 24, cursor pointer, direction rtl, transition all 0.2s
- Hover: `transform: translateY(-3px); boxShadow: 0 10px 32px rgba(0,0,0,0.08)`
- Avatar: AuthorAvatar size 60
- Name: fontSize 16, fontWeight 700, color #263238, flex gap 6 wrap
- Verified badge: fontSize 10, color #0F6B73, bg #0F6B7314, border #0F6B7330, borderRadius 999, padding 2px 7px
- Specialty: fontSize 12, color #5F6B6D, marginBottom 6
- Article count: fontSize 12, color #0F6B73, fontWeight 600
- Bio: fontSize 13, color #5F6B6D, lineHeight 1.7, margin 0 0 16px, truncated 120 chars
- Latest article badge: bg #F4EFE6, borderRadius 8, padding 10px 14px, fontSize 12, color #263238
---
## 73. TOPIC HUB PAGE COMPLETE (TopicHubPage.jsx)
### 73.1 Hero Section
**Background:** `linear-gradient(135deg, ${category.color}18, #F4EFE6)`
**Padding:** 44px 24px
**Back button:** pillBtn, bg #FFFFFFAA, color #0F6B73, border 1px solid #E4DDD2
**H1:** clamp(30px,5vw,48px), fontWeight 900, color #263238
**Intro:** maxWidth 760, color #4F5D60, fontSize 16, lineHeight 1.95
### 73.2 Action Buttons
**Follow button:** pillBtn
- Following: bg #0F6B73, color #fff, text "دنبال می‌کنید · {count}"
- Not following: bg #fff, color #0F6B73, border 1px solid #0F6B7330, text "دنبال کردن موضوع · {count}"
**Push notification button:**
- Enabled: bg #fff, color #0F6B73, border 1px solid #0F6B7330, text "اعلان فعال است"
- Disabled: bg #FAF7F0, color #0F6B73, border 1px solid #0F6B7330, text "دریافت اعلان مقالات"
- Loading: opacity 0.6
### 73.3 Content Sections
**Featured articles section:** gap 14 grid, EmptyState "مقاله شاخصی برای این موضوع ثبت نشده است"
**Latest articles section:** ArticleRow list, EmptyState "هنوز مقاله‌ای در این موضوع منتشر نشده است"
**Series + Authors grid:** `repeat(auto-fit,minmax(260px,1fr)); gap: 18`
- Series card: bg #fff, border 1px #E4DDD2, borderRadius 12, padding 20
- Series list buttons: display block, bg #F4EFE6, border 1px #E4DDD2, borderRadius 8, padding 12
- Empty: "سری مقاله مرتبط پس از تایید سردبیر اینجا نمایش داده می‌شود."
- Authors card: bg #fff, border 1px #E4DDD2, borderRadius 12, padding 20
- Author list buttons: flex, gap 10, bg transparent, padding 8px 0
- AuthorAvatar size 36
- Empty: "نویسنده مرتبطی پیدا نشد."
**FAQs section:** bg #fff, border 1px #E4DDD2, borderRadius 12, padding 20
- Each `<details>`: borderTop 1px solid #E4DDD2, padding 12px 0
- `<summary>`: fontWeight 700, color #263238
- Answer: color #5F6B6D, lineHeight 1.9
---
## 74. CONTACT PAGE FORM COMPLETE (ContactPage.jsx)
### 74.1 Contact Info Cards
**Grid:** `repeat(auto-fit, minmax(200px, 1fr))`, gap 16
**Card:** bg #FAF7F0, border 1px #E4DDD2, borderRadius 10, padding 16px 18px
- Icon: fontSize 22, marginBottom 6
- Label: fontSize 12, color #5F6B6D
- Value: fontSize 13, fontWeight 600, color #0F2A2E
### 74.2 Contact Form
**Field style:** bg #FAF7F0, border 1px #D8D0C4, borderRadius 8, padding 11px 14px, fontSize 14, Vazirmatn, color #263238, width 100%
**Name/Email row:** `gridTemplateColumns: 1fr 1fr`, gap 14
**Labels:** fontSize 12, fontWeight 600, color #5F6B6D, display block, marginBottom 5
**Required asterisk:** color #C46A4D
**Email input:** direction ltr
**Submit button:** bg #0F6B73, color #fff, borderRadius 8, padding 12px 28px, fontSize 14, fontWeight 600, alignSelf flex-start, text "ارسال پیام"
**Sent state:** centered layout, checkmark 56px, h2 "پیام شما ارسال شد" fontSize 22, body text, home button
---
## 75. TOOLS PAGE COMPLETE (ToolsPage.jsx)
### 75.1 Grid Layout
`repeat(auto-fit, minmax(280px, 1fr))`, gap 20
### 75.2 Tool Cards
Card: bg #FAF7F0, border 1px #E4DDD2, borderRadius 12, padding 24, flex column, space-between
- Icon: fontSize 32, marginBottom 12
- Title: fontSize 17, fontWeight 800, color #0F2A2E, marginBottom 10
- Description: color #5F6B6D, fontSize 13, lineHeight 1.8, marginBottom 20
- Button: bg #0F6B73, color #fff, borderRadius 8, padding 10px 18px, fontSize 13, fontWeight 600, width 100%, text "ورود به ابزار"
Two tools: NLP Normalizer, RAG Calculator
---
## 76. NLP NORMALIZER PAGE COMPLETE (NlpNormalizerPage.jsx)
### 76.1 Textarea Style
`width: 100%; minHeight: 180; background: #FAF7F0; border: 1px solid #D8D0C4; borderRadius: 8; padding: 12px 16px; fontSize: 14; fontFamily: 'Vazirmatn, sans-serif'; color: #263238; outline: none; lineHeight: 1.7; resize: vertical; boxSizing: border-box`
### 76.2 Options Panel
bg #FAF7F0, border 1px #E4DDD2, borderRadius 10, padding 18
**Grid:** `repeat(auto-fit, minmax(200px, 1fr))`, gap 12
**Checkbox labels:** flex, gap 10, cursor pointer, fontSize 13, color #374549, accentColor #0F6B73
Options: stripHtml, normalizeLetters, normalizeZwnj, cleanWhitespace
### 76.3 Buttons
**Normalize:** bg #0F6B73, color #fff, borderRadius 8, padding 12px 28px, fontSize 14, fontWeight 600, text "نرمال‌سازی متن"
**Back:** bg transparent, color #5F6B6D, border 1px #D8D0C4, borderRadius 8, padding 12px 20px, fontSize 14, fontWeight 600, text "بازگشت"
### 76.4 Output Section
Output textarea: same as input textarea + bg #fff
Copy button: bg #FAF7F0, border 1px #D8D0C4, borderRadius 6, padding 6px 12px
### 76.5 Citation Section
Code block: bg #FAF7F0, border 1px #E4DDD2, borderRadius 8, padding 12, fontSize 11, monospace, direction ltr
---
## 77. RAG CALCULATOR PAGE COMPLETE (RagCalculatorPage.jsx)
### 77.1 Settings Panel
bg #FAF7F0, border 1px #E4DDD2, borderRadius 10, padding 18
**Grid:** `repeat(auto-fit, minmax(180px, 1fr))`, gap 16
**Labels:** fontSize 12, color #5F6B6D, display block, marginBottom 5
**Number inputs:** width 100%, padding 10px 12px, border 1px #D8D0C4, borderRadius 8, fontSize 14, Vazirmatn
### 77.2 Results Section
**Summary stats:** `gridTemplateColumns: repeat(3, 1fr)`, gap 12
**Stat card:** bg #FAF7F0, border 1px #E4DDD2, borderRadius 8, padding 12, textAlign center
- Label: fontSize 11, color #5F6B6D
- Value: fontSize 16, fontWeight 800, color #0F2A2E
**Chunk cards:** `flexDirection: column; gap: 14`
- Header: bg #FAF7F0, borderBottom 1px #E4DDD2, padding 10px 16px, flex space-between
- Chunk label: fontSize 12, fontWeight 800, color #0F2A2E
- Copy button: bg #fff, border 1px #D8D0C4, borderRadius 4, padding 3px 8px, fontSize 11
- Body: padding 16, fontSize 13, lineHeight 1.8, color #263238, bg #fff, whiteSpace pre-wrap
### 77.3 Buttons
Same as NLP: "محاسبه و شبیه‌سازی" + "بازگشت"
---
## 78. TEKRAG HUB PAGE (TekRagHubPage.jsx)
### 78.1 Purpose
Academic benchmark hub for Persian RAG evaluation with citations, links to HuggingFace, Zenodo, GitHub
### 78.2 Content
Static content from TeknavData + TekRAG article data
- Citation information (DOI, version)
- Links to external platforms
- Benchmark description and methodology
---
## 79. MEMBERSHIP PAGE COMPLETE
### 79.1 Header
H1: fontSize 32, fontWeight 900, color #263238
Subtitle: color #5F6B6D, lineHeight 1.9, marginBottom 28
### 79.2 Premium Status Banner
bg #0F6B7318, border 1px #0F6B7340, borderRadius 12, padding 16px 20px, marginBottom 28
Text: "✓ شما در حال حاضر عضو ویژه هستید" + expiry date
### 79.3 Feature Cards
**Grid:** `repeat(auto-fit, minmax(240px, 1fr))`, gap 16, marginBottom 32
Each card: bg #fff, border 1px #E4DDD2, borderRadius 12, padding 20
- Icon: fontSize 24, marginBottom 8
- Title: fontSize 18, color #263238
- Body: color #5F6B6D, lineHeight 1.8
### 79.4 Subscribe Button (non-premium only)
`background: linear-gradient(135deg, #D49A2A, #B8821E); color: #fff; border: none; borderRadius: 10; padding: 14px 36px; fontSize: 16; fontWeight: 700`
- Normal: "شروع عضویت ویژه"
- Loading: "در حال اتصال به درگاه..." (opacity 0.7)
### 79.5 Membership Success Page
Crown emoji 56px, h1 "عضویت ویژه فعال شد!" fontSize 26, body text, home button (pillBtn bg #0F6B73)
---
## 80. SERIES PAGE COMPLETE
### 80.1 Layout
maxWidth 960, margin auto, padding 40px 24px
Back button: pillBtn, bg #F4EFE6, color #0F6B73, border 1px #E4DDD2
H1: fontSize 30, fontWeight 900, color #263238
Description: color #5F6B6D, fontSize 15, lineHeight 1.9
### 80.2 Article List
**Grid:** gap 14
Each row: `gridTemplateColumns: 44px 1fr`, gap 14, alignItems start
Position circle: 36px, borderRadius 999, bg #0F6B73, color #fff, display grid placeItems center, fontWeight 900
### 80.3 States
- Loading: "در حال بارگذاری..." — min-height 60vh, centered
- Error: `<EmptyState title="سری مقاله پیدا نشد" subtitle="این مجموعه در API وجود ندارد یا هنوز منتشر نشده است." />`
- Empty articles: `<EmptyState title="هنوز مقاله‌ای در این سری نیست" />`
---
## 81. NEWSLETTER PAGES COMPLETE
### 81.1 NewsletterArchivePage
**H1:** fontSize 32, fontWeight 900, color #263238, "آرشیو خبرنامه تکنـاو"
**List items:** bg #fff, border 1px #E4DDD2, borderRadius 10, padding 18, cursor pointer
- Subject: fontSize 18, fontWeight 800, color #263238
- Date: color #5F6B6D, fontSize 12
**Loading:** "در حال بارگذاری..."
**Empty:** `<EmptyState title="هنوز خبرنامه‌ای منتشر نشده است" />`
### 81.2 NewsletterIssuePage
**Content body:** fontSize 16, lineHeight 2, color #263238, bg #fff, border 1px #E4DDD2, borderRadius 12, padding 24, dangerouslySetInnerHTML
**H1:** fontSize 30, fontWeight 900, color #263238, lineHeight 1.45
**Date:** color #5F6B6D, fontSize 12, marginBottom 28
**Error:** `<EmptyState title="خبرنامه پیدا نشد" />`
---
## 82. MEMBERSHIP SUCCESS PAGE (MembershipSuccessPage.jsx)
**Layout:** centered flex, min-height 100vh
**Content:** maxWidth 480, textAlign center
- Crown emoji: fontSize 56, marginBottom 16
- H1: fontSize 26, fontWeight 900, color #263238, marginBottom 12
- Body: color #5F6B6D, lineHeight 1.9, marginBottom 28
- Button: pillBtn bg #0F6B73, color #fff, padding 12px 28px, fontSize 14, text "بازگشت به خانه"
---
## 83. JOBS PAGE COMPLETE
### 83.1 Layout
**Grid:** `1fr 360px`, gap 22, responsive at 850px → 1fr
**H1:** fontSize 32, fontWeight 900, "فرصت‌های شغلی فناوری"
### 83.2 Job Cards
bg #fff, border 1px #E4DDD2, borderRadius 12, padding 18
- Title: fontSize 18, color #263238
- Company: color #0F6B73, fontWeight 800, fontSize 13
- Location: color #5F6B6D, fontSize 12, "Remote" or city
- Description: color #5F6B6D, lineHeight 1.8, fontSize 13
- URL: color #0F6B73, fontWeight 800, "مشاهده و ارسال رزومه"
**Empty:** `<EmptyState title="هنوز آگهی منتشرشده‌ای وجود ندارد" />`
### 83.3 Job Submission Form
bg #fff, border 1px #E4DDD2, borderRadius 12, padding 18, alignSelf start
- H2: fontSize 17, color #263238, "ثبت آگهی شرکت"
- Inputs: inputStyle, various placeholders
- Remote checkbox: label flex gap 8, fontSize 13, color #263238
- Textarea: inputStyle + minHeight 110, resize vertical
- Submit: pillBtn bg #0F6B73, color #fff, text "ارسال برای بررسی" / "در حال ارسال..."
---
## 84. COURSES PAGE COMPLETE
### 84.1 Layout
maxWidth 1040, padding 40px 24px
**Grid:** `repeat(auto-fit, minmax(260px, 1fr))`, gap 16
**H1:** fontSize 32, fontWeight 900, "دوره‌های تخصصی تکناو"
### 84.2 Course Cards
bg #fff, border 1px #E4DDD2, borderRadius 12, padding 20
- Level: color #0F6B73, fontSize 12, fontWeight 800, marginBottom 8
- Title: color #263238, fontSize 19
- Summary: color #5F6B6D, lineHeight 1.9, fontSize 13
- Price: color #D49A2A, fontWeight 900, "X تومان" or "به‌زودی"
---
## 85. LEGAL PAGES COMPLETE
### 85.1 LegalPage Shell
**Wrapper:** paddingTop 88, paddingBottom 80, bg #FAF7F0, minHeight 100vh, Vazirmatn, direction rtl
**Inner:** maxWidth 820, margin auto, padding 0 24px
**Header:** marginBottom 40
- H1: fontSize 28, fontWeight 800, color #0F2A2E, fontFamily PelakFA
- Subtitle: fontSize 14, color #5F6B6D, lineHeight 1.8
- Gold bar: height 3, width 48, bg #D49A2A, borderRadius 2, marginTop 16
**Content card:** bg #fff, border 1px #E4DDD2, borderRadius 12, padding 36px 40px, lineHeight 1.95, color #374549, fontSize 14
### 85.2 LegalSection
marginBottom 32
H2: fontSize 16, fontWeight 700, color #0F2A2E, marginBottom 10, borderRight 3px solid #0F6B73, paddingRight 10
### 85.3 Privacy Policy (7 sections)
Section titles: اطلاعاتی که جمع‌آوری می‌کنیم, نحوه استفاده از اطلاعات, کوکی‌ها و ذخیره‌سازی محلی, امنیت اطلاعات, حقوق کاربر, تغییرات در این سیاست, تماس
List style: disc, paddingRight 20
### 85.4 Terms of Use (8 sections)
Section titles: پذیرش شرایط, محتوا و مالکیت معنوی, حساب کاربری, رفتار کاربران, سلب مسئولیت, تغییر خدمات, قانون حاکم, تماس
### 85.5 About Page (6 sections)
Section titles: تکناو چیست؟, حوزه‌های تخصصی, رویکرد ما, تیم, اطلاعات تماس
Domain list: 6 areas with #0F6B73 dot indicators (8px circle, 50% radius)
Buttons: "مشاهده تیم نویسندگان" (teal filled) + "تماس با ما" (teal outline)
---
## 86. DASHBOARD CATEGORY STATS (DashboardCategoryStats.jsx)
**Container:** white bg, 12px radius, 24px padding
**Each category row:** flex space-between, padding 8px 0, borderBottom 1px #E4DDD2
- Name: fontSize 13, color #263238
- Bar: width calculated (max(count*2, 20)), height 6px, bg category color or #0F6B73, borderRadius 3px, opacity 0.7
- Count: fontSize 12, color #5F6B6D
---
## 87. DASHBOARD TOP ARTICLES (DashboardTopArticles.jsx)
Each article: full-width button, bg transparent, borderBottom 1px #E4DDD2, padding 10px 0, textAlign right
- Title: fontSize 13, fontWeight 700, color #263238, lineHeight 1.6
- Meta: fontSize 11, color #5F6B6D, marginTop 2
- On click: navigate to /article/{slug}
---
## 88. LIVE ADMIN FEED SSE STREAM
**Endpoint:** `/api/v1/admin/stream`
**Event types:** `activity`, `view_update`, `visitor_update`
**Live metrics:** count (total visits), guests, users, commentsPerMin
**Up to 50 recent activity events** stored in state
**15-second auto-refresh** for panel metrics
---
## 89. PRESENCE TRACKING IN EDITOR
**Heartbeat:** POST `/api/v1/admin/articles/:id/heartbeat` every 30 seconds
**Editors list:** GET `/api/v1/admin/articles/:id/presence` every 30 seconds
**UI indicator:** "X نفر دیگر در حال ویرایش" — displayed when >1 editor
- Container: `background: #FFF8F0; border: 1px solid #F5C97A; borderRadius: 20; padding: 4px 10px; fontSize: 11; color: #7A5A00`
- Editor avatars: `width: 22px; height: 22px; borderRadius: 50%; background: #E07A3A; color: #fff; fontSize: 9; fontWeight: 800; border: 2px solid #fff`
---
## 90. SSE STREAMS SUMMARY
| Stream | Endpoint | Events | Usage |
|---|---|---|---|
| Admin live | `/api/v1/admin/stream` | activity, view_update, visitor_update | LiveAdminFeed, RoleMetricsPanel |
| Notification | `/api/v1/auth/notifications/stream` | notification | NotificationBell |
| View updates | `/api/v1/admin/stream` | view_update (articleId + views) | ArticlesManagement table |
---
## 91. COMPLETE RESPONSIVE LAYOUT CHANGES
### Breakpoint Summary Table
| Breakpoint | Layout Change | Components Affected |
|---|---|---|
| 980px | Editor grid → single column | ArticleEditor, ArtifactStudio |
| 900px | TOC hidden, article → single column | ArticleDetail (TekRAG) |
| 880px | Brand panel hidden, mobile logo shown | AuthPage |
| 850px | Glossary grid → single column | GlossaryPage |
| 850px | Jobs grid → single column | JobsPage |
| 768px | Desktop nav hidden, hamburger shown | Header |
| 768px | Category hero → single column | CategoryPage |
| 768px | Search layout → single column | SearchPage |
| 768px | Dashboard 2-col → 1-col | AdminDashboard |
| 768px | Sidebar hidden (overlay) | AdminSidebar |
| 640px | Sidebar fixed overlay | AdminSidebar mobile |
| 640px | Desktop header nav items hidden | Header nav |
| 640px | Mobile drawer at bottom | MobileDrawer |
| 560px | All aggressive mobile adjustments | Everything |
| 620px | EN article grid → 1 column | EnglishHomePage |
## 92. CSS MEDIA QUERY UTILITY CLASSES
```css
.desktop-nav { display: flex !important; } /* Desktop: show */
.mobile-menu-btn { display: none !important; } /* Desktop: hide */
@media (max-width: 768px) {
.desktop-nav { display: none !important; }
.mobile-menu-btn { display: flex !important; }
}
```
---
## 93. INLINE STYLE INJECTIONS
| Component | Purpose | Approx Lines |
|---|---|---|
| teknav-ui.jsx Header | Nav responsive, keyframes, scrollbar | 15 |
| teknav-home.jsx HomePage | heroReveal keyframe, responsive | 12 |
| teknav-home.jsx HeroSection | heroReveal keyframe | 5 |
| teknav-articles.jsx ArticleDetail | articleCSS (full article styling), responsive | 95 |
| teknav-articles.jsx ArticleDetail | TekRAG LTR overrides, responsive | 50 |
| teknav-auth.jsx LoginPage | AuthStyles (animations, layout, inputs) | 60 |
| teknav-pages.jsx SearchPage | search-layout responsive | 1 |
| teknav-pages.jsx GlossaryPage | glossary-grid responsive | 1 |
| teknav-pages.jsx CategoryPage | cat-hero-grid responsive | 1 |
| teknav-pages.jsx JobsPage | jobs-grid responsive | 1 |
| teknav-pages.jsx TopicHubPage | (none inline) | 0 |
| teknav-profile.jsx UserProfilePage | profile responsive | 6 |
| teknav-home.jsx HomePage | featured-card responsive | 10 |
| admin/Dashboard.jsx AdminPanel | dash-grid + sidebar responsive | 15 |
---
## 94. KEYBOARD SHORTCUTS
| Shortcut | Action | Context |
|---|---|---|
| Ctrl+B | Bold (`<strong>`) | HtmlEditor textarea |
| Ctrl+I | Italic (`<em>`) | HtmlEditor textarea |
| Ctrl+S | Save article | ArticleEditor |
| Escape | Close modal | All modals (Confirm, ForgotPassword, Settings, QuoteSharer, ReadingList) |
| Enter (on input) | Submit search | Search bar, search form |
| Enter (on captcha input) | N/A | CAPTCHA (no enter handler) |
---
## 95. DEPENDENCY INJECTION PATTERN
### 95.1 Provider Nesting (teknav-app.jsx)
```
<Root>
<NavProvider> ← SPA router (useNav)
<AuthProvider> ← Backend auth (useAuth)
<ToastProvider> ← Toast notifications (useToast)
<InnerApp>
<SeoManager /> ← Head SEO meta
<Header /> ← Conditionally hidden
<main>{renderPage()}</main>
<Footer /> ← Conditionally hidden
<InstallPrompt /> ← PWA install
<PushNotificationPrompt /> ← Push subscribe
</InnerApp>
</ToastProvider>
</AuthProvider>
</NavProvider>
</Root>
```
Note: The `App` component (line 17) is a DUAL provider stack that is NOT used in production. The actual mount chain is `Root` → `InnerApp`.
### 95.2 Context Hooks
| Hook | Returns | Provided By |
|---|---|---|
| `useNav()` | `{ page, navigate }` | NavProvider |
| `useAuth()` | `{ user, login, signup, logout, refreshMe, bootstrapping, verifyTwoFactor, startOAuth }` | AuthProvider |
| `useToast()` | `add(msg, type)` | ToastProvider |
---
## 96. DATA ATTRIBUTES ON DOM ELEMENTS
| Attribute | Value | Usage |
|---|---|---|
| `data-lang` | language name | Code blocks (e.g., "javascript") |
| `data-teknav-seo="jsonld"` | — | JSON-LD script tags for easy removal |
| `data-teknav-seo-list="true"` | — | Citation reference meta elements for easy removal |
---
## 97. DOCUMENT HEAD MANIPULATION (SeoManager)
**Elements created/updated on each page change:**
- `<meta name="description">`
- `<meta name="keywords">`
- `<meta name="robots">`
- `<meta name="googlebot">`
- `<meta name="bingbot">`
- `<meta name="author">`
- `<meta name="language">`
- `<meta name="citation_*">` (up to 20 citation references)
- `<meta name="DC.*">`
- `<meta property="og:*">` (7 tags)
- `<meta name="twitter:*">` (4 tags)
- `<link rel="canonical">`
- `<link rel="alternate" hreflang="...">`
- `<script type="application/ld+json">` (single @graph containing all schemas)
- `document.title`
- `document.documentElement.lang`
- `document.documentElement.dir`
**Cleanup:** Previous SEO elements are identified and removed before injection via:
- Meta tags: identified by `name` or `property` attribute
- Link tags: `rel="canonical"` and `rel="alternate"` replaced
- JSON-LD: identified by `data-teknav-seo="jsonld"`
- Citation references: identified by `data-teknav-seo-list="true"`
---
## 98. GRADIENT COLORS USED IN CANVAS (HeroBackground)
Three canvas neural network animations use these rgba color bases:
- `rgba(15,107,115,` — Deep teal (brand)
- `rgba(196,106,77,` — Terracotta
- `rgba(47,143,107,` — Warm green
32 nodes total, colors cycle through the 3-color palette.
---
## 99. THREE.JS 3D SCENE SETUP (TekRagThree)
**Renderer:** WebGLRenderer, antialias: true, alpha: true, pixelRatio capped at 2, SRGBColorSpace
**Camera:** PerspectiveCamera(45, aspect, 0.1, 100)
**Lighting:**
- AmbientLight(0xffffff, 0.7)
- DirectionalLight(0xffffff, 1.4)
- DirectionalLight(0xd49a2a, 0.8) — gold rim light
**Materials:** MeshStandardMaterial
- Roughness: 0.48
- Metalness: 0.12
**Colors (hex for Three.js):**
- teal: 0x0f6b73
- gold: 0xd49a2a
- clay: 0xc76d4a
- green: 0x2f8f6b
- ink: 0x20343a
- line: 0xe4ddd2
- red: 0xc94c4c
- cream: 0xf4efe6
**Interaction:**
- Raycaster for hover detection
- Drag rotation via pointer events
- Auto-rotation: 0.003 rad/frame (lerp factor 0.08)
**Canvas background:** `radial-gradient(circle at 50% 20%, #ffffff 0%, #f4efe6 42%, #e9f2f2 100%)`
---
## 100. SITE-WIDE STATIC ASSET INVENTORY
### 100.1 Fonts (all self-hosted)
| File | Type | Weight |
|---|---|---|
| Vazirmatn-Regular.ttf | TrueType | 400 |
| Vazirmatn-Medium.ttf | TrueType | 500 |
| Vazirmatn-SemiBold.ttf | TrueType | 600 |
| Vazirmatn-Bold.ttf | TrueType | 700 |
| Vazirmatn-ExtraBold.ttf | TrueType | 800 |
| Vazirmatn-Black.ttf | TrueType | 900 |
| PelakFA-Bold.woff | WOFF | 700 |
| PelakFA-ExtraBold.woff | WOFF | 800 |
| FiraCode-*.woff2 | WOFF2 | Multiple |
| FiraMono-*.woff2 | WOFF2 | Multiple |
### 100.2 Icons (SVG, 34 files)
bell, book-open, bookmark, bot, chart-column, clipboard-copy, crown, database, eye, flame, globe, graduation-cap, heart, image, laptop, library, lightbulb, link, lock, mail, map-pin, medal, pen-line, pencil, ruler, scroll, settings, share-2, sprout, square-pen, star, thumbs-up, triangle-alert, waves, zap
### 100.3 OG Images (JPG, 37 files)
Generated at build time: `/images/og/{slug}.jpg` — one per article + default.jpg
### 100.4 Avatars (PNG, 3 files)
avatar-ahmadreza.png, avatar-arsam.png, avatar-radman.png
### 100.5 Sitemap Files (XML, 8 files)
sitemap.xml, sitemap-articles.xml, sitemap-companies.xml, sitemap-comparisons.xml, sitemap-en.xml, sitemap-main.xml, sitemap-news.xml, sitemap-stories.xml
### 100.6 Feed Files (XML, 10 files)
feed.xml, feeds/author-mahjoob.xml, feeds/author-radman-ghelichi.xml, feeds/author-sabbagh.xml, feeds/topic-ai.xml, feeds/topic-data.xml, feeds/topic-hardware.xml, feeds/topic-security.xml, feeds/topic-software.xml, feeds/topic-startup.xml
---
## 101. COMPLETE COMPONENT TREE HIERARCHY
```
index.html
└── main.jsx (imports global.css + teknav-app.jsx)
└── createRoot(#root).render(<Root />)
├── NavProvider
│ └── AuthProvider
│ └── ToastProvider
│ └── InnerApp
│ ├── SeoManager (null render)
│ ├── Header (conditional)
│ │ ├── Logo button
│ │ ├── Desktop nav (9 items)
│ │ ├── Search icon + search bar
│ │ ├── NotificationBell
│ │ │ └── Notification dropdown
│ │ ├── Admin/Profile/Logout buttons (auth)
│ │ └── Login button (anon)
│ └── Mobile Drawer
│ ├── <main> → renderPage()
│ │ ├── HomePage
│ │ │ ├── StreakWidget (auth)
│ │ │ ├── ContinueReadingBar (auth)
│ │ │ ├── HeroSection
│ │ │ │ ├── HeroBackground (canvas)
│ │ │ │ ├── CTA buttons
│ │ │ │ └── FeaturedArticle
│ │ │ ├── StatsBar + CountUp
│ │ │ ├── Personalized Feed (ArticleCard grid)
│ │ │ ├── Featured Article section
│ │ │ ├── Latest Articles (grid)
│ │ │ ├── Deep Analyses (ArticleRowCompact)
│ │ │ ├── Popular (grid)
│ │ │ ├── Categories grid
│ │ │ ├── AuthorsSection
│ │ │ └── NewsletterForm
│ │ ├── EnglishHomePage
│ │ ├── ArticleListPage
│ │ │ ├── Search input
│ │ │ ├── FilterBar
│ │ │ └── ArticleRow (list)
│ │ ├── ArticleDetail
│ │ │ ├── ReadingProgress
│ │ │ ├── Breadcrumb
│ │ │ ├── TableOfContents (sidebar)
│ │ │ ├── Article Header (badges, h1, byline, actions)
│ │ │ ├── CorrectionNotice
│ │ │ ├── HeroDiagram (LazyDiagram)
│ │ │ ├── Article Content (dangerouslySetInnerHTML)
│ │ │ ├── PremiumGateCard (if locked)
│ │ │ ├── QuoteSharer
│ │ │ ├── EmbeddedDiagrams
│ │ │ ├── Reaction row
│ │ │ ├── SeriesNavBanner
│ │ │ ├── Tags
│ │ │ ├── ArticleCommentSection
│ │ │ ├── ArticleQaSection
│ │ │ ├── Author Box
│ │ │ └── Related Articles (ArticleCard grid)
│ │ ├── SearchPage
│ │ ├── CategoryPage
│ │ ├── TagPage
│ │ ├── GlossaryPage
│ │ ├── TopicHubPage
│ │ ├── AuthorsListPage
│ │ ├── SeriesPage
│ │ ├── AuthorProfilePage (redirect)
│ │ ├── UserProfilePage
│ │ │ ├── AvatarUpload
│ │ │ ├── Hero Banner
│ │ │ ├── Stats Bar
│ │ │ ├── Badges Section
│ │ │ ├── Content Tabs (articles/analytics)
│ │ │ ├── WriterAnalyticsTab (+ Sparkline)
│ │ │ └── ProfileSettingsModal
│ │ │ ├── EditField
│ │ │ ├── Password change
│ │ │ ├── Email/Phone/2FA section
│ │ │ ├── Push toggle
│ │ │ └── NotificationPreferencesPanel
│ │ ├── LoginPage
│ │ │ ├── AuthStyles (scoped CSS)
│ │ │ ├── Mobile Logo
│ │ │ ├── Tab Switcher (login/signup)
│ │ │ ├── OAuthButtons
│ │ │ ├── LoginForm / SignupForm
│ │ │ │ ├── AuthInput
│ │ │ │ ├── PasswordStrength
│ │ │ │ ├── TeknavCAP
│ │ │ │ └── ForgotPasswordModal
│ │ │ └── BrandPanel
│ │ │ ├── Orbital Logo
│ │ │ ├── BrandTicker
│ │ │ └── CountUp stats
│ │ ├── AdminPanel
│ │ │ ├── AdminSidebar
│ │ │ ├── Topbar
│ │ │ └── Content (18 tabs)
│ │ │ ├── Dashboard (LiveAdminFeed, Stats, Activity, etc.)
│ │ │ ├── ArticlesManagement (table + actions)
│ │ │ ├── ArticleEditor (metadata + HtmlEditor + ArtifactStudio + RevisionDrawer)
│ │ │ ├── UserManagement (table + detail modal)
│ │ │ ├── AuthorsManagement (form + card grid)
│ │ │ ├── MediaLibrary (image grid)
│ │ │ ├── CommentsModeration (table + bulk actions)
│ │ │ ├── Analytics (SeoAudit, Engagement, Overview, Jobs, ClientErrors)
│ │ │ ├── ReviewsPanel
│ │ │ ├── NewsletterPanel
│ │ │ ├── SeriesManagementPanel
│ │ │ ├── CategoryManagement
│ │ │ ├── TagsManagement
│ │ │ └── ActivityLog
│ │ └── WriterWorkspace
│ │ ├── WritingTipCard
│ │ ├── WeeklyChart
│ │ ├── WriterAnalyticsPanel (table + sparklines)
│ │ └── Overview (stats + recent articles/comments)
│ ├── Footer (conditional)
│ │ ├── About section
│ │ ├── Categories links
│ │ ├── Tools links
│ │ ├── Links section
│ │ └── Contact section
│ ├── InstallPrompt (PWA)
│ └── PushNotificationPrompt
```
---
## 102. TOTAL SIZE & COMPLEXITY METRICS
| Metric | Count |
|---|---|
| Total lines of frontend JSX/JS | ~38,000+ across all source files |
| Number of React components | 200+ components |
| Named exports from all modules | 150+ |
| Number of routes (SPA) | 37 |
| Number of API endpoints consumed | 120+ |
| Number of diagram types | 210 (18 base + 192 generated) |
| Number of CSS keyframe animations | 20+ |
| Number of CSS inline `<style>` injections | 15+ sites |
| Number of JSON-LD schema types | 15+ |
| Number of meta tags injected | 30+ |
| Number of hex color values used | 200+ distinct |
| Number of SVG icons | 34 |
| Number of self-hosted font files | 16 |
| Number of OG images | 37 |
| Number of feed XML files | 10 |
| Number of sitemap XML files | 8 |
| Number of test cases | ~15 in lib tests |
| Number of widget types | 3 (glossary, article-card, company) |
---
## 103. LEGACY CODE & DEAD CODE REFERENCES
### 103.1 teknav-store.js
- All CRUD operations for articles, users, categories, tags are localStorage-based
- `login()` explicitly returns `null` with comment: "Auth now goes through /api/v1/auth/login — this stub stays for build safety"
- `DATA_VERSION = '2026-05-02-v1'` for cache busting
- Methods are synchronous
### 103.2 teknav-admin.jsx
Thin re-export file (1 line of logic): `export { AdminPanel, WriterWorkspace, actionBtn } from './src/admin/index.js';`
### 103.3 AuthorProfilePage (teknav-pages.jsx)
Immediately redirects to `/profile/@:username` via `useNavigate`. The full component is still defined with 60 lines of layout code but never actually renders because of the redirect.
### 103.4 App component (teknav-app.jsx)
The `App` function (lines 17-81) has its own provider stack (ToastProvider → AuthProvider → NavProvider) within the render, but the `Root` component (line 98) is what actually mounts. The `App` component appears to be dead code.
---
## 104. BUILD TIME GENERATED CONTENT
| Artifact | Path Prefix | Count |
|---|---|---|
| OG images | `/images/og/{slug}.jpg` | 37 |
| Static article pages | `/articles/{slug}/index.html` | 37 |
| Web stories | `/stories/{slug}/index.html` | 37 |
| Comparison pages | `/compare/{slug}/index.html` | 10 |
| Company pages | `/directory/{slug}/index.html` | 10 |
| English homepage | `/en/index.html` | 1 |
| Author pages | `/author/{slug}/index.html` | 3 |
| Sitemap XML | `/sitemap*.xml` | 8 |
| Robots.txt | `/robots.txt` | 1 |
| Feed XML | `/feed.xml`, `/feeds/*.xml` | 10 |
All generated by scripts in `/scripts/` during `npm run build`.
---
## 105. ERROR TRACKING PAYLOAD FORMAT
```json
{
"message": "Uncaught TypeError: ...",
"source": "https://teknav.ir/article/some-slug",
"stack": "Error stack trace...",
"path": "/article/some-slug",
"userAgent": "Mozilla/5.0..."
}
```
Sent via `navigator.sendBeacon('/api/v1/errors', blob)` or `fetch POST /api/v1/errors` with `keepalive: true`.
---
## THIS DOCUMENT IS COMPLETE.
**Total sections: 105**
**Total page types documented: 37**
**Total components documented: 200+**
**Total colors documented: 200+**
**Total API endpoints: 120+**
Every visible element of the Teknav frontend — from splash loader to footer, from homepage hero canvas to admin panel SEO audit, from login page orbital animations to article share buttons — has been exhaustively documented. Any UI designer reading this should be able to reconstruct the entire site pixel-perfectly without ever accessing the live URL.