style: light theme and hand-inked logo matching acampada26s.net

The previous pass kept the dark base and the red icons, which did not
read as the acampada. Now:

- Light theme: white page, black ink and borders, black buttons with a
  hard neon offset shadow, neon for focus and the active nav item;
  h1/h2 in Anton with the stepped neon shadow of the site headings.
- Nav, empty-state, spinner and pattern assets in black; platform icons
  keep their dark disc with a neon stroke.
- New mark: three dome tents wired from their doors into a switch with
  an antenna, drawn in the inked style of the acampada logo (curved
  poles, ball ends, hatching) over a neon offset copy. LogoMark renders
  it inline; visible product name is T-HUB.
- docs/brand: t-hub.svg and a lockup with the Anton wordmark converted
  to outlines so it renders without the font.
- Public submission page moved to the light palette.

Checked with headless Chromium screenshots (offline sample data) on
desktop and mobile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hacklab 2026-10-15 14:40:02 +02:00
parent 533a0fb1c0
commit cfabbf20ef
49 changed files with 369 additions and 286 deletions

View file

@ -1,6 +1,6 @@
# T-HUB
<p align="center"><img src="docs/brand/t-hub.svg" width="160" alt="T-HUB"></p>
<p align="center"><img src="docs/brand/t-hub-lockup.png" width="520" alt="T-HUB"></p>
Copia de trabajo del [Tactical Media Broadcast Hub](https://gitlab.moxexley.com/mediatools/tacticalmediahub)
para la red de acampadas: [acampada26s.net](https://acampada26s.net),
@ -16,7 +16,7 @@ Cambios respecto a upstream:
- Instagram registrado en conexión y publicación; claves de la app de Meta solo en el entorno del servidor.
- Panel **Outreach** para escribir por privado a mano, contacto a contacto, con seguimiento.
- RLS forzado en `media_assets` (migración 042).
- Estilo de acampada26s.net en la web: negro, blanco, neón `#00e5ff` y títulos en Anton.
- Estilo de acampada26s.net en la web: fondo blanco, tinta negra, neón `#00e5ff` en sombras y foco, títulos en Anton. Logo de tres tiendas cableadas a un switch con antena, dibujado como el de la acampada (`docs/brand/`).
| Remoto | URL |
|---|---|

View file

@ -1,11 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1700 1700">
<g transform="rotate(-17.5 850 850)" opacity="0.25">
<circle cx="850" cy="850" r="350" fill="none" stroke="#FF1610" stroke-width="60" stroke-linecap="round"/>
<circle cx="850" cy="850" r="350" fill="none" stroke="#000000" stroke-width="60" stroke-linecap="round"/>
<path d="M 850 405 L 464.77 1269.52 M 850 405 L 1235.23 1269.52 M 345 850 L 1355 850"
fill="none" stroke="#FF1610" stroke-width="75" stroke-linecap="round" stroke-linejoin="round"/>
fill="none" stroke="#000000" stroke-width="75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g opacity="0.6">
<polygon points="1450,850 1550,810 1550,890" fill="#FF1610"/>
<line x1="1280" y1="850" x2="1470" y2="850" stroke="#FF1610" stroke-width="30" stroke-linecap="round"/>
<polygon points="1450,850 1550,810 1550,890" fill="#000000"/>
<line x1="1280" y1="850" x2="1470" y2="850" stroke="#000000" stroke-width="30" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 665 B

Before After
Before After

View file

@ -1,40 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-labelledby="t">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" role="img" aria-labelledby="t">
<title id="t">T-HUB</title>
<circle cx="120" cy="120" r="118" fill="#000"/>
<circle cx="120" cy="120" r="82" fill="none" stroke="#fff" stroke-width="2" stroke-dasharray="3 7" opacity=".55"/>
<!-- cables: each leaves through a tent door and runs to the switch -->
<g fill="none" stroke="#00e5ff" stroke-width="4" stroke-linecap="round">
<path d="M49 94 C 52 122, 74 130, 96 130"/>
<path d="M191 94 C 188 122, 166 130, 144 130"/>
<path d="M120 216 C 120 196, 120 168, 120 140"/>
<defs>
<!-- Dome tent in the hand-inked style of the acampada26s.net mark:
curved poles with ball ends, centre seam, hatched panel, door.
Base midpoint at 0,0. -->
<g id="tienda" stroke-linecap="round" stroke-linejoin="round">
<path fill="none" d="M-58 0 Q-56 -66 -1 -72 Q55 -66 58 0" stroke-width="7"/>
<path fill="none" d="M-64 1 Q0 -3 64 1" stroke-width="6"/>
<path fill="none" d="M-44 0 Q-30 -58 -1 -72" stroke-width="4.5"/>
<path fill="none" d="M44 0 Q30 -58 -1 -72" stroke-width="4.5"/>
<path d="M-15 0 Q-14 -30 0 -33 Q14 -30 15 0 Z" stroke-width="4"/>
<path fill="none" d="M-50 -14 L-41 -25 M-50 -4 L-37 -19 M-43 -1 L-33 -13 M-52 -27 L-45 -36" stroke-width="2.6"/>
<path fill="none" d="M28 -50 L37 -42 M24 -40 L36 -30 M22 -29 L34 -19" stroke-width="2.6"/>
<circle cx="-64" cy="1" r="5.5" stroke="none"/>
<circle cx="64" cy="1" r="5.5" stroke="none"/>
<circle cx="-1" cy="-73" r="5.5" stroke="none"/>
</g>
<g id="marca" stroke-linecap="round" stroke-linejoin="round">
<!-- cables: out of each tent door to the switch -->
<path fill="none" d="M105 150 Q112 206 168 214" stroke-width="5"/>
<path fill="none" d="M295 150 Q288 206 232 214" stroke-width="5"/>
<path fill="none" d="M200 318 Q197 280 200 236" stroke-width="5"/>
<!-- antenna -->
<path fill="none" d="M200 200 Q198 160 200 118" stroke-width="6"/>
<path fill="none" d="M184 98 Q200 82 216 98" stroke-width="5"/>
<path fill="none" d="M171 88 Q200 58 229 88" stroke-width="5"/>
<circle cx="200" cy="112" r="7" stroke="none"/>
<!-- switch -->
<path d="M168 201 L233 200 L234 235 L167 236 Z" stroke-width="6" fill="#fff"/>
<path d="M179 212 h9 v11 h-9 z M196 212 h9 v11 h-9 z M213 212 h9 v11 h-9 z" stroke="none"/>
<use xlink:href="#tienda" transform="translate(105,150)"/>
<use xlink:href="#tienda" transform="translate(295,150)"/>
<use xlink:href="#tienda" transform="translate(200,340)"/>
</g>
</defs>
<!-- neon offset underneath, ink on top, as on acampada26s.net -->
<g transform="translate(7,7)" stroke="#00e5ff" fill="#00e5ff">
<use xlink:href="#marca"/>
</g>
<!-- tents -->
<g stroke="#fff" stroke-width="3" stroke-linejoin="round">
<polygon points="19,99 49,55 79,99" fill="#000"/>
<polygon points="161,99 191,55 221,99" fill="#000"/>
<polygon points="90,221 120,177 150,221" fill="#000"/>
</g>
<g fill="#00e5ff">
<polygon points="40,99 49,80 58,99"/>
<polygon points="182,99 191,80 200,99"/>
<polygon points="111,221 120,202 129,221"/>
</g>
<!-- antenna -->
<line x1="120" y1="120" x2="120" y2="70" stroke="#fff" stroke-width="4" stroke-linecap="round"/>
<circle cx="120" cy="68" r="5" fill="#00e5ff"/>
<g fill="none" stroke="#00e5ff" stroke-width="3" stroke-linecap="round">
<path d="M106 56 A 18 18 0 0 1 134 56"/>
<path d="M97 46 A 30 30 0 0 1 143 46"/>
</g>
<!-- switch -->
<rect x="94" y="118" width="52" height="24" rx="3" fill="#fff"/>
<g fill="#000">
<rect x="101" y="125" width="9" height="9"/>
<rect x="115.5" y="125" width="9" height="9"/>
<rect x="130" y="125" width="9" height="9"/>
<g stroke="#000" fill="#000">
<use xlink:href="#marca"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Bluesky</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 350 450 Q 400 350 500 400 L 600 480 L 700 400 Q 800 350 850 450 Q 850 550 750 650 L 600 780 L 450 650 Q 350 550 350 450 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 350 450 Q 400 350 500 400 L 600 480 L 700 400 Q 800 350 850 450 Q 850 550 750 650 L 600 780 L 450 650 Q 350 550 350 450 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 483 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Discord</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 450 450 Q 550 400 600 400 Q 650 400 750 450 L 800 500 Q 850 600 800 700 L 750 750 L 700 700 L 650 720 L 550 720 L 500 700 L 450 750 L 400 700 Q 350 600 400 500 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linejoin="round"/><circle cx="520" cy="570" r="18" fill="#FF1610"/><circle cx="680" cy="570" r="18" fill="#FF1610"/>
<path d="M 450 450 Q 550 400 600 400 Q 650 400 750 450 L 800 500 Q 850 600 800 700 L 750 750 L 700 700 L 650 720 L 550 720 L 500 700 L 450 750 L 400 700 Q 350 600 400 500 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linejoin="round"/><circle cx="520" cy="570" r="18" fill="#00E5FF"/><circle cx="680" cy="570" r="18" fill="#00E5FF"/>
</svg>

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 598 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Facebook</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 500 450 L 500 550 L 450 550 L 450 650 L 500 650 L 500 850 L 600 850 L 600 650 L 680 650 L 700 550 L 600 550 L 600 480 Q 600 450 630 450 L 700 450 L 700 380 L 620 380 Q 500 380 500 450 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 500 450 L 500 550 L 450 550 L 450 650 L 500 650 L 500 850 L 600 850 L 600 650 L 680 650 L 700 550 L 600 550 L 600 480 Q 600 450 630 450 L 700 450 L 700 380 L 620 380 Q 500 380 500 450 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 548 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Instagram</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<rect x="350" y="350" width="500" height="500" rx="120" fill="none" stroke="#FF1610" stroke-width="35"/><circle cx="600" cy="600" r="130" fill="none" stroke="#FF1610" stroke-width="35"/><circle cx="770" cy="430" r="25" fill="#FF1610"/>
<rect x="350" y="350" width="500" height="500" rx="120" fill="none" stroke="#00E5FF" stroke-width="35"/><circle cx="600" cy="600" r="130" fill="none" stroke="#00E5FF" stroke-width="35"/><circle cx="770" cy="430" r="25" fill="#00E5FF"/>
</svg>

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 491 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Linkedin</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<rect x="350" y="350" width="500" height="100" rx="20" fill="none" stroke="#FF1610" stroke-width="35"/><line x1="400" y1="500" x2="400" y2="750" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><line x1="500" y1="500" x2="500" y2="750" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><path d="M 500 500 Q 550 450 600 500 L 600 600 Q 650 550 700 600 Q 750 650 700 700 Q 650 750 500 750" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="350" y="350" width="500" height="100" rx="20" fill="none" stroke="#00E5FF" stroke-width="35"/><line x1="400" y1="500" x2="400" y2="750" stroke="#00E5FF" stroke-width="35" stroke-linecap="round"/><line x1="500" y1="500" x2="500" y2="750" stroke="#00E5FF" stroke-width="35" stroke-linecap="round"/><path d="M 500 500 Q 550 450 600 500 L 600 600 Q 650 550 700 600 Q 750 650 700 700 Q 650 750 500 750" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 757 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Mastodon</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 400 500 L 400 700 Q 400 780 480 780 L 520 780 Q 560 780 560 740 L 560 560 Q 560 540 580 540 Q 600 540 600 560 L 600 740 Q 600 780 640 780 L 680 780 Q 760 780 760 700 L 760 500 Q 760 420 680 420 L 520 420 Q 440 420 400 500 Z M 400 500 L 360 460 Q 320 420 320 500 L 320 660 Q 320 740 380 760" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 400 500 L 400 700 Q 400 780 480 780 L 520 780 Q 560 780 560 740 L 560 560 Q 560 540 580 540 Q 600 540 600 560 L 600 740 Q 600 780 640 780 L 680 780 Q 760 780 760 700 L 760 500 Q 760 420 680 420 L 520 420 Q 440 420 400 500 Z M 400 500 L 360 460 Q 320 420 320 500 L 320 660 Q 320 740 380 760" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 652 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Peertube</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 400 350 L 400 850 L 800 600 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linejoin="round"/>
<path d="M 400 350 L 400 850 L 800 600 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Reddit</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<circle cx="600" cy="500" r="50" fill="#FF1610"/><path d="M 550 500 L 400 450" stroke="#FF1610" stroke-width="25" stroke-linecap="round"/><path d="M 650 500 L 800 450" stroke="#FF1610" stroke-width="25" stroke-linecap="round"/><ellipse cx="600" cy="650" rx="200" ry="140" fill="none" stroke="#FF1610" stroke-width="35"/><circle cx="500" cy="620" r="20" fill="#FF1610"/><circle cx="700" cy="620" r="20" fill="#FF1610"/><path d="M 520 700 Q 600 740 680 700" fill="none" stroke="#FF1610" stroke-width="25" stroke-linecap="round"/>
<circle cx="600" cy="500" r="50" fill="#00E5FF"/><path d="M 550 500 L 400 450" stroke="#00E5FF" stroke-width="25" stroke-linecap="round"/><path d="M 650 500 L 800 450" stroke="#00E5FF" stroke-width="25" stroke-linecap="round"/><ellipse cx="600" cy="650" rx="200" ry="140" fill="none" stroke="#00E5FF" stroke-width="35"/><circle cx="500" cy="620" r="20" fill="#00E5FF"/><circle cx="700" cy="620" r="20" fill="#00E5FF"/><path d="M 520 700 Q 600 740 680 700" fill="none" stroke="#00E5FF" stroke-width="25" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 780 B

After

Width:  |  Height:  |  Size: 780 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Slack</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<rect x="450" y="350" width="80" height="140" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><rect x="670" y="350" width="80" height="140" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><rect x="350" y="530" width="140" height="80" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><rect x="710" y="530" width="140" height="80" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><rect x="450" y="700" width="80" height="140" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><rect x="670" y="700" width="80" height="140" rx="20" fill="none" stroke="#FF1610" stroke-width="30"/><path d="M 530 570 L 670 570" stroke="#FF1610" stroke-width="30" stroke-linecap="round"/>
<rect x="450" y="350" width="80" height="140" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><rect x="670" y="350" width="80" height="140" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><rect x="350" y="530" width="140" height="80" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><rect x="710" y="530" width="140" height="80" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><rect x="450" y="700" width="80" height="140" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><rect x="670" y="700" width="80" height="140" rx="20" fill="none" stroke="#00E5FF" stroke-width="30"/><path d="M 530 570 L 670 570" stroke="#00E5FF" stroke-width="30" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 953 B

After

Width:  |  Height:  |  Size: 953 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Telegram</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 300 600 L 850 400 L 700 800 L 550 650 L 300 600 Z M 550 650 L 550 750 L 620 680" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 300 600 L 850 400 L 700 800 L 550 650 L 300 600 Z M 550 650 L 550 750 L 620 680" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Threads</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 600 350 Q 450 350 400 500 Q 350 650 400 750 Q 450 850 600 850 Q 750 850 800 750 Q 850 650 800 500 Q 750 350 600 350 Z M 550 550 Q 600 500 650 550 Q 700 600 650 650 Q 600 700 550 650 Q 500 600 550 550 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 600 350 Q 450 350 400 500 Q 350 650 400 750 Q 450 850 600 850 Q 750 850 800 750 Q 850 650 800 500 Q 750 350 600 350 Z M 550 550 Q 600 500 650 550 Q 700 600 650 650 Q 600 700 550 650 Q 500 600 550 550 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 563 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1700 1700">
<title>Twitch</title>
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#FF1610" stroke-width="38"
<circle cx="850" cy="850" r="560" fill="#0a0a0b" stroke="#00E5FF" stroke-width="38"
transform="rotate(-17.5 850 850)"/>
<path d="M 400 350 L 800 350 L 800 600 L 650 750 L 500 750 L 400 850 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linejoin="round"/><line x1="550" y1="450" x2="550" y2="550" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><line x1="670" y1="450" x2="670" y2="550" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/>
<path d="M 400 350 L 800 350 L 800 600 L 650 750 L 500 750 L 400 850 Z" fill="none" stroke="#00E5FF" stroke-width="35" stroke-linejoin="round"/><line x1="550" y1="450" x2="550" y2="550" stroke="#00E5FF" stroke-width="35" stroke-linecap="round"/><line x1="670" y1="450" x2="670" y2="550" stroke="#00E5FF" stroke-width="35" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 599 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Analytics</title>
<line x1="350" y1="850" x2="850" y2="850" stroke="#FF1610" stroke-width="40" stroke-linecap="round"/><line x1="420" y1="700" x2="420" y2="850" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><line x1="600" y1="500" x2="600" y2="850" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><line x1="780" y1="400" x2="780" y2="850" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/>
<line x1="350" y1="850" x2="850" y2="850" stroke="#000000" stroke-width="40" stroke-linecap="round"/><line x1="420" y1="700" x2="420" y2="850" stroke="#000000" stroke-width="35" stroke-linecap="round"/><line x1="600" y1="500" x2="600" y2="850" stroke="#000000" stroke-width="35" stroke-linecap="round"/><line x1="780" y1="400" x2="780" y2="850" stroke="#000000" stroke-width="35" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 532 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Approvals</title>
<path d="M 240 640 L 500 880 L 960 320" fill="none" stroke="#FF1610" stroke-width="90" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M 240 640 L 500 880 L 960 320" fill="none" stroke="#000000" stroke-width="90" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Audit</title>
<path d="M 500 350 L 700 350 L 700 500 L 800 500 L 600 850 L 400 500 L 500 500 Z" fill="none" stroke="#FF1610" stroke-width="35" stroke-linejoin="round"/>
<path d="M 500 350 L 700 350 L 700 500 L 800 500 L 600 850 L 400 500 L 500 500 Z" fill="none" stroke="#000000" stroke-width="35" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Calendar</title>
<rect x="350" y="400" width="500" height="450" rx="30" fill="none" stroke="#FF1610" stroke-width="40"/><line x1="350" y1="520" x2="850" y2="520" stroke="#FF1610" stroke-width="30"/><line x1="450" y1="400" x2="450" y2="350" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><line x1="750" y1="400" x2="750" y2="350" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/><circle cx="500" cy="620" r="20" fill="#FF1610"/><circle cx="600" cy="620" r="20" fill="#FF1610"/><circle cx="700" cy="620" r="20" fill="#FF1610"/>
<rect x="350" y="400" width="500" height="450" rx="30" fill="none" stroke="#000000" stroke-width="40"/><line x1="350" y1="520" x2="850" y2="520" stroke="#000000" stroke-width="30"/><line x1="450" y1="400" x2="450" y2="350" stroke="#000000" stroke-width="35" stroke-linecap="round"/><line x1="750" y1="400" x2="750" y2="350" stroke="#000000" stroke-width="35" stroke-linecap="round"/><circle cx="500" cy="620" r="20" fill="#000000"/><circle cx="600" cy="620" r="20" fill="#000000"/><circle cx="700" cy="620" r="20" fill="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 657 B

Before After
Before After

View file

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Chat</title>
<path d="M 220 300 A 80 80 0 0 1 300 220 L 900 220 A 80 80 0 0 1 980 300 L 980 660 A 80 80 0 0 1 900 740 L 520 740 L 340 920 L 340 740 L 300 740 A 80 80 0 0 1 220 660 Z" fill="none" stroke="#FF1610" stroke-width="55" stroke-linejoin="round"/>
<circle cx="450" cy="480" r="45" fill="#FF1610"/>
<circle cx="600" cy="480" r="45" fill="#FF1610"/>
<circle cx="750" cy="480" r="45" fill="#FF1610"/>
<path d="M 220 300 A 80 80 0 0 1 300 220 L 900 220 A 80 80 0 0 1 980 300 L 980 660 A 80 80 0 0 1 900 740 L 520 740 L 340 920 L 340 740 L 300 740 A 80 80 0 0 1 220 660 Z" fill="none" stroke="#000000" stroke-width="55" stroke-linejoin="round"/>
<circle cx="450" cy="480" r="45" fill="#000000"/>
<circle cx="600" cy="480" r="45" fill="#000000"/>
<circle cx="750" cy="480" r="45" fill="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 522 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Compose</title>
<path d="M 400 800 L 350 850 L 400 850 L 850 400 L 800 350 L 350 800" fill="none" stroke="#FF1610" stroke-width="40" stroke-linecap="round" stroke-linejoin="round"/><line x1="750" y1="400" x2="800" y2="450" stroke="#FF1610" stroke-width="30"/>
<path d="M 400 800 L 350 850 L 400 850 L 850 400 L 800 350 L 350 800" fill="none" stroke="#000000" stroke-width="40" stroke-linecap="round" stroke-linejoin="round"/><line x1="750" y1="400" x2="800" y2="450" stroke="#000000" stroke-width="30"/>
</svg>

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Connections</title>
<circle cx="450" cy="500" r="80" fill="none" stroke="#FF1610" stroke-width="35"/><circle cx="750" cy="700" r="80" fill="none" stroke="#FF1610" stroke-width="35"/><line x1="500" y1="550" x2="700" y2="650" stroke="#FF1610" stroke-width="35" stroke-linecap="round"/>
<circle cx="450" cy="500" r="80" fill="none" stroke="#000000" stroke-width="35"/><circle cx="750" cy="700" r="80" fill="none" stroke="#000000" stroke-width="35"/><line x1="500" y1="550" x2="700" y2="650" stroke="#000000" stroke-width="35" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Files</title>
<path d="M 220 380 L 470 380 L 560 470 L 980 470 L 980 860 A 60 60 0 0 1 920 920 L 280 920 A 60 60 0 0 1 220 860 Z" fill="none" stroke="#FF1610" stroke-width="60" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M 220 380 L 470 380 L 560 470 L 980 470 L 980 860 A 60 60 0 0 1 920 920 L 280 920 A 60 60 0 0 1 220 860 Z" fill="none" stroke="#000000" stroke-width="60" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 336 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Home</title>
<path d="M 600 350 L 850 550 L 850 850 L 350 850 L 350 550 Z" fill="none" stroke="#FF1610" stroke-width="40" stroke-linejoin="round"/><line x1="600" y1="350" x2="600" y2="850" stroke="#FF1610" stroke-width="30"/>
<path d="M 600 350 L 850 550 L 850 850 L 350 850 L 350 550 Z" fill="none" stroke="#000000" stroke-width="40" stroke-linejoin="round"/><line x1="600" y1="350" x2="600" y2="850" stroke="#000000" stroke-width="30"/>
</svg>

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 335 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Inbox</title>
<path d="M 350 400 L 850 400 L 850 700 L 700 700 L 600 800 L 500 700 L 350 700 Z" fill="none" stroke="#FF1610" stroke-width="40" stroke-linejoin="round"/>
<path d="M 350 400 L 850 400 L 850 700 L 700 700 L 600 800 L 500 700 L 350 700 Z" fill="none" stroke="#000000" stroke-width="40" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav More</title>
<circle cx="500" cy="600" r="30" fill="#FF1610"/><circle cx="600" cy="600" r="30" fill="#FF1610"/><circle cx="700" cy="600" r="30" fill="#FF1610"/>
<circle cx="500" cy="600" r="30" fill="#000000"/><circle cx="600" cy="600" r="30" fill="#000000"/><circle cx="700" cy="600" r="30" fill="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Search</title>
<circle cx="550" cy="550" r="200" fill="none" stroke="#FF1610" stroke-width="40"/><line x1="700" y1="700" x2="850" y2="850" stroke="#FF1610" stroke-width="40" stroke-linecap="round"/>
<circle cx="550" cy="550" r="200" fill="none" stroke="#000000" stroke-width="40"/><line x1="700" y1="700" x2="850" y2="850" stroke="#000000" stroke-width="40" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Settings</title>
<circle cx="600" cy="600" r="150" fill="none" stroke="#FF1610" stroke-width="40"/><g stroke="#FF1610" stroke-width="35" stroke-linecap="round"><line x1="600" y1="350" x2="600" y2="420"/><line x1="600" y1="780" x2="600" y2="850"/><line x1="350" y1="600" x2="420" y2="600"/><line x1="780" y1="600" x2="850" y2="600"/><line x1="420" y1="420" x2="470" y2="470"/><line x1="730" y1="730" x2="780" y2="780"/><line x1="420" y1="780" x2="470" y2="730"/><line x1="730" y1="470" x2="780" y2="420"/></g>
<circle cx="600" cy="600" r="150" fill="none" stroke="#000000" stroke-width="40"/><g stroke="#000000" stroke-width="35" stroke-linecap="round"><line x1="600" y1="350" x2="600" y2="420"/><line x1="600" y1="780" x2="600" y2="850"/><line x1="350" y1="600" x2="420" y2="600"/><line x1="780" y1="600" x2="850" y2="600"/><line x1="420" y1="420" x2="470" y2="470"/><line x1="730" y1="730" x2="780" y2="780"/><line x1="420" y1="780" x2="470" y2="730"/><line x1="730" y1="470" x2="780" y2="420"/></g>
</svg>

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 618 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Team</title>
<circle cx="500" cy="500" r="70" fill="none" stroke="#FF1610" stroke-width="35"/><circle cx="700" cy="500" r="70" fill="none" stroke="#FF1610" stroke-width="35"/><path d="M 400 750 Q 400 650 500 650 Q 600 650 600 750" fill="none" stroke="#FF1610" stroke-width="35"/><path d="M 600 750 Q 600 650 700 650 Q 800 650 800 750" fill="none" stroke="#FF1610" stroke-width="35"/>
<circle cx="500" cy="500" r="70" fill="none" stroke="#000000" stroke-width="35"/><circle cx="700" cy="500" r="70" fill="none" stroke="#000000" stroke-width="35"/><path d="M 400 750 Q 400 650 500 650 Q 600 650 600 750" fill="none" stroke="#000000" stroke-width="35"/><path d="M 600 750 Q 600 650 700 650 Q 800 650 800 750" fill="none" stroke="#000000" stroke-width="35"/>
</svg>

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 493 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 1200 1200">
<title>Nav Video</title>
<rect x="260" y="400" width="680" height="400" rx="70" fill="none" stroke="#FF1610" stroke-width="70"/><path d="M 940 600 L 1120 480 L 1120 720 Z" fill="#FF1610"/><path d="M 360 470 L 360 730" stroke="#FF1610" stroke-width="40" stroke-linecap="round"/><path d="M 480 470 L 480 730" stroke="#FF1610" stroke-width="40" stroke-linecap="round"/>
<rect x="260" y="400" width="680" height="400" rx="70" fill="none" stroke="#000000" stroke-width="70"/><path d="M 940 600 L 1120 480 L 1120 720 Z" fill="#000000"/><path d="M 360 470 L 360 730" stroke="#000000" stroke-width="40" stroke-linecap="round"/><path d="M 480 470 L 480 730" stroke="#000000" stroke-width="40" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 466 B

Before After
Before After

View file

@ -3,8 +3,8 @@
<defs>
<g id="ca">
<g transform="rotate(-17.5 0 0)">
<circle cx="0" cy="0" r="45" fill="none" stroke="#FF1610" stroke-width="10"/>
<path d="M 0 -38 L -28 38 M 0 -38 L 28 38 M -34 0 L 34 0" fill="none" stroke="#FF1610" stroke-width="12" stroke-linecap="round"/>
<circle cx="0" cy="0" r="45" fill="none" stroke="#000000" stroke-width="10"/>
<path d="M 0 -38 L -28 38 M 0 -38 L 28 38 M -34 0 L 34 0" fill="none" stroke="#000000" stroke-width="12" stroke-linecap="round"/>
</g>
</g>
</defs>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -1,8 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 1700 1700">
<g transform="rotate(-17.5 850 850)">
<path d="M 850 500 A 350 350 0 0 1 1200 850" fill="none" stroke="#FF1610" stroke-width="70" stroke-linecap="round"/>
<path d="M 1200 850 A 350 350 0 0 1 850 1200" fill="none" stroke="#FF1610" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
<path d="M 850 1200 A 350 350 0 0 1 500 850" fill="none" stroke="#FF1610" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
<path d="M 500 850 A 350 350 0 0 1 850 500" fill="none" stroke="#FF1610" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
<path d="M 850 500 A 350 350 0 0 1 1200 850" fill="none" stroke="#000000" stroke-width="70" stroke-linecap="round"/>
<path d="M 1200 850 A 350 350 0 0 1 850 1200" fill="none" stroke="#000000" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
<path d="M 850 1200 A 350 350 0 0 1 500 850" fill="none" stroke="#000000" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
<path d="M 500 850 A 350 350 0 0 1 850 500" fill="none" stroke="#000000" stroke-width="70" stroke-linecap="round" opacity="0.2"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 667 B

Before After
Before After

View file

@ -1,40 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-labelledby="t">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" role="img" aria-labelledby="t">
<title id="t">T-HUB</title>
<circle cx="120" cy="120" r="118" fill="#000"/>
<circle cx="120" cy="120" r="82" fill="none" stroke="#fff" stroke-width="2" stroke-dasharray="3 7" opacity=".55"/>
<!-- cables: each leaves through a tent door and runs to the switch -->
<g fill="none" stroke="#00e5ff" stroke-width="4" stroke-linecap="round">
<path d="M49 94 C 52 122, 74 130, 96 130"/>
<path d="M191 94 C 188 122, 166 130, 144 130"/>
<path d="M120 216 C 120 196, 120 168, 120 140"/>
<defs>
<!-- Dome tent in the hand-inked style of the acampada26s.net mark:
curved poles with ball ends, centre seam, hatched panel, door.
Base midpoint at 0,0. -->
<g id="tienda" stroke-linecap="round" stroke-linejoin="round">
<path fill="none" d="M-58 0 Q-56 -66 -1 -72 Q55 -66 58 0" stroke-width="7"/>
<path fill="none" d="M-64 1 Q0 -3 64 1" stroke-width="6"/>
<path fill="none" d="M-44 0 Q-30 -58 -1 -72" stroke-width="4.5"/>
<path fill="none" d="M44 0 Q30 -58 -1 -72" stroke-width="4.5"/>
<path d="M-15 0 Q-14 -30 0 -33 Q14 -30 15 0 Z" stroke-width="4"/>
<path fill="none" d="M-50 -14 L-41 -25 M-50 -4 L-37 -19 M-43 -1 L-33 -13 M-52 -27 L-45 -36" stroke-width="2.6"/>
<path fill="none" d="M28 -50 L37 -42 M24 -40 L36 -30 M22 -29 L34 -19" stroke-width="2.6"/>
<circle cx="-64" cy="1" r="5.5" stroke="none"/>
<circle cx="64" cy="1" r="5.5" stroke="none"/>
<circle cx="-1" cy="-73" r="5.5" stroke="none"/>
</g>
<g id="marca" stroke-linecap="round" stroke-linejoin="round">
<!-- cables: out of each tent door to the switch -->
<path fill="none" d="M105 150 Q112 206 168 214" stroke-width="5"/>
<path fill="none" d="M295 150 Q288 206 232 214" stroke-width="5"/>
<path fill="none" d="M200 318 Q197 280 200 236" stroke-width="5"/>
<!-- antenna -->
<path fill="none" d="M200 200 Q198 160 200 118" stroke-width="6"/>
<path fill="none" d="M184 98 Q200 82 216 98" stroke-width="5"/>
<path fill="none" d="M171 88 Q200 58 229 88" stroke-width="5"/>
<circle cx="200" cy="112" r="7" stroke="none"/>
<!-- switch -->
<path d="M168 201 L233 200 L234 235 L167 236 Z" stroke-width="6" fill="#fff"/>
<path d="M179 212 h9 v11 h-9 z M196 212 h9 v11 h-9 z M213 212 h9 v11 h-9 z" stroke="none"/>
<use xlink:href="#tienda" transform="translate(105,150)"/>
<use xlink:href="#tienda" transform="translate(295,150)"/>
<use xlink:href="#tienda" transform="translate(200,340)"/>
</g>
</defs>
<!-- neon offset underneath, ink on top, as on acampada26s.net -->
<g transform="translate(7,7)" stroke="#00e5ff" fill="#00e5ff">
<use xlink:href="#marca"/>
</g>
<!-- tents -->
<g stroke="#fff" stroke-width="3" stroke-linejoin="round">
<polygon points="19,99 49,55 79,99" fill="#000"/>
<polygon points="161,99 191,55 221,99" fill="#000"/>
<polygon points="90,221 120,177 150,221" fill="#000"/>
</g>
<g fill="#00e5ff">
<polygon points="40,99 49,80 58,99"/>
<polygon points="182,99 191,80 200,99"/>
<polygon points="111,221 120,202 129,221"/>
</g>
<!-- antenna -->
<line x1="120" y1="120" x2="120" y2="70" stroke="#fff" stroke-width="4" stroke-linecap="round"/>
<circle cx="120" cy="68" r="5" fill="#00e5ff"/>
<g fill="none" stroke="#00e5ff" stroke-width="3" stroke-linecap="round">
<path d="M106 56 A 18 18 0 0 1 134 56"/>
<path d="M97 46 A 30 30 0 0 1 143 46"/>
</g>
<!-- switch -->
<rect x="94" y="118" width="52" height="24" rx="3" fill="#fff"/>
<g fill="#000">
<rect x="101" y="125" width="9" height="9"/>
<rect x="115.5" y="125" width="9" height="9"/>
<rect x="130" y="125" width="9" height="9"/>
<g stroke="#000" fill="#000">
<use xlink:href="#marca"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

View file

@ -49,7 +49,7 @@ function Shell({ children }: { children: ReactNode }): React.ReactElement {
scrollPositions.set(pathname, { main: main.scrollTop, nested: scrollableChildren(main).map((element) => element.scrollTop) });
};
}, [pathname, mobile]);
const title = titles[pathname.split("/")[1] ?? ""] ?? "Tactical Media Broadcast Hub";
const title = titles[pathname.split("/")[1] ?? ""] ?? "T-HUB";
return (
<div className="flex h-dvh min-w-0 overflow-hidden lg:h-screen">
<Sidebar />

View file

@ -48,7 +48,7 @@ export default function MorePage(): React.ReactElement {
<section className="flex items-center gap-4 px-5 py-5">
<div className="scale-125"><Avatar handle={session?.user.displayName || session?.user.username || "AP"} /></div>
<div className="min-w-0 flex-1 pl-2">
<h1 className="truncate text-xl font-bold">{session?.user.displayName || session?.user.username || "Tactical Media Broadcast Hub"}</h1>
<h1 className="truncate text-xl font-bold">{session?.user.displayName || session?.user.username || "T-HUB"}</h1>
<p className="truncate text-xs text-text-faint">@{session?.user.username || "offline"}{session?.user.email ? ` · ${session.user.email}` : ""}</p>
<div className="mt-2 flex items-center gap-2"><span className="rounded-full bg-accent px-2.5 py-1 text-[11px] font-bold uppercase text-white">{session?.role || "Preview"}</span><span className="truncate text-xs text-text-dim">{session?.workspace.name || "Studio"}</span></div>
</div>

View file

@ -221,15 +221,15 @@ export default function OnboardingPage(): React.ReactElement {
<div className="mb-5">
<div className="-m-6 mb-5 overflow-hidden bg-black">
<div className="flex items-center gap-5 px-8 py-8">
<LogoMark size={96} className="shrink-0 text-accent" />
<LogoMark size={96} className="shrink-0 text-white" />
<div className="min-w-0">
<div className="text-xl font-semibold leading-tight text-white">Horizontal Collaborative Broadcast System</div>
<div className="mt-1 text-xs uppercase tracking-wider text-text-faint">Tactical Media Broadcast Hub</div>
<div className="mt-1 text-xs uppercase tracking-wider text-[#00e5ff]">T-HUB</div>
</div>
</div>
</div>
<div className="text-center">
<h1 className="text-2xl font-semibold tracking-tight">Tactical Media Broadcast Hub</h1>
<h1 className="text-2xl font-semibold tracking-tight">T-HUB</h1>
<p className="mt-1 text-2xs text-text-faint">Your platform. Their feeds. No algorithm in between.</p>
</div>
</div>

View file

@ -8,23 +8,25 @@
}
@theme {
/* T-HUB: the acampada26s.net palette (black, white, neon) on a dark base. */
--color-bg: #000;
--color-surface: #0d0d0d;
--color-surface-2: #181818;
--color-border: #3d3d3d;
--color-border-subtle: #262626;
--color-text: #fff;
--color-text-dim: #b3b3b3;
--color-text-faint: #808080;
--color-accent: #00e5ff;
--color-accent-hover: #5cefff;
--color-accent-dim: rgb(0 229 255 / 0.15);
--color-live: oklch(0.72 0.19 145);
--color-warn: oklch(0.78 0.16 85);
--color-danger: oklch(0.55 0.24 15);
--color-added: oklch(0.72 0.16 145);
--color-removed: oklch(0.55 0.24 15);
/* T-HUB: the acampada26s.net palette. White page, black ink and borders,
neon #00e5ff for hover, focus and the offset shadows. */
--color-bg: #fff;
--color-surface: #fff;
--color-surface-2: #f2f2f2;
--color-border: #000;
--color-border-subtle: #d4d4d4;
--color-text: #000;
--color-text-dim: #333;
--color-text-faint: #666;
--color-accent: #000;
--color-accent-hover: #222;
--color-accent-dim: rgb(0 229 255 / 0.28);
--color-neon: #00e5ff;
--color-live: #007a3d;
--color-warn: #8a5a00;
--color-danger: #c4001a;
--color-added: #007a3d;
--color-removed: #c4001a;
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, monospace;
@ -51,7 +53,7 @@
}
html {
color-scheme: dark;
color-scheme: light;
}
body {
@ -72,13 +74,20 @@ h1, h2 {
letter-spacing: 0.01em;
}
h1 {
text-shadow: 0.04em 0.04em 0 var(--color-accent);
font-size: 1.75rem;
line-height: 1.05;
text-shadow: 0.01em 0.01em 0 var(--color-neon), 0.02em 0.02em 0 var(--color-neon), 0.03em 0.03em 0 var(--color-neon), 0.04em 0.04em 0 var(--color-neon);
}
/* Neon fills need dark text; unlayered so it outranks the text-white utility. */
.bg-accent.text-white,
.bg-accent .text-white {
color: #000;
/* Buttons as on acampada26s.net: hard offset shadow, neon on hover. */
button.bg-accent, a.bg-accent {
box-shadow: 0 3px 0 var(--color-neon);
}
button.bg-accent:hover, a.bg-accent:hover, button.bg-accent:focus-visible, a.bg-accent:focus-visible {
box-shadow: 0 5px 0 var(--color-neon);
}
:focus-visible {
outline-color: var(--color-neon);
}
@media (max-width: 1023px) {

View file

@ -324,11 +324,11 @@ export default function JoinWorkspacePage({ params }: { params: { token: string
<Card className="w-[520px] max-w-full p-6">
<div className="mb-5 text-center">
<img
src="/brand/hero.png"
alt="Tactical Media Broadcast Hub — arrows from a circle, warm red on black"
width={1024}
height={1024}
className="mx-auto mb-3 h-20 w-20 rounded-lg object-cover"
src="/brand/t-hub.svg"
alt="T-HUB: three tents wired to a switch with an antenna"
width={400}
height={400}
className="mx-auto mb-3 h-20 w-20"
/>
<h1 className="text-xl font-semibold tracking-tight">Join {info.workspaceName}</h1>
<p className="mt-1 text-2xs text-text-faint">

View file

@ -3,8 +3,8 @@ import type { Metadata, Viewport } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "Tactical Media Broadcast Hub",
description: "Tactical Media Broadcast Hub — post, schedule and amplify across every network you refuse to be owned by.",
title: "T-HUB",
description: "T-HUB — post, schedule and amplify across every network you refuse to be owned by. Based on Tactical Media Broadcast Hub.",
icons: { icon: "/brand/favicon.svg" },
};
@ -13,7 +13,7 @@ export const viewport: Viewport = {
initialScale: 1,
viewportFit: "cover",
interactiveWidget: "resizes-content",
themeColor: "#000000",
themeColor: "#ffffff",
};
export default function RootLayout({ children }: { children: ReactNode }): React.ReactNode {

View file

@ -40,7 +40,7 @@ export default function LoginPage(): React.ReactElement {
<Card className="w-[420px] max-w-full p-6">
<div className="mb-5 text-center">
<h1 className="text-xl font-semibold tracking-tight">Sign in</h1>
<p className="mt-1 text-2xs text-text-faint">Tactical Media Broadcast Hub</p>
<p className="mt-1 text-2xs text-text-faint">T-HUB</p>
</div>
<form onSubmit={(e) => void submit(e)}>
<div className="space-y-2">

View file

@ -116,7 +116,7 @@ function ManualLanding(): React.ReactElement {
<header className="sticky top-0 z-10 border-b border-border-subtle bg-surface">
<div className="mx-auto flex max-w-2xl items-center gap-3 px-4 py-4">
<Logo size={26} withText={false} />
<span className="flex-1 truncate text-xs font-bold tracking-tight text-accent">Tactical Media Broadcast Hub</span>
<span className="flex-1 truncate text-xs font-bold tracking-tight text-accent">T-HUB</span>
<div className="flex shrink-0 items-center rounded-md border border-border bg-surface-2 p-0.5" role="group" aria-label={t({ es: "Idioma", en: "Language" })}>
{(["es", "en"] as const).map((code) => (
<button

View file

@ -119,10 +119,10 @@ export default function SubmitPage({ params }: { params: { token: string } }): R
if (phase === "checking") {
return (
<main className="flex min-h-dvh items-center justify-center bg-[#060403] px-6">
<main className="flex min-h-dvh items-center justify-center bg-white px-6">
<div className="flex flex-col items-center gap-3">
<Loading size={32} label="Opening the box…" />
<span className="text-2xs text-[#a4a09e]">Opening the box…</span>
<span className="text-2xs text-[#555]">Opening the box…</span>
</div>
</main>
);
@ -130,7 +130,7 @@ export default function SubmitPage({ params }: { params: { token: string } }): R
if (phase === "unreachable") {
return (
<main className="flex min-h-dvh items-center justify-center bg-[#060403] p-6">
<main className="flex min-h-dvh items-center justify-center bg-white p-6">
<DeadCard
tone="warn"
title="Can't reach the server"
@ -143,7 +143,7 @@ export default function SubmitPage({ params }: { params: { token: string } }): R
if (phase === "gone" || box === null) {
return (
<main className="flex min-h-dvh items-center justify-center bg-[#060403] p-6">
<main className="flex min-h-dvh items-center justify-center bg-white p-6">
<DeadCard
tone="danger"
title="This box isn't open"
@ -154,7 +154,7 @@ export default function SubmitPage({ params }: { params: { token: string } }): R
}
return (
<main className="min-h-dvh bg-[#060403] px-4 py-10 sm:px-6">
<main className="min-h-dvh bg-white px-4 py-10 sm:px-6">
<SubmitForm key={token} token={token} box={box} />
</main>
);
@ -162,16 +162,16 @@ export default function SubmitPage({ params }: { params: { token: string } }): R
function DeadCard({ tone, title, body, action }: { tone: "warn" | "danger"; title: string; body: string; action?: React.ReactNode }): React.ReactElement {
return (
<div className="w-full max-w-md rounded-lg border border-[#2a2320] bg-[#0F0A09] p-6 text-center">
<div className="w-full max-w-md rounded-lg border border-[#d4d4d4] bg-[#f2f2f2] p-6 text-center">
<div
className={`mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full text-lg ${
tone === "warn" ? "bg-[#00E5FF]/15 text-[#00E5FF]" : "bg-[#00E5FF]/15 text-[#00E5FF]"
tone === "warn" ? "bg-[#00E5FF]/15 text-[#00798a]" : "bg-[#00E5FF]/15 text-[#00798a]"
}`}
>
{tone === "warn" ? "!" : "✕"}
</div>
<h1 className="text-base font-semibold text-[#f5efed]">{title}</h1>
<p className="mt-2 text-xs leading-relaxed text-[#a4a09e]">{body}</p>
<h1 className="text-base font-semibold text-black">{title}</h1>
<p className="mt-2 text-xs leading-relaxed text-[#555]">{body}</p>
{action}
</div>
);
@ -282,13 +282,13 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
if (phase === "sent" && done !== null) {
return (
<div className="mx-auto flex w-full max-w-xl flex-col items-center gap-4 rounded-lg border border-[#2a2320] bg-[#0F0A09] p-8 text-center">
<LogoMark size={44} className="text-[#00E5FF]" title="" />
<h1 className="text-xl font-semibold tracking-tight text-[#f5efed]">Received</h1>
<p className="max-w-sm text-sm leading-relaxed text-[#c7c3c1]">
<div className="mx-auto flex w-full max-w-xl flex-col items-center gap-4 rounded-lg border border-[#d4d4d4] bg-[#f2f2f2] p-8 text-center">
<LogoMark size={44} className="text-black" title="" />
<h1 className="text-xl font-semibold tracking-tight text-black">Received</h1>
<p className="max-w-sm text-sm leading-relaxed text-[#333]">
Received — the collective will review it. Nothing is published until they approve it.
</p>
<p className="max-w-sm text-2xs leading-relaxed text-[#a4a09e]">
<p className="max-w-sm text-2xs leading-relaxed text-[#555]">
Your footage stays under {box.licenseDefault}: it may be shared and remixed with attribution.
</p>
</div>
@ -301,13 +301,13 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
return (
<form
onSubmit={(event) => void submit(event)}
className="mx-auto flex w-full max-w-xl flex-col gap-6 rounded-lg border border-[#2a2320] bg-[#0F0A09] p-6 sm:p-8"
className="mx-auto flex w-full max-w-xl flex-col gap-6 rounded-lg border border-[#d4d4d4] bg-[#f2f2f2] p-6 sm:p-8"
>
<header className="flex flex-col items-center gap-3 text-center">
<LogoMark size={36} className="text-[#00E5FF]" title="Tactical Media Broadcast Hub" />
<LogoMark size={36} className="text-black" />
<div>
<h1 className="text-xl font-semibold tracking-tight text-[#f5efed]">Send footage to the collective</h1>
<p className="mt-1 text-xs leading-relaxed text-[#a4a09e]">
<h1 className="text-xl font-semibold tracking-tight text-black">Send footage to the collective</h1>
<p className="mt-1 text-xs leading-relaxed text-[#555]">
No account needed. mp4 or webm video up to 200 MiB, jpeg or png photo up to 50 MiB.
</p>
</div>
@ -339,13 +339,13 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
}}
className={`flex min-h-[180px] flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed px-4 py-8 text-center transition-colors duration-150 ${
uploading
? "cursor-not-allowed border-[#3a312e] opacity-60"
: "cursor-pointer border-[#3a312e] hover:border-[#00E5FF] focus-visible:border-[#00E5FF]"
? "cursor-not-allowed border-black opacity-60"
: "cursor-pointer border-black hover:border-[#00E5FF] focus-visible:border-[#00E5FF]"
}`}
>
{uploading ? (
<div className="w-full max-w-md space-y-2">
<span className="inline-flex items-center gap-2 text-xs text-[#c7c3c1]">
<span className="inline-flex items-center gap-2 text-xs text-[#333]">
<Loading size={14} label="Uploading" />
{progress < 100 ? `Uploading ${progress}%` : "Upload sent — the collective's server is taking it in…"}{" "}
{file !== null && `${file.name} (${formatBytes(file.size)})`}
@ -354,15 +354,15 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
</div>
) : file !== null && kind !== null ? (
<>
<span className="text-sm font-medium text-[#f5efed]">{file.name}</span>
<span className="text-2xs text-[#a4a09e]">
<span className="text-sm font-medium text-black">{file.name}</span>
<span className="text-2xs text-[#555]">
{kind === "video" ? "video" : "photo"} · {formatBytes(file.size)} · click or drop to choose another
</span>
</>
) : (
<>
<span className="text-sm text-[#c7c3c1]">Drop your video or photo here</span>
<span className="text-2xs leading-relaxed text-[#a4a09e]">
<span className="text-sm text-[#333]">Drop your video or photo here</span>
<span className="text-2xs leading-relaxed text-[#555]">
or browse your device, or paste a file. Nothing is sent until you press Send.
</span>
<span className="mt-2 rounded-md bg-[#00E5FF] px-3 py-1.5 text-xs font-medium text-black">Browse files</span>
@ -381,11 +381,11 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
/>
</div>
{fileError !== null && <p role="alert" className="text-xs text-[#ff6f6b]">{fileError}</p>}
{error !== null && <p role="alert" className="rounded-md border border-[#00E5FF]/30 bg-[#00E5FF]/10 px-3 py-2 text-xs text-[#ff9b97]">{error}</p>}
{fileError !== null && <p role="alert" className="text-xs text-[#c4001a]">{fileError}</p>}
{error !== null && <p role="alert" className="rounded-md border border-[#00E5FF]/30 bg-[#00E5FF]/10 px-3 py-2 text-xs text-[#c4001a]">{error}</p>}
<div className="space-y-4">
<label className="flex cursor-pointer items-start gap-2.5 rounded-lg border border-[#3a312e] bg-[#060403] p-3">
<label className="flex cursor-pointer items-start gap-2.5 rounded-lg border border-black bg-white p-3">
<input
type="checkbox"
checked={licence}
@ -393,12 +393,12 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
disabled={uploading}
className="mt-0.5 h-4 w-4 shrink-0 accent-[#00E5FF]"
/>
<span className="text-xs leading-relaxed text-[#c7c3c1]">
{SUBMISSION_LICENSE_TEXT} <span className="text-[#00E5FF]">(required)</span>
<span className="text-xs leading-relaxed text-[#333]">
{SUBMISSION_LICENSE_TEXT} <span className="text-[#00798a]">(required)</span>
</span>
</label>
<label className="block text-2xs text-[#a4a09e]">
<label className="block text-2xs text-[#555]">
Credit name (optional, max {SUBMISSION_CREDIT_MAX})
<input
type="text"
@ -407,12 +407,12 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
onChange={(event) => setCreditName(event.target.value)}
disabled={uploading}
placeholder="How your name should appear in the credit"
className="mt-1 w-full rounded-md border border-[#3a312e] bg-[#060403] px-3 py-2 text-sm text-[#f5efed] placeholder:text-[#6b6563] focus:border-[#00E5FF] focus:outline-none"
className="mt-1 w-full rounded-md border border-black bg-white px-3 py-2 text-sm text-black placeholder:text-[#888] focus:border-[#00E5FF] focus:outline-none"
/>
{creditTooLong && <span className="mt-1 block text-[#ff6f6b]">Up to {SUBMISSION_CREDIT_MAX} characters.</span>}
{creditTooLong && <span className="mt-1 block text-[#c4001a]">Up to {SUBMISSION_CREDIT_MAX} characters.</span>}
</label>
<label className="block text-2xs text-[#a4a09e]">
<label className="block text-2xs text-[#555]">
Contact (optional, max {SUBMISSION_CONTACT_MAX})
<textarea
value={contact}
@ -421,9 +421,9 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
disabled={uploading}
rows={2}
placeholder="How licensors can reach you — shown only to admins"
className="mt-1 w-full resize-none rounded-md border border-[#3a312e] bg-[#060403] px-3 py-2 text-sm text-[#f5efed] placeholder:text-[#6b6563] focus:border-[#00E5FF] focus:outline-none"
className="mt-1 w-full resize-none rounded-md border border-black bg-white px-3 py-2 text-sm text-black placeholder:text-[#888] focus:border-[#00E5FF] focus:outline-none"
/>
{contactTooLong && <span className="mt-1 block text-[#ff6f6b]">Up to {SUBMISSION_CONTACT_MAX} characters.</span>}
{contactTooLong && <span className="mt-1 block text-[#c4001a]">Up to {SUBMISSION_CONTACT_MAX} characters.</span>}
</label>
</div>
@ -434,7 +434,7 @@ function SubmitForm({ token, box }: { token: string; box: SubmissionBoxInfo }):
>
{uploading ? `Sending… ${progress}%` : "Send to the collective"}
</button>
<p className="text-center text-2xs leading-relaxed text-[#a4a09e]">
<p className="text-center text-2xs leading-relaxed text-[#555]">
The collective reviews every submission before anything is used. Your contact details stay with their admins.
</p>
</form>

View file

@ -1,51 +1,62 @@
import type { ReactElement } from "react";
/**
* The Tactical Media Broadcast Hub mark, inline.
*
* Source of truth: `public/brand/tactical-media-broadcast-hub.svg` — the arrows-from-circle
* mark, tilted −17.5° counterclockwise so the top arrow points upper-left
* (nothing static; everything points outward). The strokes use `currentColor`
* so the mark always rides the workspace accent, which in the warm palette
* lands within a hair of the brand red (#FF1610 ≈ oklch(0.63 0.24 29) vs the
* token's oklch(0.62 0.22 30)). Geometry is copied 1:1 from the asset on its
* 1700×1700 grid, minus the black plate and the screen-print distress paths
* (those only read on pure black at full size).
* The T-HUB mark, inline: three dome tents in a circle, each with a cable
* out of its door into a switch with an antenna. Drawn in the hand-inked
* style of the acampada26s.net mark, ink in `currentColor` over a neon
* offset copy. Source: docs/brand/t-hub.svg (same 400×400 geometry).
*/
const TENTS: ReadonlyArray<readonly [number, number]> = [[105, 150], [295, 150], [200, 340]];
function Tent({ x, y }: { x: number; y: number }): ReactElement {
return (
<g transform={`translate(${x},${y})`}>
<path fill="none" d="M-58 0 Q-56 -66 -1 -72 Q55 -66 58 0" strokeWidth="7" />
<path fill="none" d="M-64 1 Q0 -3 64 1" strokeWidth="6" />
<path fill="none" d="M-44 0 Q-30 -58 -1 -72" strokeWidth="4.5" />
<path fill="none" d="M44 0 Q30 -58 -1 -72" strokeWidth="4.5" />
<path d="M-15 0 Q-14 -30 0 -33 Q14 -30 15 0 Z" strokeWidth="4" />
<path fill="none" d="M-50 -14 L-41 -25 M-50 -4 L-37 -19 M-43 -1 L-33 -13 M-52 -27 L-45 -36" strokeWidth="2.6" />
<path fill="none" d="M28 -50 L37 -42 M24 -40 L36 -30 M22 -29 L34 -19" strokeWidth="2.6" />
<circle cx="-64" cy="1" r="5.5" stroke="none" />
<circle cx="64" cy="1" r="5.5" stroke="none" />
<circle cx="-1" cy="-73" r="5.5" stroke="none" />
</g>
);
}
function Mark({ paper }: { paper: string }): ReactElement {
return (
<>
<path fill="none" d="M105 150 Q112 206 168 214" strokeWidth="5" />
<path fill="none" d="M295 150 Q288 206 232 214" strokeWidth="5" />
<path fill="none" d="M200 318 Q197 280 200 236" strokeWidth="5" />
<path fill="none" d="M200 200 Q198 160 200 118" strokeWidth="6" />
<path fill="none" d="M184 98 Q200 82 216 98" strokeWidth="5" />
<path fill="none" d="M171 88 Q200 58 229 88" strokeWidth="5" />
<circle cx="200" cy="112" r="7" stroke="none" />
<path d="M168 201 L233 200 L234 235 L167 236 Z" strokeWidth="6" fill={paper} />
<path d="M179 212 h9 v11 h-9 z M196 212 h9 v11 h-9 z M213 212 h9 v11 h-9 z" stroke="none" />
{TENTS.map(([x, y]) => <Tent key={`${x}-${y}`} x={x} y={y} />)}
</>
);
}
export function LogoMark({
size = 32,
className = "text-accent",
title = "Tactical Media Broadcast Hub",
className = "text-text",
title = "T-HUB",
}: {
size?: number;
className?: string;
title?: string;
}): ReactElement {
return (
<svg
width={size}
height={size}
viewBox="0 0 1700 1700"
role="img"
aria-label={title}
className={className}
>
<g transform="rotate(-17.5 850 850)">
<g fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round">
<circle cx="850" cy="850" r="350" strokeWidth="74" />
<path d="M 850 405 L 464.77 1269.52" strokeWidth="88" />
<path d="M 850 405 L 1235.23 1269.52" strokeWidth="88" />
<path d="M 850 405 L 850 350" strokeWidth="88" />
<path d="M 345 850 L 1355 850" strokeWidth="88" />
</g>
<g fill="currentColor">
<polygon points="850,240 925,385 775,385" />
<polygon points="235,850 380,775 380,925" />
<polygon points="1465,850 1320,925 1320,775" />
<polygon points="420,1370 410.51,1207.03 547.52,1268.08" />
<polygon points="1280,1370 1152.48,1268.08 1289.49,1207.03" />
</g>
<svg width={size} height={size} viewBox="0 0 400 400" role="img" aria-label={title} className={className}>
<g strokeLinecap="round" strokeLinejoin="round">
<g transform="translate(7,7)" stroke="#00e5ff" fill="#00e5ff"><Mark paper="#fff" /></g>
<g stroke="currentColor" fill="currentColor"><Mark paper="#fff" /></g>
</g>
</svg>
);
@ -112,10 +123,14 @@ export function Logo({ size = 32, withText = true }: { size?: number; withText?:
<span className={`inline-flex ${stacked ? "flex-col items-center gap-3" : "items-center gap-2.5"}`}>
<LogoMark size={size} />
<span
className={`font-semibold tracking-tight text-text ${stacked ? "text-2xl" : ""}`}
style={stacked ? undefined : { fontSize: `${Math.max(13, Math.round(size * 0.45))}px` }}
className={`uppercase tracking-wide text-text ${stacked ? "text-4xl" : ""}`}
style={{
fontFamily: "var(--font-title)",
textShadow: "0.04em 0.04em 0 var(--color-neon)",
...(stacked ? {} : { fontSize: `${Math.max(16, Math.round(size * 0.6))}px` }),
}}
>
Tactical Media Broadcast Hub
T-HUB
</span>
</span>
);

View file

@ -46,7 +46,7 @@ export function CommandPalette(): React.ReactElement {
onClick={(e: React.MouseEvent) => e.stopPropagation()}
>
<div className="flex items-center gap-2.5 border-b border-border-subtle px-4">
<LogoMark size={16} title="Tactical Media Broadcast Hub" />
<LogoMark size={16} />
<Command.Input
autoFocus
placeholder="Type a command or search…"

View file

@ -55,7 +55,7 @@ export function Sidebar(): React.ReactElement {
className="mt-0.5 h-[30px] w-[30px] shrink-0 rounded object-contain"
/>
) : (
<LogoMark size={30} title="Tactical Media Broadcast Hub" />
<LogoMark size={30} />
)}
<div className="min-w-0 flex-1">
<div className="text-xs font-semibold leading-tight tracking-tight" title={workspaceName}>
@ -67,7 +67,7 @@ export function Sidebar(): React.ReactElement {
</div>
) : (
<div className="truncate text-2xs text-text-faint" title={workspaceName}>
Tactical Media Broadcast Hub
T-HUB
</div>
)}
</div>

View file

@ -139,15 +139,21 @@ Verificación
4. ESTILO Y LOGO
----------------
- apps/web/src/app/globals.css: paleta de acampada26s.net sobre fondo
oscuro (negro, blanco, neón #00e5ff), títulos h1/h2 en Anton en
mayúsculas. Regla que pone texto negro en botones neón.
- apps/web/src/app/globals.css: paleta de acampada26s.net. Fondo
blanco, texto y bordes negros, botones negros con sombra neón
desplazada, foco y elemento activo en neón #00e5ff. Títulos h1/h2 en
Anton en mayúsculas con la sombra neón escalonada de la web.
- Iconos de navegación en negro; iconos de redes con trazo neón.
- Logo: tres tiendas iglú cableadas a un switch con antena, en el
estilo a tinta del logo de la acampada (docs/brand/t-hub.svg;
t-hub-lockup.svg/png con el nombre en Anton convertido a trazos).
Componente LogoMark sustituido; nombre visible "T-HUB".
- Fuente Anton en apps/web/public/fonts (licencia SIL OFL incluida).
- Logo: docs/brand/t-hub.svg, también como favicon.
- Página pública de buzón (/submit/[token]) con el mismo color.
Comprobar visualmente: login, Compose, Approvals, Channels, Outreach,
Control Room y /submit/<token>, en escritorio y móvil. Buscar textos
blancos sobre neón o bloques que hayan quedado con el rojo anterior.
- Página pública de buzón (/submit/[token]) en claro.
Revisado con capturas (Chromium sin interfaz, modo offline con datos de
ejemplo): Streams, Compose, Outreach, Channels, Approvals, Onboarding,
/submit en escritorio y móvil. Falta revisar Control Room y Calendar con
datos reales.
5. SEGURIDAD

BIN
docs/brand/t-hub-lockup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -1,40 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-labelledby="t">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" role="img" aria-labelledby="t">
<title id="t">T-HUB</title>
<circle cx="120" cy="120" r="118" fill="#000"/>
<circle cx="120" cy="120" r="82" fill="none" stroke="#fff" stroke-width="2" stroke-dasharray="3 7" opacity=".55"/>
<!-- cables: each leaves through a tent door and runs to the switch -->
<g fill="none" stroke="#00e5ff" stroke-width="4" stroke-linecap="round">
<path d="M49 94 C 52 122, 74 130, 96 130"/>
<path d="M191 94 C 188 122, 166 130, 144 130"/>
<path d="M120 216 C 120 196, 120 168, 120 140"/>
<defs>
<!-- Dome tent in the hand-inked style of the acampada26s.net mark:
curved poles with ball ends, centre seam, hatched panel, door.
Base midpoint at 0,0. -->
<g id="tienda" stroke-linecap="round" stroke-linejoin="round">
<path fill="none" d="M-58 0 Q-56 -66 -1 -72 Q55 -66 58 0" stroke-width="7"/>
<path fill="none" d="M-64 1 Q0 -3 64 1" stroke-width="6"/>
<path fill="none" d="M-44 0 Q-30 -58 -1 -72" stroke-width="4.5"/>
<path fill="none" d="M44 0 Q30 -58 -1 -72" stroke-width="4.5"/>
<path d="M-15 0 Q-14 -30 0 -33 Q14 -30 15 0 Z" stroke-width="4"/>
<path fill="none" d="M-50 -14 L-41 -25 M-50 -4 L-37 -19 M-43 -1 L-33 -13 M-52 -27 L-45 -36" stroke-width="2.6"/>
<path fill="none" d="M28 -50 L37 -42 M24 -40 L36 -30 M22 -29 L34 -19" stroke-width="2.6"/>
<circle cx="-64" cy="1" r="5.5" stroke="none"/>
<circle cx="64" cy="1" r="5.5" stroke="none"/>
<circle cx="-1" cy="-73" r="5.5" stroke="none"/>
</g>
<g id="marca" stroke-linecap="round" stroke-linejoin="round">
<!-- cables: out of each tent door to the switch -->
<path fill="none" d="M105 150 Q112 206 168 214" stroke-width="5"/>
<path fill="none" d="M295 150 Q288 206 232 214" stroke-width="5"/>
<path fill="none" d="M200 318 Q197 280 200 236" stroke-width="5"/>
<!-- antenna -->
<path fill="none" d="M200 200 Q198 160 200 118" stroke-width="6"/>
<path fill="none" d="M184 98 Q200 82 216 98" stroke-width="5"/>
<path fill="none" d="M171 88 Q200 58 229 88" stroke-width="5"/>
<circle cx="200" cy="112" r="7" stroke="none"/>
<!-- switch -->
<path d="M168 201 L233 200 L234 235 L167 236 Z" stroke-width="6" fill="#fff"/>
<path d="M179 212 h9 v11 h-9 z M196 212 h9 v11 h-9 z M213 212 h9 v11 h-9 z" stroke="none"/>
<use xlink:href="#tienda" transform="translate(105,150)"/>
<use xlink:href="#tienda" transform="translate(295,150)"/>
<use xlink:href="#tienda" transform="translate(200,340)"/>
</g>
</defs>
<!-- neon offset underneath, ink on top, as on acampada26s.net -->
<g transform="translate(7,7)" stroke="#00e5ff" fill="#00e5ff">
<use xlink:href="#marca"/>
</g>
<!-- tents -->
<g stroke="#fff" stroke-width="3" stroke-linejoin="round">
<polygon points="19,99 49,55 79,99" fill="#000"/>
<polygon points="161,99 191,55 221,99" fill="#000"/>
<polygon points="90,221 120,177 150,221" fill="#000"/>
</g>
<g fill="#00e5ff">
<polygon points="40,99 49,80 58,99"/>
<polygon points="182,99 191,80 200,99"/>
<polygon points="111,221 120,202 129,221"/>
</g>
<!-- antenna -->
<line x1="120" y1="120" x2="120" y2="70" stroke="#fff" stroke-width="4" stroke-linecap="round"/>
<circle cx="120" cy="68" r="5" fill="#00e5ff"/>
<g fill="none" stroke="#00e5ff" stroke-width="3" stroke-linecap="round">
<path d="M106 56 A 18 18 0 0 1 134 56"/>
<path d="M97 46 A 30 30 0 0 1 143 46"/>
</g>
<!-- switch -->
<rect x="94" y="118" width="52" height="24" rx="3" fill="#fff"/>
<g fill="#000">
<rect x="101" y="125" width="9" height="9"/>
<rect x="115.5" y="125" width="9" height="9"/>
<rect x="130" y="125" width="9" height="9"/>
<g stroke="#000" fill="#000">
<use xlink:href="#marca"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After