From 59355909f2de9236af8168a26c70bcf6caa3b285 Mon Sep 17 00:00:00 2001 From: Elvis Claros Castro Date: Sat, 26 Sep 2026 20:21:47 -0300 Subject: Import video pipeline as it was --- brand/README.md | 50 ++++++++++ brand/avatar-1024.png | Bin 0 -> 88757 bytes brand/avatar-plano-1024.png | Bin 0 -> 87007 bytes brand/avatar-plano.svg | 5 + brand/avatar.svg | 3 + brand/banner-1920.png | Bin 0 -> 58751 bytes brand/banner.svg | 4 + brand/make_logo.py | 235 ++++++++++++++++++++++++++++++++++++++++++++ brand/wordmark-2400.png | Bin 0 -> 57299 bytes brand/wordmark-claro.svg | 3 + brand/wordmark-mono.svg | 3 + brand/wordmark-plano.svg | 5 + brand/wordmark.svg | 3 + 13 files changed, 311 insertions(+) create mode 100644 brand/README.md create mode 100644 brand/avatar-1024.png create mode 100644 brand/avatar-plano-1024.png create mode 100644 brand/avatar-plano.svg create mode 100644 brand/avatar.svg create mode 100644 brand/banner-1920.png create mode 100644 brand/banner.svg create mode 100644 brand/make_logo.py create mode 100644 brand/wordmark-2400.png create mode 100644 brand/wordmark-claro.svg create mode 100644 brand/wordmark-mono.svg create mode 100644 brand/wordmark-plano.svg create mode 100644 brand/wordmark.svg (limited to 'brand') diff --git a/brand/README.md b/brand/README.md new file mode 100644 index 0000000..498efca --- /dev/null +++ b/brand/README.md @@ -0,0 +1,50 @@ +# Marca 100cIA + +El nombre se lee **"ciencia"** (100 = cien, + c + IA) y a la vez deja a la vista +que los videos los hace una IA. El logo apoya las dos lecturas: `100c` en blanco y el `IA` dentro de un chip ámbar +—el mismo recurso que usan los videos—, con un pelín de aire entre medio para que la I +no se lea como barra. + +## Archivos + +| Archivo | Para qué | +|---|---| +| `avatar.svg` / `avatar-1024.png` | **foto de perfil** | +| `avatar-plano.svg` / `avatar-plano-1024.png` | alternativa sin chip | +| `wordmark.svg` / `wordmark-2400.png` | logotipo sobre fondo oscuro | +| `wordmark-claro.svg` | logotipo sobre fondo claro | +| `wordmark-mono.svg` | una sola tinta con el `IA` calado — marca de agua sobre video | +| `wordmark-plano.svg` | logotipo sin chip | +| `banner.svg` / `banner-1920.png` | placa de cierre del video y miniatura | + +El chip alrededor del `IA` es la marca y va en todas las piezas. La versión mono +usa una máscara: el chip es de un solo color y las letras quedan caladas, así que +funciona encima de cualquier fondo. + +**TikTok e Instagram no aceptan SVG para la foto de perfil**: subí los `.png`. +Los `.svg` son para imprimir, escalar o editar. + +## Paleta (la misma de los videos) + +| | | +|---|---| +| fondo | `#0B0F1A` | +| puntitos | `#243050` | +| texto | `#FFFFFF` | +| ámbar (IA, barra de progreso) | `#FFD166` | +| ámbar oscuro (sobre fondo claro) | `#D98C00` | +| track de la barra | `#1B2233` | +| verde | `#06D6A0` · rosa `#EF476F` · celeste `#4CC9F0` | + +Tipografía: **Roboto Black**, tracking −3,5 %. En los SVG el texto ya está +convertido a curvas, así que se ven igual en cualquier máquina. + +El anillo del avatar es la barra de progreso de los videos, curvada: mismo ámbar, +misma proporción (62 %). Es lo que hace reconocible la miniatura a 44 px, donde +el texto ya no se lee. + +## Regenerar + +```bash +python3 brand/make_logo.py # necesita Inkscape y Roboto Black instalados +``` diff --git a/brand/avatar-1024.png b/brand/avatar-1024.png new file mode 100644 index 0000000..997cae4 Binary files /dev/null and b/brand/avatar-1024.png differ diff --git a/brand/avatar-plano-1024.png b/brand/avatar-plano-1024.png new file mode 100644 index 0000000..b68b861 Binary files /dev/null and b/brand/avatar-plano-1024.png differ diff --git a/brand/avatar-plano.svg b/brand/avatar-plano.svg new file mode 100644 index 0000000..e8c778b --- /dev/null +++ b/brand/avatar-plano.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/brand/avatar.svg b/brand/avatar.svg new file mode 100644 index 0000000..0b5783a --- /dev/null +++ b/brand/avatar.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/brand/banner-1920.png b/brand/banner-1920.png new file mode 100644 index 0000000..cc270b0 Binary files /dev/null and b/brand/banner-1920.png differ diff --git a/brand/banner.svg b/brand/banner.svg new file mode 100644 index 0000000..06c35ae --- /dev/null +++ b/brand/banner.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/brand/make_logo.py b/brand/make_logo.py new file mode 100644 index 0000000..dac08b5 --- /dev/null +++ b/brand/make_logo.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- +"""Genera el kit de marca de 100cIA. El texto se convierte a curvas con Inkscape, +asi que los SVG no dependen de que la fuente este instalada.""" +import os, re, subprocess, tempfile +import xml.etree.ElementTree as ET + +HERE = os.path.dirname(os.path.abspath(__file__)) + +BG = "#0B0F1A" +PUNTOS = "#243050" +BLANCO = "#FFFFFF" +AMBAR = "#FFD166" +TRACK = "#1B2233" +GRIS = "#8D99AE" + +FUENTE = "Roboto Black" +TRACKING = -0.035 # em + + +def curvas(partes, size=400, tracking=TRACKING): + """partes = [(texto, color), ...] -> (svg_interno, x, y, w, h) ya en curvas.""" + tspans = "".join( + f'{t}' + for i, (t, c) in enumerate(partes)) + src = (f'{tspans}') + with tempfile.TemporaryDirectory() as d: + a, b = os.path.join(d, "a.svg"), os.path.join(d, "b.svg") + open(a, "w", encoding="utf-8").write(src) + subprocess.run(["inkscape", "--export-text-to-path", "--export-plain-svg", + f"--export-filename={b}", a], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + raw = open(b, encoding="utf-8").read() + q = {k: float(subprocess.run(["inkscape", "--query-id=w", f"--query-{k}", b], + capture_output=True, text=True).stdout.strip()) + for k in ("x", "y", "width", "height")} + + NS = "http://www.w3.org/2000/svg" + ET.register_namespace("", NS) + root = ET.fromstring(raw) + nodo = next(e for e in root.iter() if e.get("id") == "w") + for e in nodo.iter(): + e.attrib.pop("id", None) + e.attrib.pop("aria-label", None) + cuerpo = ET.tostring(nodo, encoding="unicode") + cuerpo = cuerpo.replace(f' xmlns="{NS}"', "") + if not cuerpo.lstrip().startswith("{cuerpo}" + return cuerpo, q["x"], q["y"], q["width"], q["height"] + + +def colocar(g, bx, by, bw, bh, cx, cy, ancho): + s = ancho / bw + tx = cx - s * (bx + bw / 2) + ty = cy - s * (by + bh / 2) + return f'{g}' + + +def puntos(id_, sep=118, r=4.2, color=PUNTOS, op=0.55): + return (f'' + f'') + + +def arco(cx, cy, r, desde, hasta, color, w): + """Arco en grados, 0 = arriba, sentido horario.""" + import math + def p(a): + t = math.radians(a - 90) + return cx + r * math.cos(t), cy + r * math.sin(t) + x0, y0 = p(desde) + x1, y1 = p(hasta) + largo = 1 if (hasta - desde) % 360 > 180 else 0 + return (f'') + + +# ---------------------------------------------------------------- avatar +def avatar(archivo, chip=False, pct=0.62): + D = 1024 + R = D / 2 + anillo_r, anillo_w = R - 26, 20 + if chip: + g1, x1, y1, w1, h1 = curvas([("100c", BLANCO)]) + g2, x2, y2, w2, h2 = curvas([("IA", "#0B0F1A")]) + else: + g1, x1, y1, w1, h1 = curvas([("100c", BLANCO), ("IA", AMBAR)]) + + cuerpo = [ + f'', + f'', + f'', + arco(R, R, anillo_r, 0, 360 * pct, AMBAR, anillo_w), + ] + if chip: + ancho_total = 760 + # el chip de "IA" ocupa ~38% del ancho, como los chips de los videos + w_txt = ancho_total * 0.60 + cuerpo.append(colocar(g1, x1, y1, w1, h1, R - ancho_total / 2 + w_txt / 2, R, w_txt)) + esc = w_txt / w1 + cw, ch = w2 * esc * 1.0 + 70, h1 * esc + 62 + cxc = R - ancho_total / 2 + w_txt + 26 + cw / 2 + cuerpo.append(f'') + cuerpo.append(colocar(g2, x2, y2, w2, h2, cxc, R, w2 * esc)) + else: + cuerpo.append(colocar(g1, x1, y1, w1, h1, R, R, 740)) + + svg = (f'{puntos("dots")}' + + "".join(cuerpo) + '') + open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg) + return archivo + + +# ---------------------------------------------------------------- logotipo +# El chip alrededor del "IA" es la marca: va en todas las variantes menos en la +# "plana", que queda como alternativa. +MODOS = { + # tinta fondo del chip letra del chip + "oscuro": (BLANCO, AMBAR, "#0B0F1A"), + "claro": ("#0B0F1A", "#D98C00", "#FFFFFF"), + "mono": (BLANCO, BLANCO, None), # letras caladas +} + + +def _lockup(modo, alto=520): + """Devuelve (piezas_svg, ancho, alto) del lockup '100c' + chip 'IA'.""" + tinta, fondo_chip, letra = MODOS[modo] + g1, x1, y1, w1, h1 = curvas([("100c", tinta)]) + g2, x2, y2, w2, h2 = curvas([("IA", letra or "#000000")]) + + esc = alto / h1 + wt = w1 * esc + cw = w2 * esc + 0.68 * alto + ch = alto + 0.60 * alto + hueco = 0.13 * alto + W = wt + hueco + cw + cy = ch / 2 + rx = ch * 0.28 + cx_chip = wt + hueco + cw / 2 + chip_x = wt + hueco + + piezas = [colocar(g1, x1, y1, w1, h1, wt / 2, cy, wt)] + if letra is None: # una sola tinta: el IA se cala + mascara = (f'' + f'' + + colocar(g2, x2, y2, w2, h2, cx_chip, cy, w2 * esc) + + '') + piezas.append(f'{mascara}') + piezas.append(f'') + else: + piezas.append(f'') + piezas.append(colocar(g2, x2, y2, w2, h2, cx_chip, cy, w2 * esc)) + return piezas, W, ch + + +def wordmark(archivo, modo="oscuro", margen=0.10): + piezas, W0, H0 = _lockup(modo) + m = margen * H0 + W, H = int(round(W0 + 2 * m)), int(round(H0 + 2 * m)) + svg = (f'' + + "".join(piezas) + '') + open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg) + return archivo + + +def wordmark_plano(archivo): + """Alternativa sin chip: '100cIA' de corrido, el IA en ambar.""" + g, x, y, w, h = curvas([("100c", BLANCO), ("IA", AMBAR)]) + W = 2400 + ancho = W * 0.88 + H = int(round(h / w * ancho + 2 * 0.06 * W)) + svg = (f'' + + colocar(g, x, y, w, h, W / 2, H / 2, ancho) + '') + open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg) + return archivo + + +# ---------------------------------------------------------------- banner +def banner(archivo, tagline="ciencia en 40 segundos"): + W, H = 1920, 1080 + g, x, y, w, h = curvas([("100c", BLANCO)]) + t, tx, ty, tw, th = curvas([(tagline, "#C9D3E5")], size=200, tracking=0.012) + cuerpo = [ + f'', + f'', + f'', + f'', + None, # el lockup se arma abajo (con chip, igual que el avatar) + colocar(t, tx, ty, tw, th, W / 2, H / 2 + 205, 830), + ] + # lockup con chip, centrado, a 1150 px de ancho total + g2, x2, y2, w2, h2 = curvas([("IA", "#0B0F1A")]) + ANCHO, cy = 1150, H / 2 - 95 + alto = 210 + esc = alto / h + wt = w * esc + cw, ch = w2 * esc + 0.68 * alto, alto + 0.60 * alto + hueco = 0.13 * alto + total = wt + hueco + cw + k = ANCHO / total + wt, cw, ch, hueco = wt * k, cw * k, ch * k, hueco * k + izq = W / 2 - ANCHO / 2 + cuerpo[cuerpo.index(None)] = ( + colocar(g, x, y, w, h, izq + wt / 2, cy, wt) + + f'' + + colocar(g2, x2, y2, w2, h2, izq + wt + hueco + cw / 2, cy, w2 * esc * k)) + + svg = (f'{puntos("dots", sep=140, r=5)}' + + "".join(cuerpo) + '') + open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg) + return archivo + + +if __name__ == "__main__": + # la variante con chip es la marca: se queda con los nombres principales + for f in (avatar("avatar.svg", chip=True), avatar("avatar-plano.svg"), + wordmark("wordmark.svg", "oscuro"), + wordmark("wordmark-claro.svg", "claro"), + wordmark("wordmark-mono.svg", "mono"), + wordmark_plano("wordmark-plano.svg"), + banner("banner.svg")): + print(" ->", f) diff --git a/brand/wordmark-2400.png b/brand/wordmark-2400.png new file mode 100644 index 0000000..3bf76d5 Binary files /dev/null and b/brand/wordmark-2400.png differ diff --git a/brand/wordmark-claro.svg b/brand/wordmark-claro.svg new file mode 100644 index 0000000..01331b9 --- /dev/null +++ b/brand/wordmark-claro.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/brand/wordmark-mono.svg b/brand/wordmark-mono.svg new file mode 100644 index 0000000..94f1ea3 --- /dev/null +++ b/brand/wordmark-mono.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/brand/wordmark-plano.svg b/brand/wordmark-plano.svg new file mode 100644 index 0000000..a2bb29b --- /dev/null +++ b/brand/wordmark-plano.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/brand/wordmark.svg b/brand/wordmark.svg new file mode 100644 index 0000000..beb5ff8 --- /dev/null +++ b/brand/wordmark.svg @@ -0,0 +1,3 @@ +