#!/usr/bin/env python3 """ RealWebLearner: learned char n-gram intent model + compositional HTML/CSS/JS generator. It learns web-development intent from many generated examples and then composes code. It is designed for this tiny CPU workspace and integrates with unified_learning_ai.py. Usage: python real_web_learner.py --mode train --out outputs/real_web_learner python real_web_learner.py --mode ask --out outputs/real_web_learner --prompt "create a responsive landing page with dark mode" """ from __future__ import annotations import argparse import json import re from pathlib import Path from typing import List, Tuple from real_python_learner import NBIntent WEB_LABELS = [ "full_page", "landing_page", "portfolio", "navbar", "hero", "responsive_grid", "card", "form_validation", "todo_app", "dark_mode", "modal", "tabs", "accordion", "carousel", "css_animation", "dashboard", "fetch_api", "counter", "canvas", "explain_web" ] TEMPLATES = { "full_page": ["complete web page", "full html css javascript page", "entire website", "single page app"], "landing_page": ["landing page", "marketing page", "startup page", "product page", "saas landing"], "portfolio": ["portfolio", "personal website", "developer portfolio", "resume website"], "navbar": ["navbar", "navigation bar", "responsive menu", "mobile menu", "hamburger menu"], "hero": ["hero section", "main banner", "header section", "call to action"], "responsive_grid": ["responsive grid", "css grid layout", "gallery grid", "cards grid"], "card": ["card component", "pricing card", "profile card", "glass card"], "form_validation": ["form validation", "validate form", "contact form", "email validation"], "todo_app": ["todo app", "task list", "add remove tasks", "local storage todos"], "dark_mode": ["dark mode", "theme toggle", "light dark theme", "css variables theme"], "modal": ["modal", "popup", "dialog", "overlay"], "tabs": ["tabs", "tab component", "tabbed interface"], "accordion": ["accordion", "faq accordion", "collapsible sections"], "carousel": ["carousel", "slider", "image slider"], "css_animation": ["css animation", "advanced css", "keyframes", "animated button", "loading spinner"], "dashboard": ["dashboard", "admin dashboard", "analytics layout", "sidebar dashboard"], "fetch_api": ["fetch api", "load data from api", "javascript fetch", "async await web"], "counter": ["counter app", "increment decrement", "button counter"], "canvas": ["canvas", "draw with canvas", "html5 canvas"], "explain_web": ["explain html", "explain css", "explain javascript", "what is flexbox", "what is css grid"], } PREFIXES = [ "create", "build", "write", "make", "generate", "show me", "i need", "dame", "crea", "haz", "construye", "escribe" ] def build_training_examples(mult: int = 45) -> List[Tuple[str, str]]: examples: List[Tuple[str, str]] = [] modifiers = [ "responsive", "modern", "animated", "accessible", "mobile first", "with css variables", "with flexbox", "with css grid", "with javascript", "dark theme", "glassmorphism", "clean", "advanced css", "semantic html", "sin librerias", "vanilla javascript" ] for label, phrases in TEMPLATES.items(): for phrase in phrases: for pref in PREFIXES: examples.append((f"{pref} {phrase}", label)) for mod in modifiers[:8]: examples.append((f"{pref} {mod} {phrase}", label)) examples.append((f"{pref} {phrase} {mod}", label)) return examples * mult def html_shell(title: str, body: str, css: str, js: str = "") -> str: return f''' {title} {body} ''' BASE_CSS = ''' :root { --bg: #0f172a; --panel: rgba(255,255,255,.08); --text: #e5e7eb; --muted: #94a3b8; --brand: #7c3aed; --brand-2: #06b6d4; --ring: rgba(124,58,237,.45); --radius: 22px; --shadow: 0 24px 70px rgba(0,0,0,.35); } * { box-sizing: border-box; } body { margin: 0; font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif; background: radial-gradient(circle at top left, rgba(124,58,237,.25), transparent 30%), var(--bg); color: var(--text); min-height: 100vh; } a { color: inherit; text-decoration: none; } button, input, textarea { font: inherit; } ''' def code_for(label: str, prompt: str) -> str: p = prompt.lower() if label in {"full_page", "landing_page", "portfolio"}: title = "Portfolio" if label == "portfolio" or "portfolio" in p else "Nova Landing" body = '''

Modern Web Experience

Build beautiful interfaces with HTML, CSS and JavaScript.

Responsive layout, animated gradient, glass cards, semantic HTML and a tiny vanilla JS theme switcher.

CSS Grid + Variables

Fast, accessible, and easy to customize.

Responsive

Uses grid, clamp and media queries.

Animated

Subtle keyframes create depth.

Vanilla JS

No frameworks required.

