commit de34ecb7630b4515ef66e09b7324818878a0513e Author: jrodriiguezg Date: Sat Aug 15 15:17:13 2026 +0200 Subir archivos a "/" diff --git a/index.html b/index.html new file mode 100644 index 0000000..d06ccbc --- /dev/null +++ b/index.html @@ -0,0 +1,278 @@ + + + + + + PRRPC | Pico Real Rich Presence - Desktop Setup + + + + + + + + + +
+
+
+
V1 — Auto Monitoring | V2 — MacroDeck
+

Pico Real Rich Presence

+

Physical status monitor for Linux environments. Displays contextual active application information on a secondary LCD screen powered by RP2040.

+ +
+
+ +
+
+
+ +

Two Modes of Operation

+

PRRPC adapts to your workflow with automatic monitoring or manual macro control.

+
+ +
+
+
+

V1 — Auto Monitoring

+

Automatically detects the active application on your Linux desktop and displays contextual status on the LCD screen. Zero manual input required.

+
    +
  • GNOME focus event detection via pyatspi
  • +
  • Serial port communication (zero CPU polling)
  • +
  • Real-time application switching
  • +
  • Session time tracking
  • +
+
+ +
+
+

V2 — MacroDeck

+

Transforms into an interactive MacroDeck with local web control. Send emoji reactions and manually override the display status from any browser.

+
    +
  • Flask web server on localhost:5000
  • +
  • Multi-thread architecture
  • +
  • Emoji selector UI
  • +
  • 100x100px optimized assets
  • +
+
+
+ +
+
+
+

Client-Server Architecture

+

The system operates via a robust Client-Server architecture over serial port, combining software detection with hardware rendering for reliable performance.

+
+
+ Host (PC - Linux) + Python service monitors GNOME desktop focus events using pyatspi +
+
+
+ Serial Port + Native integration, no polling, zero CPU consumption +
+
+
+ Client (RP2040) + Renders graphical interface using raw RGB565 icons +
+
+
+
+
+
+ + + +
+
+
+ +

Specifications

+

Minimal hardware requirements for a complete physical status monitor setup.

+
+ +
+
+
+ +
+

RP2040-Zero

+

Microcontroller or compatible Raspberry Pi Pico running MicroPython firmware.

+
+ +
+
+ +
+

1.69" IPS LCD

+

ST7789 controller, 240x280 resolution, SPI interface with vibrant color output.

+
+ +
+
+ +
+

USB-C Connection

+

Single cable for both data interface and power supply. Plug and play setup.

+
+ +
+
+ +
+

Linux (GNOME/Wayland)

+

Tested on Fedora with GNOME desktop environment. Python with pyatspi required.

+
+
+ +
+
+ + + + monitor_pc.py — App Mapping +
+
# Example: Adding a new app in monitor_pc.py
+APPS_MAPPING = {
+    "Code":       "VSCODE",
+    "Firefox":    "FIREFOX",
+    # Map window focus keyword to an internal ID
+    "Obsidian":   "NOTAS"
+}
+
+# V2: Web control API snippet
+@app.route('/set_emoji/<emoji_id>')
+def set_emoji(emoji_id):
+    # Sends manual Emoji command via serial
+    send_to_serial(emoji_id.upper())
+    return {"status": "success"}
+
+# V2: RP2040 optimized image loading
+if comando in EMOJI_MAP:
+    arch = EMOJI_MAP[comando]
+    mostrar_imagen(arch)
+
+
+
+ +
+
+
+

Build Your Own PRRPC

+

Open source, fully documented. Get started with minimal hardware and bring physical status monitoring to your Linux desktop.

