aboutsummaryrefslogtreecommitdiffstats
path: root/brand
diff options
context:
space:
mode:
Diffstat (limited to 'brand')
-rw-r--r--brand/README.es.md52
-rw-r--r--brand/README.md70
-rw-r--r--brand/make_logo.py246
3 files changed, 211 insertions, 157 deletions
diff --git a/brand/README.es.md b/brand/README.es.md
new file mode 100644
index 0000000..dc9ab53
--- /dev/null
+++ b/brand/README.es.md
@@ -0,0 +1,52 @@
+# Marca 100cIA
+
+[English](README.md)
+
+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/README.md b/brand/README.md
index 498efca..18c6058 100644
--- a/brand/README.md
+++ b/brand/README.md
@@ -1,50 +1,52 @@
-# Marca 100cIA
+# 100cIA brand
-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.
+[Español](README.es.md)
-## Archivos
+The name reads **"ciencia"** (science: 100 = cien, + c + IA) and at the same time
+makes it clear the videos are made by an AI (IA in Spanish). The logo supports
+both readings: `100c` in white and the `IA` inside an amber chip (the same device
+the videos use), with a hair of space in between so the I does not read as a bar.
-| Archivo | Para qué |
+## Files
+
+| File | What for |
|---|---|
-| `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 |
+| `avatar.svg` / `avatar-1024.png` | **profile picture** |
+| `avatar-plano.svg` / `avatar-plano-1024.png` | chip-less alternative |
+| `wordmark.svg` / `wordmark-2400.png` | wordmark on a dark background |
+| `wordmark-claro.svg` | wordmark on a light background |
+| `wordmark-mono.svg` | single ink with the `IA` knocked out — watermark over video |
+| `wordmark-plano.svg` | chip-less wordmark |
+| `banner.svg` / `banner-1920.png` | video end card and thumbnail |
-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.
+The chip around the `IA` is the brand and goes on every piece. The mono version
+uses a mask: the chip is a single color and the letters are knocked out, so it
+works over any background.
-**TikTok e Instagram no aceptan SVG para la foto de perfil**: subí los `.png`.
-Los `.svg` son para imprimir, escalar o editar.
+**TikTok and Instagram do not accept SVG for the profile picture**: upload the
+`.png` files. The `.svg` files are for printing, scaling or editing.
-## Paleta (la misma de los videos)
+## Palette (the same as the 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` |
+| background | `#0B0F1A` |
+| dots | `#243050` |
+| text | `#FFFFFF` |
+| amber (IA, progress bar) | `#FFD166` |
+| dark amber (on light backgrounds) | `#D98C00` |
+| bar track | `#1B2233` |
+| green | `#06D6A0` · pink `#EF476F` · sky blue `#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.
+Typeface: **Roboto Black**, −3.5 % tracking. In the SVGs the text is already
+converted to curves, so they look the same on any machine.
-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.
+The avatar ring is the videos' progress bar, curved: same amber, same proportion
+(62 %). It is what makes the thumbnail recognizable at 44 px, where the text can
+no longer be read.
-## Regenerar
+## Regenerating
```bash
-python3 brand/make_logo.py # necesita Inkscape y Roboto Black instalados
+python3 brand/make_logo.py # needs Inkscape and Roboto Black installed
```
diff --git a/brand/make_logo.py b/brand/make_logo.py
index dac08b5..658e921 100644
--- a/brand/make_logo.py
+++ b/brand/make_logo.py
@@ -1,30 +1,30 @@
# -*- 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."""
+"""Generates the 100cIA brand kit. Text is converted to curves with Inkscape,
+so the SVGs do not depend on the font being installed."""
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"
+POINTS = "#243050"
+WHITE_C = "#FFFFFF"
+AMBER = "#FFD166"
TRACK = "#1B2233"
-GRIS = "#8D99AE"
+C_GRAY = "#8D99AE"
-FUENTE = "Roboto Black"
+FONT_NAME = "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."""
+def curve_list(parts, size=400, tracking=TRACKING):
+ """parts = [(text, color), ...] -> (inner_svg, x, y, w, h) already as curves."""
tspans = "".join(
f'<tspan fill="{c}"{f" dx=\'{0.045 * size:g}\'" if i else ""}>{t}</tspan>'
- for i, (t, c) in enumerate(partes))
+ for i, (t, c) in enumerate(parts))
src = (f'<svg xmlns="http://www.w3.org/2000/svg" width="6000" height="1200" '
f'viewBox="0 0 6000 1200"><text id="w" x="60" y="800" '
- f'font-family="{FUENTE}" font-weight="900" font-size="{size}" '
+ f'font-family="{FONT_NAME}" font-weight="900" font-size="{size}" '
f'letter-spacing="{tracking * size:g}">{tspans}</text></svg>')
with tempfile.TemporaryDirectory() as d:
a, b = os.path.join(d, "a.svg"), os.path.join(d, "b.svg")
@@ -40,192 +40,192 @@ def curvas(partes, size=400, tracking=TRACKING):
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():
+ node = next(e for e in root.iter() if e.get("id") == "w")
+ for e in node.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("<g"):
- cuerpo = f"<g>{cuerpo}</g>"
- return cuerpo, q["x"], q["y"], q["width"], q["height"]
+ body_obj = ET.tostring(node, encoding="unicode")
+ body_obj = body_obj.replace(f' xmlns="{NS}"', "")
+ if not body_obj.lstrip().startswith("<g"):
+ body_obj = f"<g>{body_obj}</g>"
+ return body_obj, q["x"], q["y"], q["width"], q["height"]
-def colocar(g, bx, by, bw, bh, cx, cy, ancho):
- s = ancho / bw
+def place(g, bx, by, bw, bh, cx, cy, width_px):
+ s = width_px / bw
tx = cx - s * (bx + bw / 2)
ty = cy - s * (by + bh / 2)
return f'<g transform="translate({tx:.3f},{ty:.3f}) scale({s:.5f})">{g}</g>'
-def puntos(id_, sep=118, r=4.2, color=PUNTOS, op=0.55):
+def point_list(id_, sep=118, r=4.2, color=POINTS, op=0.55):
return (f'<pattern id="{id_}" width="{sep}" height="{sep}" '
f'patternUnits="userSpaceOnUse">'
f'<circle cx="{sep/2}" cy="{sep/2}" r="{r}" fill="{color}" '
f'opacity="{op}"/></pattern>')
-def arco(cx, cy, r, desde, hasta, color, w):
- """Arco en grados, 0 = arriba, sentido horario."""
+def arc_m(cx, cy, r, since, until, color, w):
+ """Arc in degrees, 0 = up, clockwise."""
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
+ x0, y0 = p(since)
+ x1, y1 = p(until)
+ largo = 1 if (until - since) % 360 > 180 else 0
return (f'<path d="M {x0:.2f} {y0:.2f} A {r} {r} 0 {largo} 1 {x1:.2f} {y1:.2f}" '
f'fill="none" stroke="{color}" stroke-width="{w}" stroke-linecap="round"/>')
# ---------------------------------------------------------------- avatar
-def avatar(archivo, chip=False, pct=0.62):
+def avatar(file_path, chip=False, pct=0.62):
D = 1024
R = D / 2
- anillo_r, anillo_w = R - 26, 20
+ ring_r, ring_w = R - 26, 20
if chip:
- g1, x1, y1, w1, h1 = curvas([("100c", BLANCO)])
- g2, x2, y2, w2, h2 = curvas([("IA", "#0B0F1A")])
+ g1, x1, y1, w1, h1 = curve_list([("100c", WHITE_C)])
+ g2, x2, y2, w2, h2 = curve_list([("IA", "#0B0F1A")])
else:
- g1, x1, y1, w1, h1 = curvas([("100c", BLANCO), ("IA", AMBAR)])
+ g1, x1, y1, w1, h1 = curve_list([("100c", WHITE_C), ("IA", AMBER)])
- cuerpo = [
+ body_obj = [
f'<circle cx="{R}" cy="{R}" r="{R}" fill="{BG}"/>',
f'<circle cx="{R}" cy="{R}" r="{R}" fill="url(#dots)"/>',
- f'<circle cx="{R}" cy="{R}" r="{anillo_r}" fill="none" '
- f'stroke="{TRACK}" stroke-width="{anillo_w}"/>',
- arco(R, R, anillo_r, 0, 360 * pct, AMBAR, anillo_w),
+ f'<circle cx="{R}" cy="{R}" r="{ring_r}" fill="none" '
+ f'stroke="{TRACK}" stroke-width="{ring_w}"/>',
+ arc_m(R, R, ring_r, 0, 360 * pct, AMBER, ring_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'<rect x="{cxc - cw/2:.1f}" y="{R - ch/2:.1f}" width="{cw:.1f}" '
- f'height="{ch:.1f}" rx="{ch*0.30:.1f}" fill="{AMBAR}"/>')
- cuerpo.append(colocar(g2, x2, y2, w2, h2, cxc, R, w2 * esc))
+ total_width = 760
+ # the "IA" chip takes ~38% of the width, like the chips in the videos
+ w_text = total_width * 0.60
+ body_obj.append(place(g1, x1, y1, w1, h1, R - total_width / 2 + w_text / 2, R, w_text))
+ scale_f = w_text / w1
+ cw, ch = w2 * scale_f * 1.0 + 70, h1 * scale_f + 62
+ cxc = R - total_width / 2 + w_text + 26 + cw / 2
+ body_obj.append(f'<rect x="{cxc - cw/2:.1f}" y="{R - ch/2:.1f}" width="{cw:.1f}" '
+ f'height="{ch:.1f}" rx="{ch*0.30:.1f}" fill="{AMBER}"/>')
+ body_obj.append(place(g2, x2, y2, w2, h2, cxc, R, w2 * scale_f))
else:
- cuerpo.append(colocar(g1, x1, y1, w1, h1, R, R, 740))
+ body_obj.append(place(g1, x1, y1, w1, h1, R, R, 740))
svg = (f'<svg xmlns="http://www.w3.org/2000/svg" width="{D}" height="{D}" '
- f'viewBox="0 0 {D} {D}"><defs>{puntos("dots")}</defs>'
- + "".join(cuerpo) + '</svg>')
- 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"),
+ f'viewBox="0 0 {D} {D}"><defs>{point_list("dots")}</defs>'
+ + "".join(body_obj) + '</svg>')
+ open(os.path.join(HERE, file_path), "w", encoding="utf-8").write(svg)
+ return file_path
+
+
+# ---------------------------------------------------------------- wordmark
+# The chip around "IA" is the brand: it goes on every variant except the
+# "flat" one, kept as an alternative.
+MODES = {
+ # ink chip background chip letter
+ "oscuro": (WHITE_C, AMBER, "#0B0F1A"),
"claro": ("#0B0F1A", "#D98C00", "#FFFFFF"),
- "mono": (BLANCO, BLANCO, None), # letras caladas
+ "mono": (WHITE_C, WHITE_C, None), # knocked-out letters
}
-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")])
+def _lockup(mode, alto=520):
+ """Returns (svg_pieces, width, height) of the '100c' lockup + 'IA' chip."""
+ ink, chip_bg, letter = MODES[mode]
+ g1, x1, y1, w1, h1 = curve_list([("100c", ink)])
+ g2, x2, y2, w2, h2 = curve_list([("IA", letter or "#000000")])
- esc = alto / h1
- wt = w1 * esc
- cw = w2 * esc + 0.68 * alto
+ scale_f = alto / h1
+ wt = w1 * scale_f
+ cw = w2 * scale_f + 0.68 * alto
ch = alto + 0.60 * alto
- hueco = 0.13 * alto
- W = wt + hueco + cw
+ gap_m = 0.13 * alto
+ W = wt + gap_m + cw
cy = ch / 2
rx = ch * 0.28
- cx_chip = wt + hueco + cw / 2
- chip_x = wt + hueco
+ cx_chip = wt + gap_m + cw / 2
+ chip_x = wt + gap_m
- piezas = [colocar(g1, x1, y1, w1, h1, wt / 2, cy, wt)]
- if letra is None: # una sola tinta: el IA se cala
+ pieces = [place(g1, x1, y1, w1, h1, wt / 2, cy, wt)]
+ if letter is None: # a single ink: the IA is knocked out
mascara = (f'<mask id="cala">'
f'<rect x="{chip_x:.1f}" y="0" width="{cw:.1f}" height="{ch:.1f}" '
f'rx="{rx:.1f}" fill="#FFFFFF"/>'
- + colocar(g2, x2, y2, w2, h2, cx_chip, cy, w2 * esc)
+ + place(g2, x2, y2, w2, h2, cx_chip, cy, w2 * scale_f)
+ '</mask>')
- piezas.append(f'<defs>{mascara}</defs>')
- piezas.append(f'<rect x="{chip_x:.1f}" y="0" width="{cw:.1f}" height="{ch:.1f}" '
- f'rx="{rx:.1f}" fill="{fondo_chip}" mask="url(#cala)"/>')
+ pieces.append(f'<defs>{mascara}</defs>')
+ pieces.append(f'<rect x="{chip_x:.1f}" y="0" width="{cw:.1f}" height="{ch:.1f}" '
+ f'rx="{rx:.1f}" fill="{chip_bg}" mask="url(#cala)"/>')
else:
- piezas.append(f'<rect x="{chip_x:.1f}" y="0" width="{cw:.1f}" height="{ch:.1f}" '
- f'rx="{rx:.1f}" fill="{fondo_chip}"/>')
- piezas.append(colocar(g2, x2, y2, w2, h2, cx_chip, cy, w2 * esc))
- return piezas, W, ch
+ pieces.append(f'<rect x="{chip_x:.1f}" y="0" width="{cw:.1f}" height="{ch:.1f}" '
+ f'rx="{rx:.1f}" fill="{chip_bg}"/>')
+ pieces.append(place(g2, x2, y2, w2, h2, cx_chip, cy, w2 * scale_f))
+ return pieces, W, ch
-def wordmark(archivo, modo="oscuro", margen=0.10):
- piezas, W0, H0 = _lockup(modo)
- m = margen * H0
+def wordmark(file_path, mode="oscuro", margin=0.10):
+ pieces, W0, H0 = _lockup(mode)
+ m = margin * H0
W, H = int(round(W0 + 2 * m)), int(round(H0 + 2 * m))
svg = (f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}" '
f'viewBox="0 0 {W} {H}"><g transform="translate({m:.1f},{m:.1f})">'
- + "".join(piezas) + '</g></svg>')
- open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg)
- return archivo
+ + "".join(pieces) + '</g></svg>')
+ open(os.path.join(HERE, file_path), "w", encoding="utf-8").write(svg)
+ return file_path
-def wordmark_plano(archivo):
- """Alternativa sin chip: '100cIA' de corrido, el IA en ambar."""
- g, x, y, w, h = curvas([("100c", BLANCO), ("IA", AMBAR)])
+def wordmark_plano(file_path):
+ """Chip-less alternative: '100cIA' in one run, the IA in amber."""
+ g, x, y, w, h = curve_list([("100c", WHITE_C), ("IA", AMBER)])
W = 2400
- ancho = W * 0.88
- H = int(round(h / w * ancho + 2 * 0.06 * W))
+ width_px = W * 0.88
+ H = int(round(h / w * width_px + 2 * 0.06 * W))
svg = (f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}" '
f'viewBox="0 0 {W} {H}">'
- + colocar(g, x, y, w, h, W / 2, H / 2, ancho) + '</svg>')
- open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg)
- return archivo
+ + place(g, x, y, w, h, W / 2, H / 2, width_px) + '</svg>')
+ open(os.path.join(HERE, file_path), "w", encoding="utf-8").write(svg)
+ return file_path
# ---------------------------------------------------------------- banner
-def banner(archivo, tagline="ciencia en 40 segundos"):
+def banner(file_path, 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 = [
+ g, x, y, w, h = curve_list([("100c", WHITE_C)])
+ t, tx, ty, tw, th = curve_list([(tagline, "#C9D3E5")], size=200, tracking=0.012)
+ body_obj = [
f'<rect width="{W}" height="{H}" fill="{BG}"/>',
f'<rect width="{W}" height="{H}" fill="url(#dots)"/>',
f'<rect x="0" y="0" width="{W}" height="12" fill="{TRACK}"/>',
- f'<rect x="0" y="0" width="{int(W*0.62)}" height="12" fill="{AMBAR}"/>',
- None, # el lockup se arma abajo (con chip, igual que el avatar)
- colocar(t, tx, ty, tw, th, W / 2, H / 2 + 205, 830),
+ f'<rect x="0" y="0" width="{int(W*0.62)}" height="12" fill="{AMBER}"/>',
+ None, # the lockup is built below (with the chip, like the avatar)
+ place(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
+ # lockup with chip, centred, 1150 px total width
+ g2, x2, y2, w2, h2 = curve_list([("IA", "#0B0F1A")])
+ WIDTH, 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'<rect x="{izq + wt + hueco:.1f}" y="{cy - ch/2:.1f}" width="{cw:.1f}" '
- f'height="{ch:.1f}" rx="{ch*0.28:.1f}" fill="{AMBAR}"/>'
- + colocar(g2, x2, y2, w2, h2, izq + wt + hueco + cw / 2, cy, w2 * esc * k))
+ scale_f = alto / h
+ wt = w * scale_f
+ cw, ch = w2 * scale_f + 0.68 * alto, alto + 0.60 * alto
+ gap_m = 0.13 * alto
+ total = wt + gap_m + cw
+ k = WIDTH / total
+ wt, cw, ch, gap_m = wt * k, cw * k, ch * k, gap_m * k
+ left_part = W / 2 - WIDTH / 2
+ body_obj[body_obj.index(None)] = (
+ place(g, x, y, w, h, left_part + wt / 2, cy, wt)
+ + f'<rect x="{left_part + wt + gap_m:.1f}" y="{cy - ch/2:.1f}" width="{cw:.1f}" '
+ f'height="{ch:.1f}" rx="{ch*0.28:.1f}" fill="{AMBER}"/>'
+ + place(g2, x2, y2, w2, h2, left_part + wt + gap_m + cw / 2, cy, w2 * scale_f * k))
svg = (f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}" '
- f'viewBox="0 0 {W} {H}"><defs>{puntos("dots", sep=140, r=5)}</defs>'
- + "".join(cuerpo) + '</svg>')
- open(os.path.join(HERE, archivo), "w", encoding="utf-8").write(svg)
- return archivo
+ f'viewBox="0 0 {W} {H}"><defs>{point_list("dots", sep=140, r=5)}</defs>'
+ + "".join(body_obj) + '</svg>')
+ open(os.path.join(HERE, file_path), "w", encoding="utf-8").write(svg)
+ return file_path
if __name__ == "__main__":
- # la variante con chip es la marca: se queda con los nombres principales
+ # the chip variant is the brand: it keeps the main file names
for f in (avatar("avatar.svg", chip=True), avatar("avatar-plano.svg"),
wordmark("wordmark.svg", "oscuro"),
wordmark("wordmark-claro.svg", "claro"),