''' css = BASE_CSS + ''' .nav { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1.2rem clamp(1rem,4vw,4rem); position:sticky; top:0; backdrop-filter: blur(16px); background:rgba(15,23,42,.72); z-index:10; } .logo { font-weight:900; letter-spacing:.04em; } nav { display:flex; gap:1rem; color:var(--muted); } .ghost { border:1px solid rgba(255,255,255,.16); background:transparent; color:var(--text); border-radius:999px; padding:.65rem 1rem; cursor:pointer; } .hero { min-height:76vh; display:grid; grid-template-columns:1.1fr .9fr; align-items:center; gap:clamp(2rem,6vw,6rem); padding:clamp(2rem,6vw,6rem); } .eyebrow { color:var(--brand-2); text-transform:uppercase; letter-spacing:.18em; font-size:.78rem; font-weight:800; } h1 { font-size:clamp(2.4rem,7vw,6rem); line-height:.95; margin:.2em 0; } .lead { color:var(--muted); font-size:clamp(1rem,2vw,1.25rem); max-width:65ch; } .actions { display:flex; flex-wrap:wrap; gap:1rem; margin-top:2rem; } .btn { background:linear-gradient(135deg,var(--brand),var(--brand-2)); padding:.9rem 1.2rem; border-radius:999px; font-weight:800; box-shadow:0 14px 35px var(--ring); } .btn.secondary { background:rgba(255,255,255,.08); box-shadow:none; } .orb-card { position:relative; overflow:hidden; border:1px solid rgba(255,255,255,.14); background:var(--panel); border-radius:var(--radius); padding:2rem; box-shadow:var(--shadow); min-height:360px; backdrop-filter:blur(20px); } .orb { width:220px; height:220px; border-radius:50%; background:linear-gradient(135deg,var(--brand),var(--brand-2)); filter:blur(2px); animation:float 5s ease-in-out infinite; } .grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1rem; padding:clamp(1rem,4vw,4rem); } .card { border:1px solid rgba(255,255,255,.12); background:var(--panel); border-radius:var(--radius); padding:1.4rem; transition:transform .25s ease, border-color .25s ease; } .card:hover { transform:translateY(-6px); border-color:var(--brand-2); } body.light { --bg:#f8fafc; --panel:rgba(15,23,42,.06); --text:#0f172a; --muted:#475569; } body.light .nav { background:rgba(248,250,252,.76); } @keyframes float { 0%,100%{ transform:translateY(0) rotate(0deg);} 50%{ transform:translateY(-18px) rotate(8deg);} } @media (max-width: 800px) { .hero { grid-template-columns:1fr; } .grid { grid-template-columns:1fr; } nav { display:none; } } ''' js = ''' const btn = document.querySelector('#themeBtn'); btn.addEventListener('click', () => document.body.classList.toggle('light')); ''' return "```html\n" + html_shell(title, body, css, js) + "\n```" if label == "navbar": return '''```html ```''' if label == "responsive_grid": return '''```html
One
Two
Three
Four
```''' if label == "form_validation": return '''```html
```''' if label == "todo_app": return '''```html
```''' if label == "modal": return '''```html ```''' if label == "tabs": return '''```html
First panel
```''' if label == "accordion": return '''```html
What is HTML?

Semantic structure for web content.

What is CSS?

Presentation, layout and animation.

```''' if label == "css_animation": return '''```html
```''' if label == "fetch_api": return '''```html


```'''

    if label == "counter":
        return '''```html
0

```'''

    if label == "canvas":
        return '''```html


```'''

    if label == "explain_web":
        return "HTML gives semantic structure, CSS controls layout/visual design, and JavaScript adds behavior. Advanced CSS includes Grid, Flexbox, custom properties, clamp(), container/media queries, transforms, transitions, keyframes, and accessibility-aware responsive design."

    # default component/card/dashboard/carousel fallback
    return '''```html

Modern Card

Reusable component with advanced CSS variables and hover motion.

```''' def train(out: Path): out.mkdir(parents=True, exist_ok=True) examples = build_training_examples(mult=35) model = NBIntent(); model.fit(examples); model.save(out / 'web_intent_nb.json') report = {"examples": len(examples), "features": len(model.vocab), "labels": WEB_LABELS, "type": "char_ngram_web_intent_plus_compositional_generator"} (out / 'report.json').write_text(json.dumps(report, indent=2), encoding='utf-8') (out / 'training_examples_sample.json').write_text(json.dumps(examples[:2000], indent=2, ensure_ascii=False), encoding='utf-8') print(json.dumps(report, indent=2)) def ask(out: Path, prompt: str): model = NBIntent.load(out / 'web_intent_nb.json') probs = model.predict_proba(prompt) label = probs[0][0] print('## Learned web reasoning') print('- Read request with character n-grams and web-development fragments.') print('- Top intents: ' + ', '.join(f'{l}={p:.2f}' for l,p in probs[:4])) print(f'- Selected intent: {label}') print('\n## Answer') print(code_for(label, prompt)) def main(): ap = argparse.ArgumentParser() ap.add_argument('--mode', choices=['train','ask'], default='ask') ap.add_argument('--out', default='outputs/real_web_learner') ap.add_argument('--prompt', default='create a responsive landing page with dark mode') args = ap.parse_args(); out = Path(args.out) if args.mode == 'train': train(out) else: ask(out, args.prompt) if __name__ == '__main__': main()