+ +
+
+
+
+ + + + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..ae44316 --- /dev/null +++ b/styles.css @@ -0,0 +1,665 @@ +*, +*::before, +*::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --bg-primary: #0a0a0a; + --bg-secondary: #111111; + --bg-card: #141414; + --bg-card-hover: #1a1a1a; + --text-primary: #ffffff; + --text-secondary: #a0a0a0; + --text-muted: #666666; + --accent: #00d4ff; + --accent-dim: rgba(0, 212, 255, 0.1); + --accent-glow: rgba(0, 212, 255, 0.15); + --border: rgba(255, 255, 255, 0.06); + --border-hover: rgba(255, 255, 255, 0.12); + --radius-sm: 8px; + --radius-md: 12px; + --radius-lg: 16px; + --radius-xl: 24px; + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); + --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1); +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + background-color: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + overflow-x: hidden; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Navbar */ +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + background: rgba(10, 10, 10, 0.8); + backdrop-filter: blur(20px); + border-bottom: 1px solid var(--border); +} + +.nav-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; + height: 64px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.nav-brand { + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 700; + font-size: 1.1rem; + color: var(--text-primary); +} + +.brand-icon { + color: var(--accent); + font-size: 1.3rem; +} + +.nav-links { + display: flex; + align-items: center; + gap: 2rem; +} + +.nav-links a { + color: var(--text-secondary); + text-decoration: none; + font-size: 0.9rem; + font-weight: 500; + transition: color var(--transition); +} + +.nav-links a:hover { + color: var(--text-primary); +} + +.nav-btn { + background: var(--accent-dim); + color: var(--accent) !important; + padding: 0.5rem 1.25rem; + border-radius: var(--radius-sm); + border: 1px solid rgba(0, 212, 255, 0.2); + transition: all var(--transition); +} + +.nav-btn:hover { + background: rgba(0, 212, 255, 0.15); + border-color: rgba(0, 212, 255, 0.3); +} + +/* Hero */ +.hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 8rem 2rem 4rem; + position: relative; +} + +.hero::before { + content: ''; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 800px; + height: 800px; + background: radial-gradient(circle, rgba(0, 212, 255, 0.08) 0%, transparent 70%); + pointer-events: none; +} + +.hero-content { + text-align: center; + max-width: 800px; + position: relative; + z-index: 1; +} + +.version-badge { + display: inline-block; + padding: 0.4rem 1rem; + background: var(--accent-dim); + color: var(--accent); + border-radius: 50px; + font-size: 0.8rem; + font-weight: 600; + letter-spacing: 0.5px; + border: 1px solid rgba(0, 212, 255, 0.2); + margin-bottom: 2rem; +} + +.hero h1 { + font-size: 4rem; + font-weight: 800; + letter-spacing: -2px; + margin-bottom: 1.5rem; + line-height: 1.1; + background: linear-gradient(135deg, #ffffff 0%, #a0a0a0 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.hero-subtitle { + font-size: 1.2rem; + color: var(--text-secondary); + max-width: 600px; + margin: 0 auto 2.5rem; + line-height: 1.7; +} + +.hero-actions { + display: flex; + justify-content: center; + gap: 1rem; + flex-wrap: wrap; +} + +.btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.85rem 1.75rem; + border-radius: var(--radius-sm); + font-weight: 600; + font-size: 0.95rem; + text-decoration: none; + transition: all var(--transition); + border: 1px solid transparent; + cursor: pointer; +} + +.btn-primary { + background: var(--accent); + color: #0a0a0a; + border-color: var(--accent); +} + +.btn-primary:hover { + background: #00bfe6; + box-shadow: 0 0 20px rgba(0, 212, 255, 0.3); + transform: translateY(-2px); +} + +.btn-secondary { + background: transparent; + color: var(--text-primary); + border-color: var(--border); +} + +.btn-secondary:hover { + border-color: var(--border-hover); + background: var(--bg-secondary); +} + +/* Sections */ +.section { + padding: 6rem 2rem; +} + +.section-container { + max-width: 1200px; + margin: 0 auto; +} + +.section-header { + text-align: center; + margin-bottom: 4rem; +} + +.section-tag { + display: inline-block; + padding: 0.3rem 0.85rem; + background: var(--accent-dim); + color: var(--accent); + border-radius: 50px; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 1px; + text-transform: uppercase; + margin-bottom: 1rem; + border: 1px solid rgba(0, 212, 255, 0.15); +} + +.section-header h2 { + font-size: 2.5rem; + font-weight: 700; + letter-spacing: -1px; + margin-bottom: 1rem; +} + +.section-header p { + color: var(--text-secondary); + font-size: 1.1rem; + max-width: 600px; + margin: 0 auto; +} + +/* Features Grid */ +.features-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1.5rem; + margin-bottom: 1.5rem; +} + +.feature-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 2.5rem; + transition: all var(--transition); +} + +.feature-card:hover { + border-color: var(--border-hover); + background: var(--bg-card-hover); + transform: translateY(-4px); + box-shadow: var(--shadow-md); +} + +.feature-card.wide { + grid-column: span 2; +} + +.feature-icon { + font-size: 2rem; + color: var(--accent); + margin-bottom: 1.5rem; + width: 56px; + height: 56px; + display: flex; + align-items: center; + justify-content: center; + background: var(--accent-dim); + border-radius: var(--radius-md); + border: 1px solid rgba(0, 212, 255, 0.15); +} + +.feature-card h3 { + font-size: 1.4rem; + font-weight: 700; + margin-bottom: 0.75rem; +} + +.feature-card p { + color: var(--text-secondary); + font-size: 0.95rem; + margin-bottom: 1.5rem; + line-height: 1.7; +} + +.feature-list { + list-style: none; + display: flex; + flex-direction: column; + gap: 0.6rem; +} + +.feature-list li { + position: relative; + padding-left: 1.25rem; + color: var(--text-secondary); + font-size: 0.9rem; +} + +.feature-list li::before { + content: ''; + position: absolute; + left: 0; + top: 0.55rem; + width: 6px; + height: 6px; + background: var(--accent); + border-radius: 50%; +} + +/* Architecture Flow */ +.architecture-flow { + display: flex; + align-items: center; + justify-content: center; + gap: 1.5rem; + margin-top: 1.5rem; + flex-wrap: wrap; +} + +.flow-step { + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: var(--radius-md); + padding: 1.25rem 1.5rem; + text-align: center; + min-width: 180px; +} + +.flow-label { + display: block; + font-weight: 600; + font-size: 0.85rem; + color: var(--accent); + margin-bottom: 0.4rem; +} + +.flow-desc { + display: block; + font-size: 0.8rem; + color: var(--text-secondary); +} + +.flow-arrow { + color: var(--text-muted); + font-size: 1.5rem; +} + +/* Gallery */ +.gallery-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} + +.gallery-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + overflow: hidden; + transition: all var(--transition); +} + +.gallery-card:hover { + border-color: var(--border-hover); + transform: translateY(-4px); + box-shadow: var(--shadow-lg); +} + +.gallery-img { + width: 100%; + height: 200px; + overflow: hidden; + background: #000; +} + +.gallery-img img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.5s ease; +} + +.gallery-card:hover .gallery-img img { + transform: scale(1.05); +} + +.gallery-info { + padding: 1.25rem; +} + +.gallery-info h4 { + font-size: 1rem; + font-weight: 600; + margin-bottom: 0.4rem; +} + +.gallery-info p { + font-size: 0.85rem; + color: var(--text-secondary); + line-height: 1.5; +} + +/* Specs Grid */ +.specs-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1.5rem; + margin-bottom: 3rem; +} + +.spec-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 2rem 1.5rem; + text-align: center; + transition: all var(--transition); +} + +.spec-card:hover { + border-color: rgba(0, 212, 255, 0.2); + background: var(--bg-card-hover); +} + +.spec-icon { + color: var(--accent); + margin-bottom: 1.25rem; + display: flex; + justify-content: center; +} + +.spec-card h4 { + font-size: 1rem; + font-weight: 600; + margin-bottom: 0.5rem; +} + +.spec-card p { + font-size: 0.85rem; + color: var(--text-secondary); + line-height: 1.5; +} + +/* Code Section */ +.code-section { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.code-header { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 1rem 1.5rem; + background: rgba(255, 255, 255, 0.02); + border-bottom: 1px solid var(--border); +} + +.code-dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: var(--text-muted); +} + +.code-dot:nth-child(1) { background: #ff5f57; } +.code-dot:nth-child(2) { background: #febc2e; } +.code-dot:nth-child(3) { background: #28c840; } + +.code-title { + margin-left: 0.75rem; + font-size: 0.85rem; + color: var(--text-secondary); + font-family: 'JetBrains Mono', monospace; +} + +.code-block { + padding: 1.5rem; + font-family: 'JetBrains Mono', monospace; + font-size: 0.85rem; + line-height: 1.8; + color: var(--text-secondary); + overflow-x: auto; + white-space: pre; +} + +.code-comment { color: #555555; } +.code-keyword { color: #00d4ff; } +.code-string { color: #a8e6a3; } + +/* CTA Section */ +.cta-section { + padding: 8rem 2rem; +} + +.cta-content { + text-align: center; + background: linear-gradient(135deg, var(--bg-card) 0%, rgba(0, 212, 255, 0.03) 100%); + border: 1px solid var(--border); + border-radius: var(--radius-xl); + padding: 4rem; + position: relative; + overflow: hidden; +} + +.cta-content::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(0, 212, 255, 0.05) 0%, transparent 50%); + pointer-events: none; +} + +.cta-content h2 { + font-size: 2.5rem; + font-weight: 700; + letter-spacing: -1px; + margin-bottom: 1rem; + position: relative; +} + +.cta-content p { + color: var(--text-secondary); + font-size: 1.1rem; + max-width: 500px; + margin: 0 auto 2rem; + position: relative; +} + +.cta-actions { + display: flex; + justify-content: center; + gap: 1rem; + position: relative; +} + +/* Footer */ +footer { + border-top: 1px solid var(--border); + padding: 3rem 2rem; +} + +.footer-container { + max-width: 1200px; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; +} + +.footer-container p { + color: var(--text-muted); + font-size: 0.85rem; +} + +.footer-links { + display: flex; + gap: 1.5rem; +} + +.footer-links a { + color: var(--text-secondary); + text-decoration: none; + font-size: 0.85rem; + transition: color var(--transition); +} + +.footer-links a:hover { + color: var(--accent); +} + +/* Responsive */ +@media (max-width: 1024px) { + .specs-grid { + grid-template-columns: repeat(2, 1fr); + } + .gallery-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .hero h1 { + font-size: 2.8rem; + } + .hero-subtitle { + font-size: 1rem; + } + .features-grid { + grid-template-columns: 1fr; + } + .feature-card.wide { + grid-column: span 1; + } + .gallery-grid { + grid-template-columns: 1fr; + } + .specs-grid { + grid-template-columns: 1fr; + } + .architecture-flow { + flex-direction: column; + } + .flow-arrow { + transform: rotate(90deg); + } + .section-header h2 { + font-size: 2rem; + } + .cta-content { + padding: 2.5rem 1.5rem; + } + .cta-content h2 { + font-size: 2rem; + } + .cta-actions { + flex-direction: column; + align-items: center; + } + .footer-container { + flex-direction: column; + gap: 1rem; + text-align: center; + } + .nav-links a:not(.nav-btn) { + display: none; + } +}