Deploy: Complete TekDek documentation website with all content pages, CSS, and infrastructure
This commit is contained in:
76
publish/web1/README.md
Normal file
76
publish/web1/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# TekDek Documentation Site — PHP Framework
|
||||
|
||||
Built by **Talos** (Technical Coder, TekDek).
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
public/
|
||||
├── index.php — Main router (all requests)
|
||||
├── config.php — Menu structure, site settings, content mapping
|
||||
├── .htaccess — Apache URL rewriting
|
||||
├── includes/
|
||||
│ ├── top.php — HTML head, header, navigation
|
||||
│ ├── bottom.php — Footer, closing tags
|
||||
│ ├── menu.php — Navigation renderer (config-driven)
|
||||
│ └── functions.php — Markdown renderer, utilities
|
||||
├── pages/
|
||||
│ ├── home.php — Landing page with card grid
|
||||
│ ├── about.php — Vision & Strategy
|
||||
│ ├── projects.php — Active projects
|
||||
│ ├── tools.php — Tools & Tech stack
|
||||
│ ├── team.php — Links to team.html
|
||||
│ ├── decisions.php — Decision checklist
|
||||
│ └── 404.php — Error page
|
||||
├── css/
|
||||
│ ├── base.css — Colors, typography, resets
|
||||
│ ├── components.css — Header, nav, cards, buttons, footer
|
||||
│ └── responsive.css — Mobile/tablet breakpoints
|
||||
├── js/
|
||||
│ └── main.js — Mobile menu toggle
|
||||
├── content/ — Drop .md files here for auto-rendering
|
||||
└── assets/ — Images, icons
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. Point Apache/Nginx document root to `public/`
|
||||
2. Ensure `mod_rewrite` is enabled (Apache)
|
||||
3. Adjust `SITE_BASE_URL` in `config.php` if not at root
|
||||
|
||||
### Nginx Alternative
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
- **Routing**: All URLs go through `index.php` → matches slug against `$MENU` in `config.php` → loads `pages/{slug}.php`
|
||||
- **Content**: Pages can embed HTML directly or call `load_content('slug')` to render a markdown file from `content/`
|
||||
- **Navigation**: Rendered automatically from `$MENU` config — add/remove pages by editing one array
|
||||
- **Markdown**: Built-in renderer (no Composer, no dependencies) — supports headings, lists, code blocks, links, images, bold, italic, blockquotes
|
||||
- **404**: Unknown slugs get a clean 404 page
|
||||
|
||||
## Adding a Page
|
||||
|
||||
1. Add entry to `$MENU` in `config.php`
|
||||
2. Optionally add content mapping in `$CONTENT_MAP`
|
||||
3. Create `pages/{slug}.php` (or just drop a `.md` file in `content/`)
|
||||
|
||||
## For Icarus (CSS)
|
||||
|
||||
The CSS files are ready for customization:
|
||||
- `base.css` — CSS variables at `:root`, override colors/fonts here
|
||||
- `components.css` — All component styles, well-commented
|
||||
- `responsive.css` — Breakpoints at 768px and 480px
|
||||
|
||||
Dark theme variables are already set. The framework uses semantic class names throughout.
|
||||
|
||||
## Requirements
|
||||
|
||||
- PHP 7.4+
|
||||
- Apache with mod_rewrite (or Nginx with try_files)
|
||||
- No Composer, no external dependencies
|
||||
13
publish/web1/public/.htaccess
Executable file
13
publish/web1/public/.htaccess
Executable file
@@ -0,0 +1,13 @@
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# Don't rewrite real files or directories
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# Don't rewrite asset paths
|
||||
RewriteRule ^(css|js|assets)/ - [L]
|
||||
|
||||
# Route everything else to index.php
|
||||
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||
1
publish/web1/public/assets/.gitkeep
Executable file
1
publish/web1/public/assets/.gitkeep
Executable file
@@ -0,0 +1 @@
|
||||
# placeholder
|
||||
47
publish/web1/public/config.php
Normal file
47
publish/web1/public/config.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* TekDek Documentation Site - Configuration
|
||||
*
|
||||
* All site-wide settings, menu structure, and content mapping.
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('TEKDEK')) {
|
||||
die('Direct access not permitted.');
|
||||
}
|
||||
|
||||
// --- Site Settings ---
|
||||
define('SITE_TITLE', 'TekDek');
|
||||
define('SITE_DESCRIPTION', 'Documentation & Strategy Hub');
|
||||
define('SITE_BASE_URL', '/'); // Change if hosted in a subdirectory
|
||||
define('SITE_VERSION', '1.0.0');
|
||||
define('CONTENT_DIR', __DIR__ . '/content/');
|
||||
|
||||
// --- Menu Structure ---
|
||||
// Each entry: slug => [title, icon (optional), show_in_nav]
|
||||
$MENU = [
|
||||
'home' => ['title' => 'Home', 'icon' => '🏠', 'nav' => true],
|
||||
'about' => ['title' => 'About', 'icon' => '📖', 'nav' => true],
|
||||
'projects' => ['title' => 'Projects', 'icon' => '🚀', 'nav' => true],
|
||||
'tools' => ['title' => 'Tools', 'icon' => '🛠️', 'nav' => true],
|
||||
'team' => ['title' => 'Team', 'icon' => '👥', 'nav' => true],
|
||||
'decisions' => ['title' => 'Decisions', 'icon' => '✅', 'nav' => true],
|
||||
];
|
||||
|
||||
// --- Content Mapping ---
|
||||
// slug => markdown file (relative to CONTENT_DIR) or null for PHP-only pages
|
||||
$CONTENT_MAP = [
|
||||
'home' => null,
|
||||
'about' => 'about.md',
|
||||
'projects' => 'projects.md',
|
||||
'tools' => 'tools.md',
|
||||
'team' => null,
|
||||
'decisions' => 'decisions.md',
|
||||
];
|
||||
|
||||
// --- Page Titles (for <title> tag) ---
|
||||
function page_title(string $slug): string {
|
||||
global $MENU;
|
||||
$page = $MENU[$slug]['title'] ?? '404';
|
||||
return ($slug === 'home') ? SITE_TITLE . ' — ' . SITE_DESCRIPTION : $page . ' — ' . SITE_TITLE;
|
||||
}
|
||||
82
publish/web1/public/content/about.md
Executable file
82
publish/web1/public/content/about.md
Executable file
@@ -0,0 +1,82 @@
|
||||
# Vision & Strategy
|
||||
|
||||
TekDek is a **narrative-driven content platform** that aggregates and manages developer personas across multiple channels while driving engagement through interconnected storylines and high-quality educational content.
|
||||
|
||||
**Core thesis:** Technical education + Character-driven entertainment = sticky, differentiated community
|
||||
|
||||
## The Three Layers
|
||||
|
||||
### 1. Business Layer
|
||||
- **Multi-platform content management**: Track where each persona publishes (YouTube, TikTok, GitHub, personal sites, Stack Legion)
|
||||
- **Revenue model**: Membership tiers on Stack Legion, course/challenge monetization, persona-specific revenue streams
|
||||
- **Community engagement**: Member-exclusive content, challenges, gamification, cross-persona collaboration
|
||||
|
||||
### 2. Technical Layer
|
||||
- **Stack Legion Dev site**: Central hub article-based platform (under development)
|
||||
- **Persona agents**: Each persona has their own AI agent with distinct voice/personality
|
||||
- **Content syndication**: Personas publish independently; Stack Legion aggregates and curates
|
||||
- **Persona Portal**: Publishing and management system for persona content, brands, and identity
|
||||
|
||||
### 3. Narrative/Entertainment Layer
|
||||
- **Character arcs**: Personas are *characters* in an evolving story
|
||||
- **Conflict & drama**: Feuds, collaborations, team dynamics drive engagement
|
||||
- **Authenticity + Strategy**: Real technical knowledge + curated narrative = education that feels organic
|
||||
- **Storyline management**: Planned arcs that tie personas, content, and community together
|
||||
|
||||
## The Persona Model
|
||||
|
||||
### What Is a Persona?
|
||||
- Independent brand with own platform presence (YouTube, TikTok, personal site, GitHub)
|
||||
- Specialized expertise (frontend, backend, DevOps, etc.) or "learning journey" archetype
|
||||
- Distinct personality: quirks, voice, relationship dynamics with other personas
|
||||
- AI-powered agent for content generation + human curation
|
||||
- Character in a larger narrative (TekDek storyline)
|
||||
|
||||
### Key Properties
|
||||
- **Expertise**: What they teach (PHP, React, DevOps, etc.)
|
||||
- **Voice/Tone**: How they communicate
|
||||
- **Platform Presence**: Where they publish independently
|
||||
- **Relationships**: Allies, rivals, neutral parties within TekDek
|
||||
- **Personality Consistency**: Rules for maintaining character across posts
|
||||
|
||||
## The Narrative Engine
|
||||
|
||||
### Storyline Management
|
||||
**Purpose**: Drive long-term engagement through character arcs, conflicts, and plot beats.
|
||||
|
||||
**Structure**:
|
||||
- **Arcs** (3–6 month timelines): Feud between two personas, team collaboration, industry challenge
|
||||
- **Beats** (weekly/monthly): Specific conflict, resolution, or collaboration moment
|
||||
- **Content tie-ins**: Tutorial posts, rant blog posts, GitHub contributions that support the arc
|
||||
|
||||
### Example Arc
|
||||
1. Persona A (PHP expert) and Persona B (Node expert) disagree on a best practice
|
||||
2. They each publish educational content defending their position
|
||||
3. Community sides form, challenges emerge
|
||||
4. Mid-arc: They collaborate on a comparison article (unity moment)
|
||||
5. Resolution: New "hybrid" tutorial that bridges both approaches
|
||||
|
||||
## Target Audience & Use Cases
|
||||
|
||||
### Primary: Stack Legion Dev (Developers)
|
||||
- **Learning**: Tutorials, code challenges, expert-led education
|
||||
- **Community**: Engage with other developers, vote on challenges, earn points
|
||||
- **Entertainment**: Follow persona storylines, watch conflicts unfold, participate in meta-drama
|
||||
|
||||
### Secondary: Content Creators
|
||||
- **Independent publishing**: Personas manage their own platforms while leveraging Stack Legion
|
||||
- **Monetization**: Multiple revenue streams (membership share, courses, sponsorships, merchandise)
|
||||
- **Community**: Collaborate with other experts under the TekDek umbrella
|
||||
|
||||
### Tertiary: Brands & Sponsors
|
||||
- Partner with individual personas or the Stack Legion platform for credible tech education
|
||||
|
||||
## Replication Across Verticals
|
||||
|
||||
The model is designed to be **replicable across industries**:
|
||||
- **Stack Legion Dev** (current): Developer education + character drama
|
||||
- **DIY/Makers**: Tutorial creators teaching carpentry, electronics, 3D printing
|
||||
- **Fitness/Wellness**: Personal trainers and nutritionists under one brand
|
||||
- **Finance**: Financial experts/advisors with distinct philosophies
|
||||
|
||||
The core mechanics remain the same: personas, narrative arcs, community engagement, multi-platform presence.
|
||||
241
publish/web1/public/content/decisions.md
Executable file
241
publish/web1/public/content/decisions.md
Executable file
@@ -0,0 +1,241 @@
|
||||
# Critical Decisions Checklist
|
||||
|
||||
## Phase 0: Foundation (NOW — Week 4)
|
||||
|
||||
This week's decisions lock in everything needed for 12 weeks of confident execution.
|
||||
|
||||
### 🔴 DECISION 1: Brick's Technical Specialty
|
||||
**Why**: Templates his first articles, determines his voice in depth
|
||||
|
||||
**Status**: ⏳ **PENDING**
|
||||
|
||||
**Options**:
|
||||
- Backend (servers, databases, APIs)
|
||||
- Frontend (React, Vue, CSS, UX)
|
||||
- DevOps (deployment, infrastructure, containerization)
|
||||
- Full-stack (end-to-end development)
|
||||
- Architecture (system design, scalability)
|
||||
- Database design (data modeling, optimization)
|
||||
|
||||
**Action**: Pick one, finalizes his profile and content roadmap
|
||||
|
||||
**Deadline**: This week
|
||||
|
||||
---
|
||||
|
||||
### 🔴 DECISION 2: Initial Persona Roster (Personas 2–10)
|
||||
**Why**: Determines content calendar, arc participants, expertise mix
|
||||
|
||||
**Status**: ⏳ **PENDING**
|
||||
|
||||
**What we need**:
|
||||
- 5–9 persona sketches (name, expertise, rough voice idea)
|
||||
- Real people you know, or recruit during Phase 1?
|
||||
- Mix of expertise (ensure complementary skills)
|
||||
|
||||
**Example structure**:
|
||||
- Persona name
|
||||
- Technical specialty
|
||||
- Voice idea ("rough but relatable," "professional educator," "comedy-focused")
|
||||
- Platform presence (YouTube? Blog? GitHub?)
|
||||
|
||||
**Deadline**: End of Week 1
|
||||
|
||||
---
|
||||
|
||||
### 🔴 DECISION 3: First Narrative Arc
|
||||
**Why**: Drives all content scheduling and engagement
|
||||
|
||||
**Status**: ⏳ **PENDING**
|
||||
|
||||
**Options**:
|
||||
- **Conflict arc**: Persona A (PHP expert) vs. Persona B (Node expert) — which is better?
|
||||
- **Learning journey arc**: New persona builds in public, learns on camera
|
||||
- **Collaboration arc**: Multiple personas team up to build something
|
||||
- **Drama arc**: Personal storyline (career change, comeback story)
|
||||
- **Other custom arc**: Your idea!
|
||||
|
||||
**What's needed**:
|
||||
- Arc title
|
||||
- Main characters involved
|
||||
- 3–6 month timeline
|
||||
- Key beats (monthly story moments)
|
||||
- Content tie-ins (which articles support this story)
|
||||
- Engagement hooks (why will users care?)
|
||||
|
||||
**Deadline**: End of Week 2
|
||||
|
||||
---
|
||||
|
||||
### 🔴 DECISION 4: Revenue Model
|
||||
**Why**: Dev team needs this to build payment processing
|
||||
|
||||
**Status**: ⏳ **PENDING**
|
||||
|
||||
**Decisions needed**:
|
||||
- **Membership tiers**: Free / $5/mo / $15/mo? What's included?
|
||||
- **Courses**: One-time purchase? Pricing ($29–$99)?
|
||||
- **Persona revenue share**: 70/30 split? 80/20? What cuts to TekDek?
|
||||
- **Sponsorships**: Per-article? Seasonal? Partner discounts?
|
||||
- **Challenge rewards**: Premium users only? Paid challenges?
|
||||
|
||||
**Deadline**: End of Week 3
|
||||
|
||||
---
|
||||
|
||||
### 🔴 DECISION 5: Launch Target Date
|
||||
**Why**: Everything else is scheduled around this
|
||||
|
||||
**Status**: ⏳ **PENDING**
|
||||
|
||||
**Options**:
|
||||
- Q3 2026 (July–September)
|
||||
- Q4 2026 (October–December)
|
||||
- Early 2027 (January–March)
|
||||
- Flexible/TBD
|
||||
|
||||
**Why it matters**: Determines sprint length, dev team roadmap, Phase 1/2/3 timing
|
||||
|
||||
**Deadline**: End of Week 4
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Foundational Development (Week 5–12)
|
||||
|
||||
### ⏸️ CHECKPOINT 6: Voice Consistency Validation (Week 8)
|
||||
**Decision**: Does Brick's voice actually work across platforms?
|
||||
|
||||
**Why**: If not, we pivot before scaling to other personas
|
||||
|
||||
**Validation criteria**:
|
||||
- [ ] 2–3 Brick articles published (blog, tutorial, opinion)
|
||||
- [ ] Consistent voice across platforms (blog, social media, code comments)
|
||||
- [ ] Reader feedback positive (comments, shares, engagement)
|
||||
- [ ] Technical accuracy verified
|
||||
|
||||
**If voice works**: Proceed with personas 2–3, confident in scaling
|
||||
|
||||
**If voice fails**: Adjust Brick profile, try different approach
|
||||
|
||||
---
|
||||
|
||||
### ⏸️ CHECKPOINT 7: Arc 1 Engagement (Week 10)
|
||||
**Decision**: Is the narrative arc driving user engagement?
|
||||
|
||||
**Why**: If not, we adjust narrative strategy before Phase 2
|
||||
|
||||
**Engagement metrics**:
|
||||
- [ ] Views per article (target: 1K+)
|
||||
- [ ] Comments per article (target: 20+)
|
||||
- [ ] User retention (target: 40%+ repeat readers)
|
||||
- [ ] Social shares (target: 100+ per major post)
|
||||
|
||||
**If arc engages**: Proceed to Phase 2 with confidence
|
||||
|
||||
**If arc is flat**: Try different conflict, different personas, or pivot narrative strategy
|
||||
|
||||
---
|
||||
|
||||
### ⏸️ CHECKPOINT 8: Go/No-Go for Phase 2 (Week 12)
|
||||
**Decision**: Ready to launch MVP to public?
|
||||
|
||||
**Why**: This is the major go/no-go moment for public beta
|
||||
|
||||
**Success criteria**:
|
||||
- ✅ 3 personas with proven voice consistency
|
||||
- ✅ 8–10 quality articles published
|
||||
- ✅ Arc 1 showing engagement
|
||||
- ✅ Portal MVP complete and tested
|
||||
- ✅ APIs operational and documented
|
||||
- ✅ Content monitor tracking publications
|
||||
- ✅ Curation workflow proven
|
||||
|
||||
**If all criteria met**: Launch Phase 2
|
||||
|
||||
**If criteria not met**: Extend Phase 1, address gaps
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: MVP Launch (Week 13–16)
|
||||
|
||||
### ⏸️ CHECKPOINT 9: MVP Success Metrics (Week 16)
|
||||
**Decision**: Did MVP launch meet success criteria?
|
||||
|
||||
**Metrics to review**:
|
||||
- [ ] 500+ registered members (target)
|
||||
- [ ] 100+ challenge participants
|
||||
- [ ] Arc 2 engagement (comments, participation)
|
||||
- [ ] Revenue conversion (50%+ to membership)
|
||||
- [ ] Site stability (99.5%+ uptime)
|
||||
|
||||
**If metrics healthy**: Proceed to Phase 3 scale
|
||||
|
||||
**If metrics poor**: Reassess product-market fit, gather user feedback, potentially pivot
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Scale & Iteration (Week 17–24)
|
||||
|
||||
### ⏸️ CHECKPOINT 10: Vertical 2 Launch Go/No-Go (Week 21)
|
||||
**Decision**: Is DIY/Fitness/Finance vertical ready to launch?
|
||||
|
||||
**Why**: Critical validation that replication template works
|
||||
|
||||
**Evaluation criteria**:
|
||||
- [ ] 3–5 personas for vertical 2 onboarded
|
||||
- [ ] Voice consistency across new domain
|
||||
- [ ] First arc planned and ready
|
||||
- [ ] Portal ready for multi-vertical support
|
||||
- [ ] Marketing plan for vertical 2 launch
|
||||
|
||||
**If template replicates well**: Proceed with vertical 2 expansion
|
||||
|
||||
**If replication struggles**: Refine template, extend timeline, or select different vertical
|
||||
|
||||
---
|
||||
|
||||
## Decision Log
|
||||
|
||||
```
|
||||
PHASE 0 (THIS WEEK)
|
||||
[ ] 1. Brick's specialty — PENDING
|
||||
[ ] 2. Initial persona roster (5–9) — PENDING
|
||||
[ ] 3. First narrative arc — PENDING
|
||||
[ ] 4. Revenue model — PENDING
|
||||
[ ] 5. Launch target date — PENDING
|
||||
|
||||
PHASE 1
|
||||
[ ] 6. Voice consistency validation — CHECKPOINT WEEK 8
|
||||
[ ] 7. Arc 1 engagement — CHECKPOINT WEEK 10
|
||||
[ ] 8. Go/no-go for Phase 2 — CHECKPOINT WEEK 12
|
||||
|
||||
PHASE 2
|
||||
[ ] 9. MVP success metrics — CHECKPOINT WEEK 16
|
||||
|
||||
PHASE 3
|
||||
[ ] 10. Vertical 2 launch readiness — CHECKPOINT WEEK 21
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How Decisions Flow
|
||||
|
||||
Each decision unlocks the next phase:
|
||||
|
||||
1. **Brick's specialty** → Determines his first content, tests voice consistency
|
||||
2. **Persona roster** → Enables arc planning, content calendar drafting
|
||||
3. **First arc** → Drives Phase 1 content production
|
||||
4. **Revenue model** → Dev team builds payment + analytics systems
|
||||
5. **Launch date** → Entire timeline cascades from this commitment
|
||||
|
||||
**If any decision slips, all downstream work is blocked.**
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
**For Glytcht**: Reply with Decisions 1–3 (Brick specialty, personas, first arc)
|
||||
|
||||
Once locked, ParzivalTD finalizes all profiles, narrative framework, and content calendar for Phase 1 execution.
|
||||
|
||||
**Then we're off to the races.**
|
||||
175
publish/web1/public/content/projects.md
Executable file
175
publish/web1/public/content/projects.md
Executable file
@@ -0,0 +1,175 @@
|
||||
# Active Projects & Roadmap
|
||||
|
||||
## Master Roadmap
|
||||
|
||||
TekDek operates on a phased timeline with two parallel execution tracks:
|
||||
|
||||
| Track | Owner | Deliverable | Purpose |
|
||||
|-------|-------|-------------|---------|
|
||||
| **Development** | External Dev Team | Article publishing platform, community, APIs | Content delivery, monetization, user engagement |
|
||||
| **Management** | TekDek | Persona roster, narrative engine, content monitoring | Character operations, storyline tracking, curation |
|
||||
|
||||
```
|
||||
Phase 0: Discovery & Planning (NOW)
|
||||
↓ (Week 4)
|
||||
Phase 1: Foundational Development (Week 5–12)
|
||||
↓ (Week 12)
|
||||
Phase 2: MVP Launch (Week 13–16)
|
||||
↓ (Week 16)
|
||||
Phase 3: Scale & Iteration (Week 17–24)
|
||||
↓ (Week 24)
|
||||
Phase 4: Expansion (Week 25+)
|
||||
```
|
||||
|
||||
## Phase 0: Discovery & Planning (NOW)
|
||||
|
||||
### Purpose
|
||||
Lock in product definition, persona prototypes, narrative framework, and team specifications before major development begins.
|
||||
|
||||
### Current Deliverables
|
||||
- ✅ TekDek Strategy & Vision
|
||||
- ✅ Master Project Plan
|
||||
- ✅ Tool Requirements
|
||||
- 🔄 Persona System (Brick prototype, 5–9 additional persona sketches)
|
||||
- 🔄 Narrative Framework & First Arc Definition
|
||||
- 🔄 Decision Checkpoints & Timeline
|
||||
|
||||
### Key Decisions This Week
|
||||
1. **Brick's Technical Specialty** — Templates his voice, determines first content
|
||||
2. **Initial Persona Roster** — 5–10 people for wave 1
|
||||
3. **First Narrative Arc** — What drives engagement in early phase
|
||||
4. **Revenue Model** — Membership tiers, course pricing, persona share %
|
||||
5. **Launch Target** — Q3? Q4 2026? Firm commitment needed
|
||||
|
||||
## Phase 1: Foundational Development (Week 5–12)
|
||||
|
||||
### Purpose
|
||||
Build core systems, test persona voice consistency, begin content production, establish the content/narrative feedback loop.
|
||||
|
||||
### Management Deliverables
|
||||
- **Persona System**: Build roster tracker in OpenClaw (profile, voice guide, relationships, narrative state)
|
||||
- **Narrative System**: Arc tracker, content calendar, storyline planning tool
|
||||
- **Content Monitoring**: Track publications, engagement, voice consistency
|
||||
- **Content Production**: Publish 8–10 articles (Brick, personas 2–3)
|
||||
- **Analytics**: Arc performance metrics, voice consistency feedback
|
||||
|
||||
### Development Deliverables
|
||||
- **Portal MVP Build**: Auth, publishing interface, article display, community features skeleton
|
||||
- **API Development**: Persona API, content sync, analytics, narrative endpoints
|
||||
- **Integration Readiness**: Test data flow between OpenClaw and Portal
|
||||
|
||||
### Success Criteria
|
||||
- ✅ 3 personas fully onboarded with consistent voices
|
||||
- ✅ 8–10 articles published with proven quality
|
||||
- ✅ Arc 1 live and showing engagement
|
||||
- ✅ Content monitor tracking all publications
|
||||
- ✅ Portal MVP ready for Phase 2
|
||||
- ✅ APIs operational and tested
|
||||
|
||||
## Phase 2: MVP Launch (Week 13–16)
|
||||
|
||||
### Purpose
|
||||
Launch public beta, establish community, prove engagement model (narrative + education), gather user feedback.
|
||||
|
||||
### Management Deliverables
|
||||
- **Persona Expansion**: Personas 4–5 fully onboarded
|
||||
- **Narrative Expansion**: Arc 1 conclusion, Arc 2 launch
|
||||
- **Content Production**: 15–20 articles across all active personas
|
||||
- **Platform Integrations**: BookStack, Gitea, social media syncing
|
||||
- **Launch Coordination**: Marketing plan, user onboarding, community guidelines
|
||||
|
||||
### Development Deliverables
|
||||
- **Portal Beta Launch**: Public-facing Stack Legion live with articles, community, challenges
|
||||
- **User Registration**: Member tiers, gamification live
|
||||
- **Performance**: Load testing, database optimization, caching strategy
|
||||
- **API Maturity**: Versioning, rate limiting, documentation, monitoring
|
||||
|
||||
### Success Criteria
|
||||
- ✅ Stack Legion MVP live with 5 personas, multiple articles
|
||||
- ✅ 500+ registered members, 100+ challenge participants
|
||||
- ✅ Arc 2 live and generating engagement
|
||||
- ✅ Site handles 1K+ concurrent users
|
||||
- ✅ Revenue model validated (50%+ conversion to membership/courses)
|
||||
- ✅ All APIs stable and documented
|
||||
|
||||
## Phase 3: Scale & Iteration (Week 17–24)
|
||||
|
||||
### Purpose
|
||||
Grow community, expand persona roster, launch multiple narrative arcs in parallel, prove replication template with second vertical.
|
||||
|
||||
### Management Deliverables
|
||||
- **Full Wave 1 Roster**: Personas 6–10 onboarded
|
||||
- **Vertical 2 Planning**: Choose second vertical (DIY? Fitness? Finance?)
|
||||
- **Narrative Expansion**: 3–4 concurrent arcs, seasonal themes, community-driven narratives
|
||||
- **Content Production**: 40–60 articles across all personas
|
||||
- **Analytics & Growth**: Cohort analysis, content performance, SEO growth
|
||||
|
||||
### Development Deliverables
|
||||
- **Platform Scaling**: Microservices architecture, database sharding, cache optimization
|
||||
- **Advanced Features**: Persona Portal MVP, advanced gamification, recommendation engine
|
||||
- **Revenue Systems**: Course hosting, membership tiers, payment processing, revenue sharing
|
||||
- **API Expansion**: Persona Portal APIs, recommendation APIs, revenue APIs
|
||||
|
||||
### Success Criteria
|
||||
- ✅ 10,000+ active community members
|
||||
- ✅ 10 personas across 2 verticals
|
||||
- ✅ 150+ articles published
|
||||
- ✅ 3–4 narrative arcs generating measurable engagement
|
||||
- ✅ Monthly recurring revenue established
|
||||
- ✅ Platform handles 10K+ concurrent users
|
||||
- ✅ 50K+ monthly organic visitors (SEO)
|
||||
- ✅ Replication template proven with second vertical
|
||||
|
||||
## Phase 4: Expansion (Week 25+)
|
||||
|
||||
### Purpose
|
||||
Scale to 3–5 verticals, build revenue streams, establish moat through narrative depth, prepare for external partnerships.
|
||||
|
||||
### Management Deliverables
|
||||
- **Multi-Vertical Operations**: 3–5 verticals live, 30–50 personas
|
||||
- **Narrative Complexity**: 10–15 concurrent arcs, cross-vertical storylines, annual events
|
||||
- **Monetization & Partnerships**: Sponsorships, affiliate marketing, white-label opportunities
|
||||
|
||||
### Development Deliverables
|
||||
- **Enterprise-Grade Platform**: Advanced analytics, internationalization, white-label features
|
||||
- **API Marketplace**: Third-party integrations, ecosystem partnerships
|
||||
|
||||
### Success Criteria
|
||||
- ✅ $50K+ monthly recurring revenue
|
||||
- ✅ 50+ personas across 3–5 verticals
|
||||
- ✅ Enterprise partnerships established
|
||||
- ✅ Replication playbook proven
|
||||
|
||||
## Critical Success Factors
|
||||
|
||||
### Week 1 (This Week)
|
||||
- [ ] Brick specialty finalized
|
||||
- [ ] 5 personas sketched
|
||||
- [ ] Arc 1 defined
|
||||
- [ ] Dev team aligned
|
||||
|
||||
### Week 4 Checkpoint
|
||||
- [ ] All Phase 0 decisions locked
|
||||
- [ ] Personas documented
|
||||
- [ ] Narrative engine designed
|
||||
- [ ] Revenue model detailed
|
||||
- [ ] Launch date committed
|
||||
|
||||
### Week 12 Checkpoint (Phase 1 Go/No-Go)
|
||||
- [ ] 3 personas with proven voice consistency
|
||||
- [ ] 8–10 quality articles published
|
||||
- [ ] Arc 1 showing engagement
|
||||
- [ ] Portal MVP complete
|
||||
- [ ] APIs operational
|
||||
|
||||
### Week 16 Checkpoint (Phase 2 Go/No-Go)
|
||||
- [ ] Stack Legion MVP public
|
||||
- [ ] 500+ members
|
||||
- [ ] Revenue model working
|
||||
- [ ] Ready for Phase 3 scale
|
||||
|
||||
### Week 24 Checkpoint (Phase 3 Go/No-Go)
|
||||
- [ ] 10 personas, 2 verticals
|
||||
- [ ] 10K+ users
|
||||
- [ ] Replication validated
|
||||
- [ ] Ready for Phase 4 expansion
|
||||
174
publish/web1/public/content/tools.md
Executable file
174
publish/web1/public/content/tools.md
Executable file
@@ -0,0 +1,174 @@
|
||||
# Tools & Infrastructure
|
||||
|
||||
## Overview
|
||||
|
||||
TekDek operates across multiple platforms and tools to manage personas, content, narratives, and community.
|
||||
|
||||
## Critical Path Tools (MVP — Phase 2)
|
||||
|
||||
### 1. Persona Management System
|
||||
**Purpose**: Central hub for persona profiles, voice guides, platform presence tracking, and character consistency.
|
||||
|
||||
**Must-have features**:
|
||||
- Persona profile (name, expertise, voice/tone guide, relationships)
|
||||
- Platform presence tracking (which channels they publish on)
|
||||
- Voice guide (how they write, speak, communicate across formats)
|
||||
- Personality consistency rules (what's on-brand vs. off-brand)
|
||||
- History/timeline (articles, posts, video links across all platforms)
|
||||
|
||||
**Status**: In design (OpenClaw-based)
|
||||
|
||||
### 2. Storyline & Narrative Planning Tool
|
||||
**Purpose**: Track character arcs, plan narrative beats, schedule content tie-ins, and coordinate drama.
|
||||
|
||||
**Must-have features**:
|
||||
- Arc planner (3–6 month timelines, character involvement, key beats)
|
||||
- Content calendar tied to narrative (posts that support specific story moments)
|
||||
- Conflict/collaboration tracker (who's involved, what's the status)
|
||||
- Engagement hooks (what will drive user interest)
|
||||
- Curated content log (you approve/reject content before publication)
|
||||
|
||||
**Status**: In design (combination of docs + dashboard)
|
||||
|
||||
### 3. Content Curation & Approval System
|
||||
**Purpose**: Central intake for persona-generated content; review for technical accuracy, narrative fit, and voice consistency before publication.
|
||||
|
||||
**Must-have features**:
|
||||
- Content submission form (title, draft, persona, narrative arc tie-in)
|
||||
- Approval workflow (pending, approved, rejected with feedback)
|
||||
- Scheduling (publish date/time, multi-platform coordination)
|
||||
- Consistency check (does this match the persona's voice?)
|
||||
- SEO/tagging (keywords, trending alignment)
|
||||
|
||||
**Status**: In design (form-based workflow)
|
||||
|
||||
## Phase 2 Nice-to-Have Tools
|
||||
|
||||
### 4. Persona Agent Framework
|
||||
**Purpose**: AI agents that generate content drafts in each persona's voice.
|
||||
|
||||
**Must-have features**:
|
||||
- Voice consistency (trained on persona's previous work)
|
||||
- Topic/expertise alignment (generates appropriate content)
|
||||
- Multi-format output (blog posts, social media captions, code comments)
|
||||
- Draft generation (not auto-publish; requires your curation)
|
||||
|
||||
**Tech approach**: Fine-tuned LLM or prompt engineering with persona voice guide + examples
|
||||
|
||||
**Status**: Research phase (OpenClaw subagents)
|
||||
|
||||
### 5. Content Syndication System
|
||||
**Purpose**: Pull content from persona's independent platforms (YouTube videos, blog posts, GitHub repos) into Stack Legion aggregation.
|
||||
|
||||
**Must-have features**:
|
||||
- Feed ingestion (RSS, API, webhook)
|
||||
- Metadata extraction (title, date, persona, expertise tag)
|
||||
- Cross-linking (persona's site + Stack Legion)
|
||||
- Attribution (credit the original source)
|
||||
|
||||
**Status**: Integration planning
|
||||
|
||||
## Phase 3+ Tools (Growth & Scale)
|
||||
|
||||
### 6. Persona Portal
|
||||
**Purpose**: Publishing and identity management platform for personas.
|
||||
|
||||
**Must-have features**:
|
||||
- Publishing interface (write, schedule, preview)
|
||||
- Analytics dashboard (views, engagement per persona)
|
||||
- Revenue tracking (integrations with YouTube, Patreon, course platforms)
|
||||
- Branding tools (custom templates, fonts, colors)
|
||||
- Community moderation (comments, member interactions)
|
||||
|
||||
**Status**: Under external development
|
||||
|
||||
### 7. Community & Gamification System
|
||||
**Purpose**: Stack Legion member engagement through challenges, points, leaderboards.
|
||||
|
||||
**Must-have features**:
|
||||
- Challenge creation (persona-authored coding challenges)
|
||||
- Points/badges system (users earn for participation)
|
||||
- Leaderboards (global, per-challenge, per-persona)
|
||||
- Member-exclusive content (early access to articles, special threads)
|
||||
|
||||
**Status**: Part of Stack Legion development
|
||||
|
||||
### 8. Analytics & Growth Dashboard
|
||||
**Purpose**: Track engagement, SEO, trending alignment, and narrative arc performance.
|
||||
|
||||
**Must-have features**:
|
||||
- Persona performance (views, engagement per content)
|
||||
- Narrative arc metrics (virality, user investment, discussion volume)
|
||||
- SEO tracking (search rankings, traffic sources)
|
||||
- Trending alignment (what's being discussed, how our content fits)
|
||||
- Cohort analysis (which personas drive retention, growth)
|
||||
|
||||
**Status**: In planning (custom dashboard)
|
||||
|
||||
## TekDek Infrastructure
|
||||
|
||||
### Hosted Services
|
||||
|
||||
| Service | Domain | Purpose |
|
||||
|---------|--------|---------|
|
||||
| **Gitea** | `git.tekdek.dev` | Git repository hosting for all projects |
|
||||
| **BookStack** | `docs.tekdek.dev` | Internal documentation wiki |
|
||||
| **Stack Legion** | `web.tekdek.dev` (TBD) | Main user-facing portal |
|
||||
| **This Site** | TBD | Documentation & strategy hub |
|
||||
|
||||
### Tech Stack (This Site)
|
||||
|
||||
- **PHP** (no framework — lean and intentional)
|
||||
- **Markdown** for content (parsed to HTML)
|
||||
- **Custom CSS** (no frameworks)
|
||||
- **Vanilla JavaScript** (minimal)
|
||||
|
||||
### Tech Stack (Stack Legion)
|
||||
|
||||
- **TBD** (external development team)
|
||||
- Requirements: article publishing, community, gamification, API support
|
||||
|
||||
## Build vs. Buy Strategy
|
||||
|
||||
### Build (Internal)
|
||||
- Persona Management System
|
||||
- Storyline Planning Tool
|
||||
- Content Curation Workflow
|
||||
- Persona Agent Framework (experimental)
|
||||
|
||||
### Buy / Integrate
|
||||
- Stack Legion (external dev)
|
||||
- Community & Gamification (external dev)
|
||||
- Analytics (Google Analytics, Mixpanel, or custom)
|
||||
- Syndication (Zapier, IFTTT, or custom API)
|
||||
|
||||
### Partner / Outsource
|
||||
- Stack Legion Portal (external dev team)
|
||||
- Video hosting (YouTube, TikTok — personas own)
|
||||
- Course platform (Teachable, Udemy, or custom)
|
||||
- Email/communication (SendGrid, ConvertKit, etc.)
|
||||
|
||||
## Immediate Next Steps
|
||||
|
||||
1. **Week 1**: Finalize Brick persona profile
|
||||
2. **Week 1**: Create narrative arc template
|
||||
3. **Week 2**: Build content curation spreadsheet/form
|
||||
4. **Week 2**: Sketch 3–5 additional persona profiles
|
||||
5. **Week 3**: Start persona agent prototyping
|
||||
6. **Week 4**: SEO/growth strategy documentation
|
||||
|
||||
## API Integration Points
|
||||
|
||||
### Portal ↔ Management System (OpenClaw)
|
||||
|
||||
**Persona API**: `GET /persona/{id}`
|
||||
- Returns: profile, system prompt, voice guide
|
||||
|
||||
**Content Sync API**: `POST /content/published`
|
||||
- Sync when articles go live
|
||||
|
||||
**Analytics API**: `GET /analytics/article/{id}`
|
||||
- Returns: engagement metrics
|
||||
|
||||
**Narrative API**: `GET /narrative/arc/{id}`
|
||||
- Returns: arc beats, status, engagement
|
||||
59
publish/web1/public/css/base.css
Normal file
59
publish/web1/public/css/base.css
Normal file
@@ -0,0 +1,59 @@
|
||||
/* TekDek Base Styles — Icarus: customize these */
|
||||
|
||||
:root {
|
||||
--color-bg: #0f0f0f;
|
||||
--color-surface: #1a1a2e;
|
||||
--color-primary: #00d4ff;
|
||||
--color-secondary: #7b2ff7;
|
||||
--color-text: #e0e0e0;
|
||||
--color-text-muted: #888;
|
||||
--color-border: #2a2a3e;
|
||||
--color-accent: #ff6b6b;
|
||||
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
--font-mono: 'Fira Code', 'Cascadia Code', monospace;
|
||||
--max-width: 1100px;
|
||||
--radius: 8px;
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
html { font-size: 16px; scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.container { max-width: var(--max-width); margin: 0 auto; padding: 0 1.5rem; width: 100%; }
|
||||
|
||||
a { color: var(--color-primary); text-decoration: none; transition: color 0.2s; }
|
||||
a:hover { color: #fff; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 { line-height: 1.3; margin-bottom: 0.75rem; color: #fff; }
|
||||
h1 { font-size: 2.25rem; }
|
||||
h2 { font-size: 1.5rem; margin-top: 2rem; }
|
||||
h3 { font-size: 1.25rem; }
|
||||
|
||||
p { margin-bottom: 1rem; }
|
||||
|
||||
ul, ol { margin: 0 0 1rem 1.5rem; }
|
||||
li { margin-bottom: 0.35rem; }
|
||||
|
||||
code { font-family: var(--font-mono); background: var(--color-surface); padding: 0.15em 0.4em; border-radius: 4px; font-size: 0.9em; }
|
||||
pre { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1.25rem; overflow-x: auto; margin-bottom: 1.5rem; }
|
||||
pre code { background: none; padding: 0; }
|
||||
|
||||
blockquote { border-left: 3px solid var(--color-primary); padding-left: 1rem; color: var(--color-text-muted); margin-bottom: 1rem; }
|
||||
|
||||
hr { border: none; border-top: 1px solid var(--color-border); margin: 2rem 0; }
|
||||
|
||||
table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; }
|
||||
th, td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--color-border); }
|
||||
th { color: #fff; font-weight: 600; }
|
||||
|
||||
img { max-width: 100%; height: auto; border-radius: var(--radius); }
|
||||
54
publish/web1/public/css/components.css
Normal file
54
publish/web1/public/css/components.css
Normal file
@@ -0,0 +1,54 @@
|
||||
/* TekDek Components — Icarus: expand these */
|
||||
|
||||
/* Header */
|
||||
.site-header { background: var(--color-surface); border-bottom: 1px solid var(--color-border); padding: 1rem 0; position: sticky; top: 0; z-index: 100; }
|
||||
.header-inner { display: flex; align-items: center; justify-content: space-between; max-width: var(--max-width); margin: 0 auto; padding: 0 1.5rem; }
|
||||
.site-logo { display: flex; flex-direction: column; text-decoration: none; }
|
||||
.logo-text { font-size: 1.5rem; font-weight: 700; color: var(--color-primary); }
|
||||
.logo-tagline { font-size: 0.75rem; color: var(--color-text-muted); }
|
||||
|
||||
/* Navigation */
|
||||
.main-nav ul { display: flex; list-style: none; gap: 0.25rem; margin: 0; padding: 0; }
|
||||
.main-nav a { display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.75rem; border-radius: var(--radius); color: var(--color-text-muted); transition: all 0.2s; }
|
||||
.main-nav a:hover, .main-nav .active a { color: #fff; background: rgba(0,212,255,0.1); }
|
||||
.nav-icon { font-size: 1.1rem; }
|
||||
|
||||
/* Mobile menu toggle */
|
||||
.menu-toggle { display: none; background: none; border: none; cursor: pointer; padding: 0.5rem; }
|
||||
.hamburger, .hamburger::before, .hamburger::after { display: block; width: 24px; height: 2px; background: var(--color-text); transition: all 0.3s; position: relative; }
|
||||
.hamburger::before, .hamburger::after { content: ''; position: absolute; left: 0; }
|
||||
.hamburger::before { top: -7px; }
|
||||
.hamburger::after { top: 7px; }
|
||||
|
||||
/* Main content */
|
||||
.site-main { flex: 1; padding: 2rem 0; }
|
||||
.page-content { max-width: 800px; }
|
||||
|
||||
/* Hero */
|
||||
.hero { margin-bottom: 3rem; padding: 2rem 0; }
|
||||
.hero h1 { font-size: 2.75rem; margin-bottom: 0.5rem; }
|
||||
.lead { font-size: 1.2rem; color: var(--color-text-muted); }
|
||||
|
||||
/* Cards */
|
||||
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; }
|
||||
.card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1.5rem; transition: all 0.2s; text-decoration: none; color: var(--color-text); }
|
||||
.card:hover { border-color: var(--color-primary); transform: translateY(-2px); color: #fff; }
|
||||
.card-icon { font-size: 2rem; display: block; margin-bottom: 0.5rem; }
|
||||
.card h3 { margin-bottom: 0.25rem; }
|
||||
.card-list { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 1.5rem; }
|
||||
.card-list .card { cursor: default; }
|
||||
.card-list .card:hover { transform: none; }
|
||||
|
||||
/* Badges */
|
||||
.badge { display: inline-block; padding: 0.2em 0.6em; border-radius: 999px; font-size: 0.8rem; background: var(--color-border); color: var(--color-text-muted); }
|
||||
.badge-active { background: rgba(0,212,255,0.15); color: var(--color-primary); }
|
||||
|
||||
/* Buttons */
|
||||
.btn { display: inline-block; padding: 0.6rem 1.25rem; border-radius: var(--radius); background: var(--color-primary); color: var(--color-bg); font-weight: 600; transition: all 0.2s; }
|
||||
.btn:hover { background: #fff; color: var(--color-bg); }
|
||||
|
||||
/* Footer */
|
||||
.site-footer { padding: 2rem 0; border-top: 1px solid var(--color-border); text-align: center; color: var(--color-text-muted); font-size: 0.85rem; }
|
||||
|
||||
/* Decisions table */
|
||||
.decisions-table th { background: var(--color-surface); }
|
||||
17
publish/web1/public/css/responsive.css
Normal file
17
publish/web1/public/css/responsive.css
Normal file
@@ -0,0 +1,17 @@
|
||||
/* TekDek Responsive — Icarus: refine breakpoints */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.menu-toggle { display: block; }
|
||||
.main-nav { display: none; position: absolute; top: 100%; left: 0; right: 0; background: var(--color-surface); border-bottom: 1px solid var(--color-border); padding: 1rem; }
|
||||
.main-nav.open { display: block; }
|
||||
.main-nav ul { flex-direction: column; }
|
||||
.main-nav a { padding: 0.75rem 1rem; }
|
||||
.hero h1 { font-size: 2rem; }
|
||||
.cards { grid-template-columns: 1fr 1fr; }
|
||||
h1 { font-size: 1.75rem; }
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.cards { grid-template-columns: 1fr; }
|
||||
.header-inner { padding: 0 1rem; }
|
||||
}
|
||||
11
publish/web1/public/includes/bottom.php
Normal file
11
publish/web1/public/includes/bottom.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
</div><!-- /.container -->
|
||||
</main>
|
||||
<footer class="site-footer">
|
||||
<div class="container">
|
||||
<p>© <?= date('Y') ?> <?= e(SITE_TITLE) ?>. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="<?= SITE_BASE_URL ?>js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
179
publish/web1/public/includes/functions.php
Normal file
179
publish/web1/public/includes/functions.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* TekDek - Utility Functions
|
||||
*
|
||||
* Lightweight markdown renderer and helpers. No external dependencies.
|
||||
*/
|
||||
|
||||
if (!defined('TEKDEK')) die('Direct access not permitted.');
|
||||
|
||||
/**
|
||||
* Convert markdown to HTML (lightweight, no dependencies).
|
||||
* Supports: headings, bold, italic, code blocks, inline code, links, images,
|
||||
* unordered/ordered lists, blockquotes, horizontal rules, paragraphs.
|
||||
*/
|
||||
function markdown_to_html(string $md): string {
|
||||
$md = str_replace("\r\n", "\n", $md);
|
||||
$lines = explode("\n", $md);
|
||||
$html = '';
|
||||
$in_code = false;
|
||||
$in_list = false;
|
||||
$in_ol = false;
|
||||
$in_blockquote = false;
|
||||
$paragraph = '';
|
||||
|
||||
$flush_paragraph = function () use (&$html, &$paragraph) {
|
||||
if ($paragraph !== '') {
|
||||
$html .= '<p>' . inline_markdown(trim($paragraph)) . "</p>\n";
|
||||
$paragraph = '';
|
||||
}
|
||||
};
|
||||
|
||||
$close_list = function () use (&$html, &$in_list, &$in_ol) {
|
||||
if ($in_list) { $html .= "</ul>\n"; $in_list = false; }
|
||||
if ($in_ol) { $html .= "</ol>\n"; $in_ol = false; }
|
||||
};
|
||||
|
||||
foreach ($lines as $line) {
|
||||
// Fenced code blocks
|
||||
if (preg_match('/^```(\w*)/', $line, $m)) {
|
||||
$flush_paragraph();
|
||||
$close_list();
|
||||
if (!$in_code) {
|
||||
$lang = $m[1] ? ' class="language-' . e($m[1]) . '"' : '';
|
||||
$html .= "<pre><code{$lang}>";
|
||||
$in_code = true;
|
||||
} else {
|
||||
$html .= "</code></pre>\n";
|
||||
$in_code = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($in_code) {
|
||||
$html .= e($line) . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Blank line
|
||||
if (trim($line) === '') {
|
||||
$flush_paragraph();
|
||||
$close_list();
|
||||
if ($in_blockquote) { $html .= "</blockquote>\n"; $in_blockquote = false; }
|
||||
continue;
|
||||
}
|
||||
|
||||
// Headings
|
||||
if (preg_match('/^(#{1,6})\s+(.+)/', $line, $m)) {
|
||||
$flush_paragraph(); $close_list();
|
||||
$level = strlen($m[1]);
|
||||
$id = slugify($m[2]);
|
||||
$html .= "<h{$level} id=\"{$id}\">" . inline_markdown($m[2]) . "</h{$level}>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Horizontal rule
|
||||
if (preg_match('/^(-{3,}|\*{3,}|_{3,})$/', trim($line))) {
|
||||
$flush_paragraph(); $close_list();
|
||||
$html .= "<hr>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Blockquote
|
||||
if (preg_match('/^>\s?(.*)/', $line, $m)) {
|
||||
$flush_paragraph(); $close_list();
|
||||
if (!$in_blockquote) { $html .= "<blockquote>\n"; $in_blockquote = true; }
|
||||
$html .= '<p>' . inline_markdown($m[1]) . "</p>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Unordered list
|
||||
if (preg_match('/^[\-\*]\s+(.+)/', $line, $m)) {
|
||||
$flush_paragraph();
|
||||
if ($in_ol) { $html .= "</ol>\n"; $in_ol = false; }
|
||||
if (!$in_list) { $html .= "<ul>\n"; $in_list = true; }
|
||||
$html .= '<li>' . inline_markdown($m[1]) . "</li>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ordered list
|
||||
if (preg_match('/^\d+\.\s+(.+)/', $line, $m)) {
|
||||
$flush_paragraph();
|
||||
if ($in_list) { $html .= "</ul>\n"; $in_list = false; }
|
||||
if (!$in_ol) { $html .= "<ol>\n"; $in_ol = true; }
|
||||
$html .= '<li>' . inline_markdown($m[1]) . "</li>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Paragraph text
|
||||
$paragraph .= $line . "\n";
|
||||
}
|
||||
|
||||
$flush_paragraph();
|
||||
$close_list();
|
||||
if ($in_code) $html .= "</code></pre>\n";
|
||||
if ($in_blockquote) $html .= "</blockquote>\n";
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process inline markdown: bold, italic, code, links, images.
|
||||
*/
|
||||
function inline_markdown(string $text): string {
|
||||
// Images: 
|
||||
$text = preg_replace('/!\[([^\]]*)\]\(([^)]+)\)/', '<img src="$2" alt="$1" loading="lazy">', $text);
|
||||
// Links: [text](url)
|
||||
$text = preg_replace('/\[([^\]]+)\]\(([^)]+)\)/', '<a href="$2">$1</a>', $text);
|
||||
// Bold+italic
|
||||
$text = preg_replace('/\*\*\*(.+?)\*\*\*/', '<strong><em>$1</em></strong>', $text);
|
||||
// Bold
|
||||
$text = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $text);
|
||||
// Italic
|
||||
$text = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $text);
|
||||
// Inline code
|
||||
$text = preg_replace('/`([^`]+)`/', '<code>$1</code>', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML-escape shorthand.
|
||||
*/
|
||||
function e(string $s): string {
|
||||
return htmlspecialchars($s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a URL-friendly slug from text.
|
||||
*/
|
||||
function slugify(string $text): string {
|
||||
$text = strtolower(strip_tags($text));
|
||||
$text = preg_replace('/[^a-z0-9\s-]/', '', $text);
|
||||
return preg_replace('/[\s-]+/', '-', trim($text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and render a markdown content file. Returns HTML or null.
|
||||
*/
|
||||
function load_content(string $slug): ?string {
|
||||
global $CONTENT_MAP;
|
||||
$file = $CONTENT_MAP[$slug] ?? null;
|
||||
if (!$file) return null;
|
||||
$path = CONTENT_DIR . $file;
|
||||
if (!file_exists($path)) return null;
|
||||
return markdown_to_html(file_get_contents($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current page matches slug (for nav highlighting).
|
||||
*/
|
||||
function is_active(string $slug, string $current): string {
|
||||
return ($slug === $current) ? ' class="active"' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL for a page slug.
|
||||
*/
|
||||
function page_url(string $slug): string {
|
||||
if ($slug === 'home') return SITE_BASE_URL;
|
||||
return SITE_BASE_URL . $slug;
|
||||
}
|
||||
26
publish/web1/public/includes/menu.php
Normal file
26
publish/web1/public/includes/menu.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* TekDek - Navigation Renderer
|
||||
*
|
||||
* Renders nav from $MENU config. $current_page must be set before including.
|
||||
*/
|
||||
if (!defined('TEKDEK')) die('Direct access not permitted.');
|
||||
?>
|
||||
<nav class="main-nav" role="navigation" aria-label="Main navigation">
|
||||
<ul>
|
||||
<?php foreach ($MENU as $slug => $item): ?>
|
||||
<?php if ($item['nav']): ?>
|
||||
<?php
|
||||
$url = ($slug === 'team') ? SITE_BASE_URL . 'team.html' : page_url($slug);
|
||||
$active = is_active($slug, $current_page);
|
||||
?>
|
||||
<li<?= $active ?>>
|
||||
<a href="<?= e($url) ?>">
|
||||
<span class="nav-icon"><?= $item['icon'] ?></span>
|
||||
<span class="nav-label"><?= e($item['title']) ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
27
publish/web1/public/includes/top.php
Normal file
27
publish/web1/public/includes/top.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="<?= e(SITE_DESCRIPTION) ?>">
|
||||
<title><?= e(page_title($current_page)) ?></title>
|
||||
<link rel="stylesheet" href="<?= SITE_BASE_URL ?>css/base.css">
|
||||
<link rel="stylesheet" href="<?= SITE_BASE_URL ?>css/components.css">
|
||||
<link rel="stylesheet" href="<?= SITE_BASE_URL ?>css/responsive.css">
|
||||
</head>
|
||||
<body data-page="<?= e($current_page) ?>">
|
||||
<header class="site-header">
|
||||
<div class="header-inner">
|
||||
<a href="<?= SITE_BASE_URL ?>" class="site-logo">
|
||||
<span class="logo-text"><?= e(SITE_TITLE) ?></span>
|
||||
<span class="logo-tagline"><?= e(SITE_DESCRIPTION) ?></span>
|
||||
</a>
|
||||
<button class="menu-toggle" aria-label="Toggle navigation" aria-expanded="false">
|
||||
<span class="hamburger"></span>
|
||||
</button>
|
||||
<?php include __DIR__ . '/menu.php'; ?>
|
||||
</div>
|
||||
</header>
|
||||
<main class="site-main">
|
||||
<div class="container">
|
||||
45
publish/web1/public/index.php
Normal file
45
publish/web1/public/index.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* TekDek Documentation Site - Main Router
|
||||
*
|
||||
* All requests route through here via .htaccess.
|
||||
*/
|
||||
define('TEKDEK', true);
|
||||
|
||||
require_once __DIR__ . '/config.php';
|
||||
require_once __DIR__ . '/includes/functions.php';
|
||||
|
||||
// --- Determine requested page ---
|
||||
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
$base = rtrim(SITE_BASE_URL, '/');
|
||||
$path = ($base !== '') ? substr($request_uri, strlen($base)) : $request_uri;
|
||||
$path = trim($path, '/');
|
||||
|
||||
// Default to home
|
||||
$current_page = ($path === '') ? 'home' : $path;
|
||||
|
||||
// --- Validate page exists ---
|
||||
if (!isset($MENU[$current_page])) {
|
||||
$current_page = '404';
|
||||
http_response_code(404);
|
||||
}
|
||||
|
||||
// --- Render ---
|
||||
include __DIR__ . '/includes/top.php';
|
||||
|
||||
$page_file = __DIR__ . '/pages/' . $current_page . '.php';
|
||||
if (file_exists($page_file)) {
|
||||
include $page_file;
|
||||
} elseif ($current_page === '404') {
|
||||
include __DIR__ . '/pages/404.php';
|
||||
} else {
|
||||
// Fallback: try loading markdown content
|
||||
$content = load_content($current_page);
|
||||
if ($content) {
|
||||
echo '<article class="page-content">' . $content . '</article>';
|
||||
} else {
|
||||
include __DIR__ . '/pages/404.php';
|
||||
}
|
||||
}
|
||||
|
||||
include __DIR__ . '/includes/bottom.php';
|
||||
16
publish/web1/public/js/main.js
Normal file
16
publish/web1/public/js/main.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* TekDek - Main JS
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Mobile menu toggle
|
||||
const toggle = document.querySelector('.menu-toggle');
|
||||
const nav = document.querySelector('.main-nav');
|
||||
if (toggle && nav) {
|
||||
toggle.addEventListener('click', function() {
|
||||
const open = nav.classList.toggle('open');
|
||||
toggle.setAttribute('aria-expanded', open);
|
||||
});
|
||||
}
|
||||
})();
|
||||
7
publish/web1/public/pages/404.php
Normal file
7
publish/web1/public/pages/404.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<article class="page-content error-page">
|
||||
<h1>404 — Page Not Found</h1>
|
||||
<p>The page you're looking for doesn't exist.</p>
|
||||
<p><a href="<?= SITE_BASE_URL ?>" class="btn">← Back to Home</a></p>
|
||||
</article>
|
||||
25
publish/web1/public/pages/about.php
Normal file
25
publish/web1/public/pages/about.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<article class="page-content">
|
||||
<h1>About TekDek</h1>
|
||||
|
||||
<?php
|
||||
$content = load_content('about');
|
||||
if ($content) {
|
||||
echo $content;
|
||||
} else {
|
||||
?>
|
||||
<h2>Vision & Strategy</h2>
|
||||
<p>TekDek is a multifaceted organization covering multiple projects with a <strong>creative backend</strong> — meaning there's a living storyline behind the development.</p>
|
||||
|
||||
<h2>Core Concept</h2>
|
||||
<ul>
|
||||
<li>Individual <strong>Coders</strong> are separate personas — each with their own development style, expertise, quirks, personality, and personal brand.</li>
|
||||
<li>Personas may or may not be attached to any given TekDek project.</li>
|
||||
<li>Relationships between personas drive the narrative.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Our Mission</h2>
|
||||
<p>Build quality software. Tell compelling stories. No corners cut.</p>
|
||||
<?php } ?>
|
||||
</article>
|
||||
18
publish/web1/public/pages/home.php
Normal file
18
publish/web1/public/pages/home.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<section class="hero">
|
||||
<h1>Welcome to TekDek</h1>
|
||||
<p class="lead">Documentation & Strategy Hub — where our vision, projects, and tools come together.</p>
|
||||
</section>
|
||||
|
||||
<section class="grid cards">
|
||||
<?php foreach ($MENU as $slug => $item): ?>
|
||||
<?php if ($slug !== 'home' && $item['nav']): ?>
|
||||
<?php $url = ($slug === 'team') ? SITE_BASE_URL . 'team.html' : page_url($slug); ?>
|
||||
<a href="<?= e($url) ?>" class="card">
|
||||
<span class="card-icon"><?= $item['icon'] ?></span>
|
||||
<h3><?= e($item['title']) ?></h3>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</section>
|
||||
30
publish/web1/public/pages/projects.php
Normal file
30
publish/web1/public/pages/projects.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<article class="page-content">
|
||||
<h1>Projects</h1>
|
||||
|
||||
<?php
|
||||
$content = load_content('projects');
|
||||
if ($content) {
|
||||
echo $content;
|
||||
} else {
|
||||
?>
|
||||
<h2>Active Projects</h2>
|
||||
|
||||
<div class="card-list">
|
||||
<div class="card">
|
||||
<h3>🌐 Persona Portal</h3>
|
||||
<p>Platform for personas to publish content, tutorials, and showcase their work.</p>
|
||||
<span class="badge">In Development</span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>📚 Documentation Site</h3>
|
||||
<p>This site — TekDek's central documentation and strategy hub.</p>
|
||||
<span class="badge badge-active">Live</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><em>More projects coming as TekDek evolves.</em></p>
|
||||
<?php } ?>
|
||||
</article>
|
||||
7
publish/web1/public/pages/team.php
Normal file
7
publish/web1/public/pages/team.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<article class="page-content">
|
||||
<h1>Team</h1>
|
||||
<p>Meet the TekDek crew.</p>
|
||||
<p><a href="<?= SITE_BASE_URL ?>team.html" class="btn">View Team Page →</a></p>
|
||||
</article>
|
||||
27
publish/web1/public/pages/tools.php
Normal file
27
publish/web1/public/pages/tools.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php if (!defined('TEKDEK')) die('Direct access not permitted.'); ?>
|
||||
|
||||
<article class="page-content">
|
||||
<h1>Tools & Tech</h1>
|
||||
|
||||
<?php
|
||||
$content = load_content('tools');
|
||||
if ($content) {
|
||||
echo $content;
|
||||
} else {
|
||||
?>
|
||||
<h2>Infrastructure</h2>
|
||||
<ul>
|
||||
<li><strong>Gitea</strong> — Git repository hosting (<code>git.tekdek.dev</code>)</li>
|
||||
<li><strong>BookStack</strong> — Documentation wiki (<code>docs.tekdek.dev</code>)</li>
|
||||
<li><strong>Web Server</strong> — Site hosting (<code>web.tekdek.dev</code>)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Stack</h2>
|
||||
<ul>
|
||||
<li>PHP (no framework — lean and intentional)</li>
|
||||
<li>Markdown for content</li>
|
||||
<li>CSS (custom, no frameworks)</li>
|
||||
<li>Vanilla JavaScript</li>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</article>
|
||||
Reference in New Issue
Block a user