Panel: fuente Xirod, titulos centrados y diseno de dos columnas
Anade la fuente Xirod (web/panel/fonts/xirod.otf, de 1001fonts) para el titulo del panel, tanto en Raspberry como en portatil. Titulos centrados en la cabecera y en cada tarjeta. En pantalla ancha el panel pasa a dos columnas para aprovechar el espacio del portatil (Visuales/Audio/Sensibilidad a la izquierda, Motor y controles a la derecha); en movil sigue en una sola columna, igual que antes. El README explica el uso en ordenador con diagrama, comandos y tabla de diferencias, recalcando que en ordenador no se usa el modo kiosko. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c8b51615ba
commit
7ebb593288
5 changed files with 281 additions and 182 deletions
59
README.md
59
README.md
|
|
@ -2,11 +2,15 @@
|
||||||
|
|
||||||
# FOSFENO
|
# FOSFENO
|
||||||
|
|
||||||
**Motor de visuales audio-reactivas para Raspberry Pi.**
|
**Motor de visuales audio-reactivas para Raspberry Pi y para portátil Linux.**
|
||||||
Convierte una Raspberry Pi + un proyector + un micro USB en una estación de
|
Convierte una Raspberry Pi + un proyector + un micro USB en una estación de
|
||||||
VJ automática: la Pi escucha la música de la sala, detecta su BPM y proyecta
|
VJ automática: escucha la música de la sala, detecta su BPM y proyecta
|
||||||
visuales que reaccionan al sonido. Todo se controla desde un panel web.
|
visuales que reaccionan al sonido. Todo se controla desde un panel web.
|
||||||
|
|
||||||
|
Funciona en dos escenarios: en una **Raspberry Pi** como aparato dedicado que
|
||||||
|
arranca solo, o en un **portátil Linux** que lanzas cuando quieras. El apartado
|
||||||
|
[En un portátil Linux](#en-un-portátil-linux) explica las diferencias.
|
||||||
|
|
||||||
```
|
```
|
||||||
[ Música en la sala ]
|
[ Música en la sala ]
|
||||||
│ (micro USB)
|
│ (micro USB)
|
||||||
|
|
@ -76,13 +80,7 @@ bash install.sh --no-projectm # omite la compilación de projectM
|
||||||
bash install.sh --check # solo comprueba el sistema, no instala nada
|
bash install.sh --check # solo comprueba el sistema, no instala nada
|
||||||
```
|
```
|
||||||
|
|
||||||
### En un portátil Linux
|
Después, en la Raspberry, activa el arranque al escritorio:
|
||||||
|
|
||||||
FOSFENO también corre en un portátil con Debian, Ubuntu o Mint, sin Raspberry
|
|
||||||
Pi. Se instala con `bash install.sh --laptop` y se arranca cuando quieras con
|
|
||||||
`./fosfeno`. Los detalles están en [FOSFENO en un portátil](docs/portatil.md).
|
|
||||||
|
|
||||||
Después:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo raspi-config # System Options → Boot/Auto Login → Desktop Autologin
|
sudo raspi-config # System Options → Boot/Auto Login → Desktop Autologin
|
||||||
|
|
@ -91,6 +89,49 @@ sudo reboot
|
||||||
|
|
||||||
Al reiniciar, la Pi arranca sola en modo kiosko mostrando las visuales.
|
Al reiniciar, la Pi arranca sola en modo kiosko mostrando las visuales.
|
||||||
|
|
||||||
|
### En un portátil Linux
|
||||||
|
|
||||||
|
FOSFENO no necesita la Raspberry: corre igual en un portátil con Debian,
|
||||||
|
Ubuntu o Mint. El portátil ya trae micrófono y cámara, y lo conectas al
|
||||||
|
proyector por HDMI como cualquier otra cosa.
|
||||||
|
|
||||||
|
```
|
||||||
|
[ Música de la sala ]
|
||||||
|
│ (micrófono integrado, o USB)
|
||||||
|
▼
|
||||||
|
┌────────────────────────┐
|
||||||
|
│ Portátil Linux │── HDMI ──▶ [ Proyector :: visuales ]
|
||||||
|
│ ./fosfeno │
|
||||||
|
└───────────┬────────────┘
|
||||||
|
│
|
||||||
|
Panel: http://localhost:8080/
|
||||||
|
(o desde el móvil, en la misma red Wi-Fi)
|
||||||
|
```
|
||||||
|
|
||||||
|
Se instala una vez y se arranca a mano cuando lo necesites:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash install.sh --laptop # instala, sin tocar el arranque del sistema
|
||||||
|
./fosfeno # arranca FOSFENO; Ctrl+C para cerrarlo
|
||||||
|
```
|
||||||
|
|
||||||
|
Diferencias con la Raspberry Pi:
|
||||||
|
|
||||||
|
| | Raspberry Pi | Portátil Linux |
|
||||||
|
|---|---|---|
|
||||||
|
| Arranque | Automático al encender | A mano, con `./fosfeno` |
|
||||||
|
| Modo kiosko | Sí: visuales a pantalla completa al arrancar | **No**: ventana normal que mueves al proyector |
|
||||||
|
| Puerto del panel | 80 — `http://fosfeno.local/` | 8080 — `http://localhost:8080/` |
|
||||||
|
| Micrófono y cámara | Por USB | Los integrados del portátil |
|
||||||
|
| Cambios en el sistema | Arranque automático y nombre de red | Ninguno |
|
||||||
|
|
||||||
|
La diferencia clave: en el portátil **no se usa el modo kiosko**. Las visuales
|
||||||
|
salen en una ventana de navegador normal que arrastras a la pantalla del
|
||||||
|
proyector y pones a pantalla completa con F11. Así FOSFENO no se apodera de tu
|
||||||
|
pantalla ni se mete en el arranque del sistema; lo abres y lo cierras tú.
|
||||||
|
|
||||||
|
Guía completa: [FOSFENO en un portátil](docs/portatil.md).
|
||||||
|
|
||||||
## Uso
|
## Uso
|
||||||
|
|
||||||
- **Visuales** → salen automáticamente por el proyector (HDMI).
|
- **Visuales** → salen automáticamente por el proyector (HDMI).
|
||||||
|
|
|
||||||
9
web/panel/fonts/README.txt
Normal file
9
web/panel/fonts/README.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
Fuente del panel
|
||||||
|
================
|
||||||
|
|
||||||
|
xirod.otf - fuente "Xirod", usada para el titulo del panel.
|
||||||
|
Descargada de 1001fonts.com. Comprueba sus condiciones de uso si vas a
|
||||||
|
distribuir el proyecto con fines comerciales.
|
||||||
|
|
||||||
|
Para cambiar la fuente del titulo, sustituye este archivo y ajusta la
|
||||||
|
regla @font-face de web/panel/panel.css.
|
||||||
BIN
web/panel/fonts/xirod.otf
Normal file
BIN
web/panel/fonts/xirod.otf
Normal file
Binary file not shown.
|
|
@ -10,7 +10,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>F O S F E N O</h1>
|
<h1>FOSFENO</h1>
|
||||||
<span id="conn" class="dot off" title="Conexion"></span>
|
<span id="conn" class="dot off" title="Conexion"></span>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -20,167 +20,176 @@
|
||||||
<button id="notif-close" aria-label="Cerrar aviso">×</button>
|
<button id="notif-close" aria-label="Cerrar aviso">×</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- En movil las tarjetas van en una sola columna; en pantalla ancha,
|
||||||
|
en dos columnas (.column pasa a display:contents en movil). -->
|
||||||
<main>
|
<main>
|
||||||
<!-- Encendido -->
|
<div class="column">
|
||||||
<section class="card center">
|
|
||||||
<div class="cardhead">
|
|
||||||
<span class="label">Visuales</span>
|
|
||||||
<button class="info" data-help="power">i</button>
|
|
||||||
</div>
|
|
||||||
<button id="power" class="power-btn">ON</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Selector de motor -->
|
<!-- Encendido -->
|
||||||
<section class="card">
|
<section class="card center" id="card-power">
|
||||||
<div class="cardhead">
|
<div class="cardhead">
|
||||||
<span class="label">Motor de visuales</span>
|
<span class="label">Visuales</span>
|
||||||
<button class="info" data-help="engines">i</button>
|
<button class="info" data-help="power">i</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="engines">
|
<button id="power" class="power-btn">ON</button>
|
||||||
<button class="engine" data-engine="projectm">
|
</section>
|
||||||
<strong>projectM</strong><small>nativo</small></button>
|
|
||||||
<button class="engine" data-engine="butterchurn">
|
|
||||||
<strong>Butter</strong><small>MilkDrop</small></button>
|
|
||||||
<button class="engine" data-engine="hydra">
|
|
||||||
<strong>Hydra</strong><small>codigo</small></button>
|
|
||||||
<button class="engine" data-engine="shaders">
|
|
||||||
<strong>Shaders</strong><small>GLSL</small></button>
|
|
||||||
<button class="engine" data-engine="mixer">
|
|
||||||
<strong>Mezcla</strong><small>camara</small></button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Audio: tarjeta + BPM -->
|
<!-- Audio: tarjeta + BPM -->
|
||||||
<section class="card">
|
<section class="card" id="card-audio">
|
||||||
<div class="cardhead">
|
<div class="cardhead">
|
||||||
<span class="label">Audio</span>
|
<span class="label">Audio</span>
|
||||||
<button class="info" data-help="audio">i</button>
|
<button class="info" data-help="audio">i</button>
|
||||||
</div>
|
</div>
|
||||||
<select id="audio-device"><option>Detectando entradas...</option></select>
|
<select id="audio-device"><option>Detectando entradas...</option></select>
|
||||||
<button id="dev-rescan" class="cmd">Buscar dispositivos de nuevo</button>
|
<button id="dev-rescan" class="cmd">Buscar dispositivos de nuevo</button>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="label">BPM detectado</span>
|
<span class="label">BPM detectado</span>
|
||||||
<span id="bpm" class="bpm">--</span>
|
<span id="bpm" class="bpm">--</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="hint">Si conectas el microfono o la camara con la Raspberry ya
|
<p class="hint">Si conectas el microfono o la camara con el equipo ya
|
||||||
encendida, pulsa este boton para que aparezcan.</p>
|
encendido, pulsa este boton para que aparezcan.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Sensibilidad -->
|
<!-- Sensibilidad -->
|
||||||
<section class="card">
|
<section class="card" id="card-sens">
|
||||||
<div class="cardhead">
|
<div class="cardhead">
|
||||||
<span class="label">Sensibilidad al audio:
|
<span class="label">Sensibilidad al audio:
|
||||||
<span id="sens-val" class="value">1.0</span></span>
|
<span id="sens-val" class="value">1.0</span></span>
|
||||||
<button class="info" data-help="sensibilidad">i</button>
|
<button class="info" data-help="sensibilidad">i</button>
|
||||||
</div>
|
</div>
|
||||||
<input id="sens" type="range" min="0" max="4" step="0.1" value="1">
|
<input id="sens" type="range" min="0" max="4" step="0.1" value="1">
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Butterchurn -->
|
<!-- Estado -->
|
||||||
<section class="card" id="ctl-butterchurn" hidden>
|
<section class="card" id="card-now">
|
||||||
<div class="cardhead">
|
<span class="label">Ahora suena</span>
|
||||||
<span class="label">Butterchurn</span>
|
<div id="now" class="now">-</div>
|
||||||
<button class="info" data-help="butterchurn">i</button>
|
</section>
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<button class="cmd" data-action="prev">« Anterior</button>
|
|
||||||
<button class="cmd" data-action="next">Siguiente »</button>
|
|
||||||
</div>
|
|
||||||
<select id="bc-preset"><option>Cargando presets...</option></select>
|
|
||||||
<label class="check">
|
|
||||||
<input type="checkbox" id="bc-shuffle"> Cambio automatico de preset
|
|
||||||
</label>
|
|
||||||
<div class="seg">
|
|
||||||
<button id="bc-mode-seconds" class="segbtn">Por segundos</button>
|
|
||||||
<button id="bc-mode-beats" class="segbtn">Al compas (BPM)</button>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<span class="label">Intervalo: <span id="bc-int-val">20</span>
|
|
||||||
<span id="bc-int-unit">s</span></span>
|
|
||||||
</div>
|
|
||||||
<input id="bc-interval" type="range" min="1" max="120" step="1" value="20">
|
|
||||||
<div class="row">
|
|
||||||
<span class="label">Transicion: <span id="bc-blend-val">2.7</span> s</span>
|
|
||||||
</div>
|
|
||||||
<input id="bc-blend" type="range" min="0" max="10" step="0.1" value="2.7">
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Editor de codigo (Hydra / Shaders) -->
|
<!-- Sistema -->
|
||||||
<section class="card" id="ctl-editor" hidden>
|
<section class="card sys" id="card-sys">
|
||||||
<div class="cardhead">
|
<button id="reboot" class="sysbtn">Reiniciar</button>
|
||||||
<span class="label" id="editor-title">Editor de codigo</span>
|
<button id="shutdown" class="sysbtn danger">Apagar</button>
|
||||||
<button class="info" id="editor-info" data-help="hydra">i</button>
|
</section>
|
||||||
</div>
|
|
||||||
<select id="lib-select"><option>Libreria...</option></select>
|
|
||||||
<textarea id="code"></textarea>
|
|
||||||
<div class="row">
|
|
||||||
<button id="run-code" class="cmd accent">Ejecutar</button>
|
|
||||||
<button id="clear-code" class="cmd">Limpiar</button>
|
|
||||||
</div>
|
|
||||||
<p class="hint" id="editor-hint"></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Mezclador VJ -->
|
<p id="net-foot" class="netfoot">FOSFENO</p>
|
||||||
<section class="card" id="ctl-mixer" hidden>
|
</div>
|
||||||
<div class="cardhead">
|
|
||||||
<span class="label">Mezclador VJ</span>
|
|
||||||
<button class="info" data-help="mixer">i</button>
|
|
||||||
</div>
|
|
||||||
<div class="seg" id="mixer-source">
|
|
||||||
<button class="segbtn" data-src="cam">Camara</button>
|
|
||||||
<button class="segbtn" data-src="video">Video</button>
|
|
||||||
<button class="segbtn" data-src="mix">Mezcla</button>
|
|
||||||
</div>
|
|
||||||
<label class="check">
|
|
||||||
<input type="checkbox" id="mix-cam"> Camara activada
|
|
||||||
</label>
|
|
||||||
<select id="mix-camera"><option value="0">Camara por defecto</option></select>
|
|
||||||
<select id="mix-video"><option value="">-- sin video --</option></select>
|
|
||||||
<button id="mix-rescan" class="cmd">Actualizar lista de videos</button>
|
|
||||||
<div class="row">
|
|
||||||
<span class="label">Modo de mezcla</span>
|
|
||||||
<select id="mix-blend" class="inline">
|
|
||||||
<option value="blend">Fundido</option>
|
|
||||||
<option value="diff">Diferencia</option>
|
|
||||||
<option value="mult">Multiplicar</option>
|
|
||||||
<option value="add">Sumar</option>
|
|
||||||
<option value="layer">Capa</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div id="mixer-sliders"></div>
|
|
||||||
<label class="check">
|
|
||||||
<input type="checkbox" id="mix-invert"> Invertir colores
|
|
||||||
</label>
|
|
||||||
<label class="check">
|
|
||||||
<input type="checkbox" id="mix-beat"> Pulso al ritmo
|
|
||||||
</label>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- projectM -->
|
<div class="column">
|
||||||
<section class="card" id="ctl-projectm" hidden>
|
|
||||||
<div class="cardhead">
|
|
||||||
<span class="label">projectM</span>
|
|
||||||
<button class="info" data-help="projectm">i</button>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<button class="cmd" data-action="prev">« Anterior</button>
|
|
||||||
<button class="cmd" data-action="next">Siguiente »</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Estado -->
|
<!-- Selector de motor -->
|
||||||
<section class="card">
|
<section class="card" id="card-engines">
|
||||||
<span class="label">Ahora suena</span>
|
<div class="cardhead">
|
||||||
<div id="now" class="now">-</div>
|
<span class="label">Motor de visuales</span>
|
||||||
</section>
|
<button class="info" data-help="engines">i</button>
|
||||||
|
</div>
|
||||||
|
<div class="engines">
|
||||||
|
<button class="engine" data-engine="projectm">
|
||||||
|
<strong>projectM</strong><small>nativo</small></button>
|
||||||
|
<button class="engine" data-engine="butterchurn">
|
||||||
|
<strong>Butter</strong><small>MilkDrop</small></button>
|
||||||
|
<button class="engine" data-engine="hydra">
|
||||||
|
<strong>Hydra</strong><small>codigo</small></button>
|
||||||
|
<button class="engine" data-engine="shaders">
|
||||||
|
<strong>Shaders</strong><small>GLSL</small></button>
|
||||||
|
<button class="engine" data-engine="mixer">
|
||||||
|
<strong>Mezcla</strong><small>camara</small></button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Sistema -->
|
<!-- Butterchurn -->
|
||||||
<section class="card sys">
|
<section class="card" id="ctl-butterchurn" hidden>
|
||||||
<button id="reboot" class="sysbtn">Reiniciar Pi</button>
|
<div class="cardhead">
|
||||||
<button id="shutdown" class="sysbtn danger">Apagar Pi</button>
|
<span class="label">Butterchurn</span>
|
||||||
</section>
|
<button class="info" data-help="butterchurn">i</button>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<button class="cmd" data-action="prev">« Anterior</button>
|
||||||
|
<button class="cmd" data-action="next">Siguiente »</button>
|
||||||
|
</div>
|
||||||
|
<select id="bc-preset"><option>Cargando presets...</option></select>
|
||||||
|
<label class="check">
|
||||||
|
<input type="checkbox" id="bc-shuffle"> Cambio automatico de preset
|
||||||
|
</label>
|
||||||
|
<div class="seg">
|
||||||
|
<button id="bc-mode-seconds" class="segbtn">Por segundos</button>
|
||||||
|
<button id="bc-mode-beats" class="segbtn">Al compas (BPM)</button>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span class="label">Intervalo: <span id="bc-int-val">20</span>
|
||||||
|
<span id="bc-int-unit">s</span></span>
|
||||||
|
</div>
|
||||||
|
<input id="bc-interval" type="range" min="1" max="120" step="1" value="20">
|
||||||
|
<div class="row">
|
||||||
|
<span class="label">Transicion: <span id="bc-blend-val">2.7</span> s</span>
|
||||||
|
</div>
|
||||||
|
<input id="bc-blend" type="range" min="0" max="10" step="0.1" value="2.7">
|
||||||
|
</section>
|
||||||
|
|
||||||
<p id="net-foot" class="netfoot">FOSFENO</p>
|
<!-- Editor de codigo (Hydra / Shaders) -->
|
||||||
|
<section class="card" id="ctl-editor" hidden>
|
||||||
|
<div class="cardhead">
|
||||||
|
<span class="label" id="editor-title">Editor de codigo</span>
|
||||||
|
<button class="info" id="editor-info" data-help="hydra">i</button>
|
||||||
|
</div>
|
||||||
|
<select id="lib-select"><option>Libreria...</option></select>
|
||||||
|
<textarea id="code"></textarea>
|
||||||
|
<div class="row">
|
||||||
|
<button id="run-code" class="cmd accent">Ejecutar</button>
|
||||||
|
<button id="clear-code" class="cmd">Limpiar</button>
|
||||||
|
</div>
|
||||||
|
<p class="hint" id="editor-hint"></p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Mezclador VJ -->
|
||||||
|
<section class="card" id="ctl-mixer" hidden>
|
||||||
|
<div class="cardhead">
|
||||||
|
<span class="label">Mezclador VJ</span>
|
||||||
|
<button class="info" data-help="mixer">i</button>
|
||||||
|
</div>
|
||||||
|
<div class="seg" id="mixer-source">
|
||||||
|
<button class="segbtn" data-src="cam">Camara</button>
|
||||||
|
<button class="segbtn" data-src="video">Video</button>
|
||||||
|
<button class="segbtn" data-src="mix">Mezcla</button>
|
||||||
|
</div>
|
||||||
|
<label class="check">
|
||||||
|
<input type="checkbox" id="mix-cam"> Camara activada
|
||||||
|
</label>
|
||||||
|
<select id="mix-camera"><option value="0">Camara por defecto</option></select>
|
||||||
|
<select id="mix-video"><option value="">-- sin video --</option></select>
|
||||||
|
<button id="mix-rescan" class="cmd">Actualizar lista de videos</button>
|
||||||
|
<div class="row">
|
||||||
|
<span class="label">Modo de mezcla</span>
|
||||||
|
<select id="mix-blend" class="inline">
|
||||||
|
<option value="blend">Fundido</option>
|
||||||
|
<option value="diff">Diferencia</option>
|
||||||
|
<option value="mult">Multiplicar</option>
|
||||||
|
<option value="add">Sumar</option>
|
||||||
|
<option value="layer">Capa</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="mixer-sliders"></div>
|
||||||
|
<label class="check">
|
||||||
|
<input type="checkbox" id="mix-invert"> Invertir colores
|
||||||
|
</label>
|
||||||
|
<label class="check">
|
||||||
|
<input type="checkbox" id="mix-beat"> Pulso al ritmo
|
||||||
|
</label>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- projectM -->
|
||||||
|
<section class="card" id="ctl-projectm" hidden>
|
||||||
|
<div class="cardhead">
|
||||||
|
<span class="label">projectM</span>
|
||||||
|
<button class="info" data-help="projectm">i</button>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<button class="cmd" data-action="prev">« Anterior</button>
|
||||||
|
<button class="cmd" data-action="next">Siguiente »</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Ventana de informacion -->
|
<!-- Ventana de informacion -->
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
/* FOSFENO :: Panel de control
|
/* FOSFENO :: Panel de control
|
||||||
Tema verde acido y negro, con acentos en naranja neon. */
|
Tema verde acido y negro, con acentos en naranja neon.
|
||||||
|
Movil: una columna. Pantalla ancha: dos columnas. */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Xirod";
|
||||||
|
src: url("/panel/fonts/xirod.otf") format("opentype");
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg: #060a06;
|
--bg: #060a06;
|
||||||
--card: #0d120c;
|
--card: #0d120c;
|
||||||
|
|
@ -27,24 +35,52 @@ body {
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Cabecera con el titulo centrado --- */
|
||||||
header {
|
header {
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
position: sticky; top: 0; z-index: 10;
|
||||||
padding: 18px 20px; border-bottom: 2px solid var(--green-d);
|
display: flex; align-items: center; justify-content: center;
|
||||||
position: sticky; top: 0; background: var(--bg); z-index: 10;
|
padding: 16px 20px; border-bottom: 2px solid var(--green-d);
|
||||||
|
background: var(--bg);
|
||||||
}
|
}
|
||||||
header h1 {
|
header h1 {
|
||||||
font-size: 20px; font-weight: 800; letter-spacing: 0.32em;
|
font-family: "Xirod", "Arial Black", sans-serif;
|
||||||
color: var(--green); text-shadow: 0 0 14px rgba(180, 255, 0, 0.55);
|
font-size: 21px; font-weight: 400; letter-spacing: 0.16em;
|
||||||
|
color: var(--green); text-shadow: 0 0 16px rgba(180, 255, 0, 0.6);
|
||||||
|
}
|
||||||
|
#conn {
|
||||||
|
position: absolute; right: 20px; top: 50%; transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dot { width: 13px; height: 13px; border-radius: 50%; display: inline-block; }
|
.dot { width: 13px; height: 13px; border-radius: 50%; display: inline-block; }
|
||||||
.dot.on { background: var(--green); box-shadow: 0 0 9px var(--green); }
|
.dot.on { background: var(--green); box-shadow: 0 0 9px var(--green); }
|
||||||
.dot.off { background: var(--red); box-shadow: 0 0 9px var(--red); }
|
.dot.off { background: var(--red); box-shadow: 0 0 9px var(--red); }
|
||||||
|
|
||||||
|
/* --- Disposicion: movil en una columna --- */
|
||||||
main {
|
main {
|
||||||
max-width: 560px; margin: 0 auto;
|
max-width: 560px; margin: 0 auto;
|
||||||
padding: 16px; display: flex; flex-direction: column; gap: 14px;
|
padding: 16px; display: flex; flex-direction: column; gap: 14px;
|
||||||
}
|
}
|
||||||
|
.column { display: contents; } /* en movil, las columnas no existen */
|
||||||
|
|
||||||
|
/* Orden de las tarjetas cuando estan todas en una sola columna (movil) */
|
||||||
|
#card-power { order: 1; }
|
||||||
|
#card-engines { order: 2; }
|
||||||
|
#card-audio { order: 3; }
|
||||||
|
#card-sens { order: 4; }
|
||||||
|
#ctl-butterchurn, #ctl-editor, #ctl-mixer, #ctl-projectm { order: 5; }
|
||||||
|
#card-now { order: 6; }
|
||||||
|
#card-sys { order: 7; }
|
||||||
|
#net-foot { order: 8; }
|
||||||
|
|
||||||
|
/* --- Disposicion: pantalla ancha (portatil) en dos columnas --- */
|
||||||
|
@media (min-width: 880px) {
|
||||||
|
main {
|
||||||
|
max-width: 1080px; flex-direction: row;
|
||||||
|
align-items: flex-start; gap: 18px;
|
||||||
|
}
|
||||||
|
.column {
|
||||||
|
display: flex; flex-direction: column; gap: 14px; flex: 1 1 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Tarjetas --- */
|
/* --- Tarjetas --- */
|
||||||
.card {
|
.card {
|
||||||
|
|
@ -54,9 +90,10 @@ main {
|
||||||
}
|
}
|
||||||
.card.center { align-items: center; }
|
.card.center { align-items: center; }
|
||||||
|
|
||||||
|
/* Cabecera de tarjeta: titulo centrado, boton de info a la derecha */
|
||||||
.cardhead {
|
.cardhead {
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
position: relative; width: 100%;
|
||||||
gap: 10px; width: 100%;
|
display: flex; align-items: center; justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label { color: var(--green); font-size: 13px; text-transform: uppercase;
|
.label { color: var(--green); font-size: 13px; text-transform: uppercase;
|
||||||
|
|
@ -68,9 +105,10 @@ main {
|
||||||
gap: 10px; }
|
gap: 10px; }
|
||||||
.row .cmd { flex: 1; }
|
.row .cmd { flex: 1; }
|
||||||
|
|
||||||
/* --- Boton de informacion (circular naranja) --- */
|
/* --- Boton de informacion (circular naranja, esquina de la tarjeta) --- */
|
||||||
.info {
|
.info {
|
||||||
width: 28px; height: 28px; flex: none; border-radius: 50%;
|
position: absolute; right: 0; top: 50%; transform: translateY(-50%);
|
||||||
|
width: 28px; height: 28px; border-radius: 50%;
|
||||||
background: var(--orange); color: var(--ink); border: none;
|
background: var(--orange); color: var(--ink); border: none;
|
||||||
font-weight: 900; font-style: italic; font-size: 15px; cursor: pointer;
|
font-weight: 900; font-style: italic; font-size: 15px; cursor: pointer;
|
||||||
box-shadow: 0 0 10px rgba(255, 122, 0, 0.5);
|
box-shadow: 0 0 10px rgba(255, 122, 0, 0.5);
|
||||||
|
|
@ -115,9 +153,7 @@ main {
|
||||||
font-weight: 700; font-size: 14px;
|
font-weight: 700; font-size: 14px;
|
||||||
}
|
}
|
||||||
.cmd:active, .sysbtn:active { background: #202a16; }
|
.cmd:active, .sysbtn:active { background: #202a16; }
|
||||||
.cmd.accent {
|
.cmd.accent { background: var(--green); color: var(--ink); border: none; }
|
||||||
background: var(--green); color: var(--ink); border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Selectores y sliders --- */
|
/* --- Selectores y sliders --- */
|
||||||
select {
|
select {
|
||||||
|
|
@ -165,6 +201,8 @@ input[type=range] { width: 100%; accent-color: var(--green); height: 30px; }
|
||||||
font-size: 13px; font-family: "Fira Mono", Consolas, monospace;
|
font-size: 13px; font-family: "Fira Mono", Consolas, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Tarjeta de estado --- */
|
||||||
|
#card-now { text-align: center; }
|
||||||
.now { font-size: 15px; color: var(--orange-n); word-break: break-word; }
|
.now { font-size: 15px; color: var(--orange-n); word-break: break-word; }
|
||||||
|
|
||||||
/* --- Sistema --- */
|
/* --- Sistema --- */
|
||||||
|
|
@ -172,11 +210,17 @@ input[type=range] { width: 100%; accent-color: var(--green); height: 30px; }
|
||||||
.sys .sysbtn { flex: 1; }
|
.sys .sysbtn { flex: 1; }
|
||||||
.sysbtn.danger { color: var(--red); border-color: var(--red); }
|
.sysbtn.danger { color: var(--red); border-color: var(--red); }
|
||||||
|
|
||||||
|
/* --- Pie con la direccion del panel --- */
|
||||||
|
.netfoot {
|
||||||
|
text-align: center; color: var(--dim);
|
||||||
|
font-size: 12px; font-family: monospace; padding: 4px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Banda de avisos --- */
|
/* --- Banda de avisos --- */
|
||||||
.notif {
|
.notif {
|
||||||
display: flex; align-items: center; gap: 10px;
|
display: flex; align-items: center; gap: 10px;
|
||||||
padding: 12px 16px; font-size: 14px; font-weight: 600;
|
padding: 12px 16px; font-size: 14px; font-weight: 600;
|
||||||
position: sticky; top: 60px; z-index: 9;
|
position: sticky; top: 56px; z-index: 9;
|
||||||
}
|
}
|
||||||
.notif.info { background: var(--green); color: var(--ink); }
|
.notif.info { background: var(--green); color: var(--ink); }
|
||||||
.notif.warn { background: var(--orange); color: var(--ink); }
|
.notif.warn { background: var(--orange); color: var(--ink); }
|
||||||
|
|
@ -201,12 +245,8 @@ input[type=range] { width: 100%; accent-color: var(--green); height: 30px; }
|
||||||
box-shadow: 0 0 30px rgba(180, 255, 0, 0.3);
|
box-shadow: 0 0 30px rgba(180, 255, 0, 0.3);
|
||||||
}
|
}
|
||||||
.modal-box h2 {
|
.modal-box h2 {
|
||||||
color: var(--green); font-size: 18px; letter-spacing: 0.04em;
|
font-family: "Xirod", "Arial Black", sans-serif; font-weight: 400;
|
||||||
|
color: var(--green); font-size: 16px; letter-spacing: 0.06em;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.modal-box p { color: var(--txt); font-size: 14px; line-height: 1.5; }
|
.modal-box p { color: var(--txt); font-size: 14px; line-height: 1.5; }
|
||||||
|
|
||||||
/* Pie con la direccion del panel */
|
|
||||||
.netfoot {
|
|
||||||
text-align: center; color: var(--dim);
|
|
||||||
font-size: 12px; font-family: monospace; padding: 4px 0 8px;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue