Add original branding proofs for six channels
Ring X, Riot, Odyssey, Terra, Dark Files and PixelZ, redrawn from Paul's concept boards using the After Dark workflow: editable VectorCraft logos, layered PhotoCraft backgrounds, EffectCraft idents and FigCraft review sheets, all rebuilt by one script. Design proofs only; nothing is added to the app. Adds Anton and Comfortaa, both under the SIL OFL. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@@ -0,0 +1,623 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Original Orbit channel branding, built the After Dark way from the concept boards.
|
||||
|
||||
Writes editable SVG sources, then uses the installed Craft CLIs for native VectorCraft,
|
||||
PhotoCraft, FigCraft and EffectCraft files. Existing channel folders are never touched.
|
||||
|
||||
build-network-brands.py [--static] [channel ...]
|
||||
"""
|
||||
from pathlib import Path
|
||||
import html, json, math, os, random, shutil, subprocess, sys
|
||||
from PIL import Image
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parent.parent
|
||||
ENV = dict(os.environ, XDG_DATA_HOME=str(ROOT / '.tooling/font-data'))
|
||||
NAVY, PANEL, BLUE, FOCUS, MUTED = '#071632', '#12356B', '#194C91', '#FFDE59', '#B7CBE8'
|
||||
BARLOW, CONDENSED, ANTON, ROUND = 'Barlow', 'Barlow Condensed', 'Anton', 'Comfortaa'
|
||||
|
||||
|
||||
def svg(w, h, body):
|
||||
return f'<svg xmlns="http://www.w3.org/2000/svg" width="{w}" height="{h}" viewBox="0 0 {w} {h}">{body}</svg>'
|
||||
|
||||
|
||||
def text(x, y, value, size, fill='white', family=BARLOW, weight='400', extra=''):
|
||||
return f'<text x="{x}" y="{y}" font-family="{family}" font-size="{size}" font-weight="{weight}" fill="{fill}" {extra}>{html.escape(value)}</text>'
|
||||
|
||||
|
||||
def stops(*pairs):
|
||||
return ''.join(f'<stop offset="{o}" stop-color="{c}"' + (f' stop-opacity="{a[0]}"' if a else '') + '/>' for o, c, *a in pairs)
|
||||
|
||||
|
||||
def vgrad(name, *pairs):
|
||||
return f'<linearGradient id="{name}" x1="0" y1="0" x2="0" y2="1">{stops(*pairs)}</linearGradient>'
|
||||
|
||||
|
||||
def rgrad(name, *pairs):
|
||||
return f'<radialGradient id="{name}">{stops(*pairs)}</radialGradient>'
|
||||
|
||||
|
||||
SILVER = vgrad('silver', (0, '#FFFFFF'), (.44, '#E8EDF5'), (.5, '#B7CBE8'), (1, '#F5F7FF'))
|
||||
CRESCENT = 'M335 132C141 114 66 384 257 475C143 363 185 207 335 132Z'
|
||||
|
||||
|
||||
def crescent(fill='url(#silver)'):
|
||||
return f'<path d="{CRESCENT}" fill="{fill}"/>'
|
||||
|
||||
|
||||
def ring(colour, width=11):
|
||||
"""The family's orbital line: the same path as After Dark, in the channel's accent."""
|
||||
return (f'<path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289C455 250 405 250 369 261" fill="none" stroke="{colour}" stroke-width="{width}"/>'
|
||||
f'<circle cx="430" cy="282" r="9" fill="{colour}"/>')
|
||||
|
||||
|
||||
def skyline(seed, base='#061025', lit='#FFDE59', low=70, high=220):
|
||||
rng, lamps = random.Random(seed), random.Random(seed + 7)
|
||||
x, d, windows = 0, 'M0 1080V900', ''
|
||||
while x < 1920:
|
||||
w, h = rng.randint(35, 85), rng.randint(low, high)
|
||||
d += f'H{x}V{1080 - h}H{x + w}V1080'
|
||||
if lamps.random() > .2:
|
||||
for wy in range(1080 - h + 12, 1069, 18):
|
||||
for wx in range(x + 9, min(x + w - 7, 1912), 14):
|
||||
if lamps.random() < .24:
|
||||
windows += f'<rect x="{wx}" y="{wy}" width="4" height="7" fill="{lit}" opacity="{lamps.choice([.35, .5, .7])}"/>'
|
||||
x += w + rng.randint(5, 18)
|
||||
return f'<path d="{d}H1920Z" fill="{base}"/>{windows}'
|
||||
|
||||
|
||||
def stars(seed, count=70, colour=MUTED, y1=720):
|
||||
rng = random.Random(seed)
|
||||
return ''.join(f'<circle cx="{rng.randrange(30, 1890)}" cy="{rng.randrange(30, y1)}" r="{rng.choice([1, 1, 1.5, 2])}" fill="{colour}" opacity="{rng.choice([.35, .5, .75])}"/>' for _ in range(count))
|
||||
|
||||
|
||||
def jagged(points, seed, amount=9, step=26):
|
||||
"""A torn edge: subdivide each side and nudge the points, so no two tears match."""
|
||||
rng, out = random.Random(seed), []
|
||||
for (x1, y1), (x2, y2) in zip(points, points[1:] + points[:1]):
|
||||
n = max(1, int(math.hypot(x2 - x1, y2 - y1) / step))
|
||||
for i in range(n):
|
||||
t = i / n
|
||||
out.append((round(x1 + (x2 - x1) * t + rng.uniform(-amount, amount)), round(y1 + (y2 - y1) * t + rng.uniform(-amount, amount))))
|
||||
return ' '.join(f'{x},{y}' for x, y in out)
|
||||
|
||||
|
||||
def halftone(x0, y0, cols, rows, gap, colour, seed=1, opacity=.8):
|
||||
"""Dots shrink away from the patch's centre."""
|
||||
out = ''
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
d = math.hypot((c - cols / 2) / (cols / 2), (r - rows / 2) / (rows / 2))
|
||||
if d < 1:
|
||||
out += f'<circle cx="{x0 + c * gap + (r % 2) * gap / 2:.0f}" cy="{y0 + r * gap}" r="{(1 - d) * gap * .46:.1f}" fill="{colour}" opacity="{opacity}"/>'
|
||||
return out
|
||||
|
||||
|
||||
def checker(x, y, cols, rows, size, angle=0, a='#F7F7F7', b='#0B0E16'):
|
||||
cells = ''.join(f'<rect x="{c * size}" y="{r * size}" width="{size}" height="{size}" fill="{a if (c + r) % 2 else b}"/>' for r in range(rows) for c in range(cols))
|
||||
return f'<g transform="translate({x},{y}) rotate({angle})">{cells}</g>'
|
||||
|
||||
|
||||
def bolt(x, y, scale, colour):
|
||||
return f'<polygon transform="translate({x},{y}) scale({scale})" points="60,0 10,95 48,95 22,190 110,70 66,70 96,0" fill="{colour}"/>'
|
||||
|
||||
|
||||
def burst(cx, cy, r1, r2, points, colour, opacity=1):
|
||||
pts = []
|
||||
for i in range(points * 2):
|
||||
r, a = (r1 if i % 2 else r2), math.pi * i / points - math.pi / 2
|
||||
pts.append(f'{cx + r * math.cos(a):.0f},{cy + r * math.sin(a):.0f}')
|
||||
return f'<polygon points="{" ".join(pts)}" fill="{colour}" opacity="{opacity}"/>'
|
||||
|
||||
|
||||
def cube(x, y, s, top, left, right):
|
||||
"""An isometric cube whose top corner sits at (x, y)."""
|
||||
w, h = s * .87, s * .5
|
||||
return (f'<polygon points="{x:.0f},{y:.0f} {x + w:.0f},{y + h:.0f} {x:.0f},{y + 2 * h:.0f} {x - w:.0f},{y + h:.0f}" fill="{top}"/>'
|
||||
f'<polygon points="{x - w:.0f},{y + h:.0f} {x:.0f},{y + 2 * h:.0f} {x:.0f},{y + 2 * h + s:.0f} {x - w:.0f},{y + h + s:.0f}" fill="{left}"/>'
|
||||
f'<polygon points="{x + w:.0f},{y + h:.0f} {x:.0f},{y + 2 * h:.0f} {x:.0f},{y + 2 * h + s:.0f} {x + w:.0f},{y + h + s:.0f}" fill="{right}"/>')
|
||||
|
||||
|
||||
def spotlight(x, y, reach, spread, colour, name):
|
||||
"""A beam that fades out along its length. Gradients, so no filters are needed."""
|
||||
return (f'<defs><linearGradient id="{name}" gradientUnits="userSpaceOnUse" x1="{x}" y1="{y}" x2="{x + reach[0]}" y2="{y + reach[1]}">{stops((0, colour, .62), (1, colour, 0))}</linearGradient></defs>'
|
||||
f'<polygon points="{x - 8},{y} {x + 8},{y} {x + reach[0] + spread},{y + reach[1]} {x + reach[0] - spread},{y + reach[1]}" fill="url(#{name})"/>'
|
||||
f'<circle cx="{x}" cy="{y}" r="17" fill="#E9F1FF"/><circle cx="{x}" cy="{y}" r="28" fill="{colour}" opacity=".35"/>')
|
||||
|
||||
|
||||
def truss(x1, y1, x2, y2, depth=46, colour='#8C9AB3', opacity=.7, step=52):
|
||||
"""A steel truss: two chords and a zig-zag between them."""
|
||||
length = math.hypot(x2 - x1, y2 - y1)
|
||||
ux, uy = (x2 - x1) / length, (y2 - y1) / length
|
||||
nx, ny = -uy * depth, ux * depth
|
||||
zig = []
|
||||
for i in range(int(length / step) + 1):
|
||||
d = i * step
|
||||
px, py = x1 + ux * d, y1 + uy * d
|
||||
zig.append(f'{px + (nx if i % 2 else 0):.0f},{py + (ny if i % 2 else 0):.0f}')
|
||||
return (f'<g opacity="{opacity}" fill="none" stroke="{colour}"><line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke-width="6"/>'
|
||||
f'<line x1="{x1 + nx:.0f}" y1="{y1 + ny:.0f}" x2="{x2 + nx:.0f}" y2="{y2 + ny:.0f}" stroke-width="6"/>'
|
||||
f'<polyline points="{" ".join(zig)}" stroke-width="3"/></g>')
|
||||
|
||||
|
||||
def word_chrome():
|
||||
return vgrad('chrome', (0, '#FFFFFF'), (.34, '#C9CDD6'), (.5, '#5E6675'), (.56, '#E6EAF1'), (1, '#8E96A6'))
|
||||
|
||||
|
||||
def ring_x():
|
||||
defs = '<defs>' + SILVER + word_chrome() + vgrad('red', (0, '#FF4A55'), (.55, '#F0142F'), (1, '#8E0B1C')) + '</defs>'
|
||||
mark = defs + crescent() + ring('#F0142F')
|
||||
orbit = text(486, 150, 'ORBIT', 50, '#C9CDD6', BARLOW, '600', 'letter-spacing="14"')
|
||||
word = f'<g transform="skewX(-9)">' + text(530, 438, 'RING', 280, 'url(#chrome)', ANTON, '400', 'letter-spacing="10"') + '</g>'
|
||||
# The X is drawn, not typed: a slashed cross cut at angles, so it can't be mistaken for Orbit X's brushstroke.
|
||||
x = ('<polygon points="1040,118 1236,118 1302,232 1416,118 1560,118 1378,312 1492,520 1296,520 1236,404 1116,520 968,520 1160,318" fill="url(#red)"/>'
|
||||
'<polygon points="1040,118 1236,118 1302,232 1280,256 1208,142 1090,142 1192,318 1020,496 968,520 1160,318" fill="#FFFFFF" opacity=".28"/>')
|
||||
sweep = '<path d="M452 560C700 598 1000 570 1206 522L1190 546C980 600 660 622 452 560Z" fill="#F0142F"/>'
|
||||
parts = [('crescent', mark), ('orbit', defs + orbit), ('word', defs + word), ('accent', defs + f'<g transform="translate(-50,0)">{x}</g>'), ('sweep', defs + sweep)]
|
||||
epg = defs + f'<g transform="translate(-5,1) scale(.26)">{crescent()}{ring("#F0142F")}</g>' + text(134, 50, 'ORBIT', 18, '#C9CDD6', BARLOW, '600', 'letter-spacing="5"') + text(134, 128, 'RING', 74, 'url(#chrome)', ANTON) + f'<g transform="translate(-6,10) scale(.27)">{x}</g>'
|
||||
bug = defs + f'<g transform="translate(-7,-8) scale(.22)">{crescent("#FFFFFF")}{ring("#F0142F")}</g>' + text(112, 100, 'RING', 82, '#FFFFFF', ANTON, '400', 'stroke="#071632" stroke-width="2"') + f'<g transform="translate(-20,-8) scale(.24)">{x}</g>'
|
||||
arena = ('<defs>' + vgrad('hall', (0, '#050812'), (.6, '#0A1226'), (1, '#0A0E1E')) + rgrad('floorglow', (0, '#F0142F', .42), (1, '#F0142F', 0)) + rgrad('blueglow', (0, '#1E6FFF', .34), (1, '#1E6FFF', 0)) + '</defs>'
|
||||
'<rect width="1920" height="1080" fill="url(#hall)"/><ellipse cx="520" cy="860" rx="720" ry="330" fill="url(#floorglow)"/><ellipse cx="1420" cy="860" rx="720" ry="330" fill="url(#floorglow)"/><ellipse cx="960" cy="240" rx="900" ry="330" fill="url(#blueglow)"/>')
|
||||
rig = truss(0, 110, 1920, 110) + truss(330, 150, 330, 900) + truss(1590, 150, 1590, 900) + truss(0, 340, 300, 150, 40, '#8C9AB3', .4) + truss(1920, 340, 1620, 150, 40, '#8C9AB3', .4)
|
||||
screen = '<rect x="470" y="220" width="980" height="520" fill="#0A0E1E" stroke="#8C9AB3" stroke-width="5"/>' + ''.join(f'<line x1="{470 + i * 40}" y1="222" x2="{430 + i * 40 + 40}" y2="738" stroke="#1B2233" stroke-width="2" opacity=".55"/>' for i in range(1, 25))
|
||||
floor = ('<polygon points="620,760 1300,760 1860,1080 60,1080" fill="#0E1730"/>' + ''.join(f'<line x1="{620 + i * 68}" y1="760" x2="{60 + i * 186}" y2="1080" stroke="#1E6FFF" stroke-width="2" opacity=".28"/>' for i in range(11)) +
|
||||
'<polygon points="620,760 640,760 240,1080 180,1080" fill="#F0142F" opacity=".7"/><polygon points="1300,760 1280,760 1680,1080 1740,1080" fill="#F0142F" opacity=".7"/>')
|
||||
rng = random.Random(24)
|
||||
crowd = ''
|
||||
x_ = -20
|
||||
while x_ < 1960:
|
||||
h = rng.randint(120, 200)
|
||||
if 470 < x_ < 1420:
|
||||
h -= 95
|
||||
crowd += f'<circle cx="{x_}" cy="{1080 - h}" r="{rng.randint(22, 30)}" fill="#03050C"/><rect x="{x_ - 36}" y="{1080 - h + 20}" width="72" height="{h}" rx="20" fill="#03050C"/>'
|
||||
if rng.random() < .42:
|
||||
crowd += f'<rect x="{x_ + 16}" y="{1080 - h - 92}" width="15" height="118" rx="7" fill="#03050C" transform="rotate({rng.randint(-16, 16)} {x_ + 23} {1080 - h})"/>'
|
||||
x_ += rng.randint(48, 78)
|
||||
sparks = ''.join(f'<circle cx="{rng.randrange(40, 1880)}" cy="{rng.randrange(240, 860)}" r="{rng.choice([1.5, 2, 3])}" fill="{rng.choice(["#FF8A3C", "#FF4A55", "#FFD08A"])}" opacity="{rng.choice([.45, .7, .9])}"/>' for _ in range(70))
|
||||
beams = [(150, 120, (360, 760), 150, '#1E6FFF'), (560, 120, (-120, 760), 130, '#F0142F'), (800, 120, (120, 760), 130, '#1E6FFF'), (1120, 120, (-120, 760), 130, '#1E6FFF'), (1360, 120, (120, 760), 130, '#F0142F'), (1770, 120, (-360, 760), 150, '#1E6FFF')]
|
||||
lights = [(f'beam_{i + 1}', spotlight(*b[:2], b[2], b[3], b[4], f'beam{i}')) for i, b in enumerate(beams)]
|
||||
layers = [('arena', arena), ('rig', rig + screen + floor)] + lights + [('sparks', sparks), ('crowd', crowd)]
|
||||
return dict(id='orbit-ring-x', name='Ring X', tag='Wrestling television and events', palette=[('Ring red', '#F0142F'), ('Chrome', '#C9CDD6'), ('Electric blue', '#1E6FFF'), ('Arena black', '#0A0E1E')],
|
||||
accent='#F0142F', parts=parts, epg=epg, bug=bug, layers=layers, background='#0A0E1E', base=['arena', 'rig', 'crowd'],
|
||||
motion=[(f'beam_{i + 1}', .25 + i * .2) for i in range(6)] + [('sparks', 1.5)], trail=([[150, 610], [1140, 430]], [[0, 0], [-260, 120]], [[260, 60], [0, 0]]),
|
||||
reveal=[('crescent', 2.3, 'fade'), ('orbit', 2.42, 'fade'), ('word', 2.42, 'rise'), ('sweep', 2.5, 'fade'), ('accent', 2.72, 'slam')], note='Arena lights come up one by one, a red line draws, the metal lettering forms, then the red X lands. No strobing: each light ramps over 0.4 s.')
|
||||
|
||||
|
||||
def riot():
|
||||
defs = '<defs>' + SILVER + '</defs>'
|
||||
paper = (f'<polygon points="{jagged([(440, 120), (1296, 72), (1336, 470), (500, 524)], 3, 13)}" fill="#D7FF00"/>')
|
||||
pink = (f'<polygon points="{jagged([(420, 300), (1370, 330), (1340, 570), (452, 570)], 5, 15)}" fill="#FF2EA6"/>')
|
||||
dots = halftone(180, 330, 24, 16, 15, '#A84DFF') + halftone(1020, 30, 24, 10, 15, '#FF2EA6')
|
||||
word = text(478, 470, 'RIOT', 350, '#0B0E16', ANTON, '400', 'letter-spacing="30" transform="rotate(-3 900 300)"')
|
||||
mark = defs + crescent('#F7F7F7') + ring('#FF2EA6')
|
||||
orbit = text(520, 104, 'ORBIT', 50, '#F7F7F7', BARLOW, '600', 'letter-spacing="14" transform="rotate(-3 620 100)"')
|
||||
crown = '<path d="M1240 40L1262 -8L1302 26L1344 -18L1360 40Z" transform="translate(-110,20)" fill="none" stroke="#F7F7F7" stroke-width="9" stroke-linejoin="round"/>'
|
||||
ticks = '<path d="M1366 118L1424 78M1376 178L1448 168M1356 62L1386 24" stroke="#D7FF00" stroke-width="13" stroke-linecap="round"/>'
|
||||
strip = checker(640, 545, 26, 3, 19, -2)
|
||||
sweep = '<path d="M470 618C760 640 1110 620 1380 566" fill="none" stroke="#FF2EA6" stroke-width="8"/>'
|
||||
parts = [('dots', dots), ('pink', pink), ('paper', paper), ('crescent', mark), ('word', word), ('orbit', orbit), ('accent', crown + ticks + strip), ('sweep', sweep)]
|
||||
epg = defs + f'<g transform="translate(-5,1) scale(.26)">{crescent("#F7F7F7")}{ring("#FF2EA6")}</g>' + f'<polygon points="{jagged([(132, 62), (348, 52), (358, 146), (138, 152)], 8, 4, 18)}" fill="#D7FF00"/>' + text(134, 42, 'ORBIT', 20, '#F7F7F7', BARLOW, '600', 'letter-spacing="5"') + text(144, 140, 'RIOT', 82, '#0B0E16', ANTON, '400', 'letter-spacing="9"')
|
||||
bug = defs + f'<g transform="translate(-7,-8) scale(.22)">{crescent("#F7F7F7")}{ring("#FF2EA6")}</g>' + f'<polygon points="{jagged([(104, 16), (330, 8), (336, 120), (108, 124)], 9, 4, 18)}" fill="#D7FF00"/>' + text(122, 112, 'RIOT', 96, '#0B0E16', ANTON, '400', 'letter-spacing="9"')
|
||||
sky = '<defs>' + vgrad('riotsky', (0, '#0B0E2A'), (.55, '#3A1A78'), (1, '#6A1FA8')) + '</defs><rect width="1920" height="1080" fill="url(#riotsky)"/>'
|
||||
torn = (f'<polygon points="{jagged([(-20, 130), (720, 200), (660, 330), (-20, 270)], 11, 11)}" fill="#F7F7F7"/>' + f'<polygon points="{jagged([(1240, 700), (1940, 560), (1940, 900), (1270, 950)], 12, 13)}" fill="#FF2EA6"/>' +
|
||||
f'<polygon points="{jagged([(300, 300), (1620, 250), (1600, 840), (330, 880)], 13, 15)}" fill="#FF2EA6"/>' + halftone(60, 480, 36, 24, 18, '#A84DFF', opacity=.9) + halftone(1300, 40, 36, 20, 18, '#00E5FF', opacity=.7))
|
||||
rng = random.Random(77)
|
||||
tv = ('<rect x="520" y="210" width="880" height="660" rx="60" fill="#2A1830"/><rect x="520" y="210" width="880" height="660" rx="60" fill="none" stroke="#120A18" stroke-width="10"/>'
|
||||
'<rect x="570" y="262" width="640" height="550" rx="46" fill="#0B0E16"/>'
|
||||
'<circle cx="1306" cy="360" r="46" fill="#120A18"/><circle cx="1306" cy="360" r="28" fill="#6C5A70"/><circle cx="1306" cy="500" r="46" fill="#120A18"/><circle cx="1306" cy="500" r="28" fill="#6C5A70"/>' +
|
||||
''.join(f'<rect x="1262" y="{610 + i * 24}" width="88" height="10" fill="#120A18"/>' for i in range(6)))
|
||||
static = ''.join(f'<rect x="{rng.randrange(586, 1190)}" y="{rng.randrange(280, 790)}" width="{rng.randint(6, 34)}" height="3" fill="{rng.choice(["#F7F7F7", "#9AA0AC", "#5B606C"])}" opacity="{rng.choice([.4, .6, .85])}"/>' for _ in range(900))
|
||||
shapes = [('burst', burst(960, 200, 78, 170, 9, '#00E5FF')), ('bolt_left', bolt(150, 330, 1.7, '#D7FF00')), ('bolt_right', bolt(1560, 290, 1.7, '#D7FF00')), ('strip', checker(20, 700, 22, 4, 26, -5))]
|
||||
city = skyline(9, '#0B0E2A', '#FFDE59', 70, 170)
|
||||
layers = [('sky', sky), ('torn', torn), ('city', city)] + shapes + [('tv', tv), ('static', static)]
|
||||
return dict(id='orbit-riot', name='Riot', tag='Adult animation, sitcoms and alternative comedy', palette=[('Electric lime', '#D7FF00'), ('Hot pink', '#FF2EA6'), ('Cyan', '#00E5FF'), ('Orange', '#FF8A00'), ('Purple', '#A84DFF'), ('Near black', '#0B0E16')],
|
||||
accent='#FF2EA6', parts=parts, epg=epg, bug=bug, layers=layers, background='#0B0E2A', base=['sky', 'torn', 'city', 'tv'],
|
||||
motion=[('static', .1), ('burst', .9), ('bolt_left', 1.1), ('bolt_right', 1.25), ('strip', 1.4)], pop={'burst', 'bolt_left', 'bolt_right', 'strip'}, trail=([[180, 840], [1500, 640]], [[0, 0], [-300, 120]], [[320, 120], [0, 0]]),
|
||||
scrim=False, reveal=[('dots', 1.9, 'fade'), ('pink', 2.0, 'slam'), ('paper', 2.15, 'slam'), ('crescent', 2.3, 'fade'), ('word', 2.4, 'slam'), ('orbit', 2.55, 'fade'), ('accent', 2.7, 'slam'), ('sweep', 2.8, 'fade')],
|
||||
note='Static on a retro TV, graphic shapes burst in, then the logo assembles as a collage. The static holds steady rather than flickering, to stay clear of flashing.')
|
||||
|
||||
|
||||
def odyssey():
|
||||
gold = vgrad('gold', (0, '#FFE9A8'), (1, '#E9B44C'))
|
||||
defs = '<defs>' + SILVER + gold + '</defs>'
|
||||
star = '<path d="M430 240L442 276L478 288L442 300L430 336L418 300L382 288L418 276Z" fill="url(#gold)"/>'
|
||||
mark = defs + crescent() + '<path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289" fill="none" stroke="url(#gold)" stroke-width="10"/>'
|
||||
orbit = text(510, 180, 'ORBIT', 56, '#D6E2F3', BARLOW, '600', 'letter-spacing="24"')
|
||||
word = text(486, 440, 'ODYSSEY', 268, 'url(#silver)', CONDENSED, '500', 'letter-spacing="12"')
|
||||
sweep = '<path d="M470 510C760 560 1140 540 1480 450C1200 580 760 610 470 510Z" fill="url(#gold)"/>'
|
||||
parts = [('crescent', mark), ('orbit', defs + orbit), ('word', defs + word), ('accent', defs + star), ('sweep', defs + sweep)]
|
||||
small = f'<g transform="translate(-5,1) scale(.26)">{crescent()}<path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289" fill="none" stroke="url(#gold)" stroke-width="11"/>{star}</g>'
|
||||
epg = defs + small + text(136, 52, 'ORBIT', 20, '#D6E2F3', BARLOW, '600', 'letter-spacing="9"') + text(134, 124, 'ODYSSEY', 78, '#F4F6FF', CONDENSED, '500', 'letter-spacing="3"')
|
||||
bug = defs + f'<g transform="translate(-7,-8) scale(.22)">{crescent("#FFFFFF")}<path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289" fill="none" stroke="url(#gold)" stroke-width="13"/></g>' + text(106, 96, 'ODYSSEY', 88, '#FFFFFF', CONDENSED, '500', 'letter-spacing="2" stroke="#071632" stroke-width="2"')
|
||||
sky = '<defs>' + vgrad('space', (0, '#030817'), (.7, '#07142E'), (1, '#0E3E7A')) + '</defs><rect width="1920" height="1080" fill="url(#space)"/>'
|
||||
earth = ('<defs>' + rgrad('ocean', (.82, '#0A2F63'), (.97, '#0E5C8A'), (.995, '#138A8A'), (1, '#6FD3E8')) + '</defs><circle cx="960" cy="2820" r="2200" fill="url(#ocean)"/>')
|
||||
rng = random.Random(41)
|
||||
land = ''
|
||||
for _ in range(30):
|
||||
cx, cy = rng.randrange(40, 1880), rng.randrange(690, 1060)
|
||||
cy = cy + (2200 - math.sqrt(max(0, 2200 ** 2 - (cx - 960) ** 2))) * .9
|
||||
squash = .22 + (cy - 620) / 900
|
||||
n, pts = 14, []
|
||||
for t in range(n):
|
||||
a = 2 * math.pi * t / n
|
||||
radius = rng.uniform(.55, 1) * rng.randint(70, 170)
|
||||
pts.append((cx + radius * 1.6 * math.cos(a), cy + radius * squash * math.sin(a)))
|
||||
d = f'M{(pts[0][0] + pts[-1][0]) / 2:.0f} {(pts[0][1] + pts[-1][1]) / 2:.0f}'
|
||||
for i, (px, py) in enumerate(pts):
|
||||
nx_, ny_ = pts[(i + 1) % n]
|
||||
d += f'Q{px:.0f} {py:.0f} {(px + nx_) / 2:.0f} {(py + ny_) / 2:.0f}'
|
||||
land += f'<path d="{d}Z" fill="{rng.choice(["#1E6B57", "#2A7F5F", "#8C7A48", "#245F4E"])}" opacity=".62"/>'
|
||||
grid = ''.join(f'<ellipse cx="960" cy="2820" rx="{r}" ry="2200" fill="none" stroke="#D6E2F3" stroke-width="1.5" opacity=".16"/>' for r in (240, 620, 1040, 1500, 1950)) + ''.join(f'<circle cx="960" cy="2820" r="{r}" fill="none" stroke="#D6E2F3" stroke-width="1.5" opacity=".16"/>' for r in (2020, 2090, 2150))
|
||||
sun = '<defs>' + rgrad('sunrise', (0, '#FFF3C4', 1), (.28, '#FFC766', .72), (1, '#FFC766', 0)) + '</defs><ellipse cx="1240" cy="630" rx="760" ry="210" fill="url(#sunrise)"/><circle cx="960" cy="2820" r="2200" fill="none" stroke="#BDEBFF" stroke-width="7" opacity=".85"/>'
|
||||
layers = [('space', sky + stars(31, 110)), ('earth', earth), ('land', land), ('grid', grid), ('sunrise', sun)]
|
||||
return dict(id='orbit-odyssey', name='Odyssey', tag='Science, history, exploration', palette=[('Orbit navy', '#07142E'), ('Expedition blue', '#0E3E7A'), ('Atlantic teal', '#138A8A'), ('Orbit silver', '#D6E2F3'), ('Discovery gold', '#FFC766')],
|
||||
accent='#FFC766', parts=parts, epg=epg, bug=bug, layers=layers, background='#07142E', base=['space', 'earth', 'land'],
|
||||
motion=[('grid', .35), ('sunrise', .9)], trail=([[60, 500], [1640, 300]], [[0, 0], [-500, 40]], [[520, 120], [0, 0]]),
|
||||
reveal=[('crescent', 2.3, 'fade'), ('orbit', 2.42, 'fade'), ('word', 2.42, 'rise'), ('sweep', 2.55, 'fade'), ('accent', 2.75, 'pop')], note='Sun rises over the Earth, a gold orbital line traces across it, then the logo appears with its discovery star.')
|
||||
|
||||
|
||||
def terra():
|
||||
green = vgrad('leaf', (0, '#9BE564'), (1, '#2F9E44'))
|
||||
defs = '<defs>' + SILVER + green + rgrad('globe', (.1, '#4FB7E0'), (.72, '#123E7E'), (1, '#07142E')) + '</defs>'
|
||||
globe = '<circle cx="232" cy="300" r="176" fill="url(#globe)"/><path d="M148 214C196 186 256 204 262 240C266 278 214 268 198 300C186 330 214 372 180 386C138 354 116 278 148 214Z" fill="#3E9B5C"/><path d="M296 300C330 288 372 316 368 356C348 392 306 420 284 416C290 376 270 332 296 300Z" fill="#3E9B5C"/><circle cx="232" cy="300" r="176" fill="none" stroke="#BDEBFF" stroke-width="5" opacity=".8"/>'
|
||||
leaf = '<path d="M254 244C310 148 410 118 500 130C486 222 410 306 290 298C340 268 382 220 402 170C350 196 300 232 254 244Z" fill="url(#leaf)"/>'
|
||||
orbit = text(556, 190, 'ORBIT', 56, '#E6F4EE', BARLOW, '600', 'letter-spacing="24"')
|
||||
word = text(530, 440, 'TERRA', 290, '#FFFFFF', BARLOW, '600', 'letter-spacing="14"')
|
||||
sweep = '<path d="M190 510C560 570 1020 560 1440 450C1120 590 560 620 190 510Z" fill="url(#leaf)"/>'
|
||||
parts = [('globe', defs + globe), ('orbit', defs + orbit), ('word', defs + word), ('accent', defs + leaf), ('sweep', defs + sweep)]
|
||||
small = f'<g transform="translate(-16,-14) scale(.32)">{globe}{leaf}</g>'
|
||||
epg = defs + small + text(150, 52, 'ORBIT', 20, '#E6F4EE', BARLOW, '600', 'letter-spacing="9"') + text(148, 124, 'TERRA', 76, '#FFFFFF', BARLOW, '600', 'letter-spacing="3"')
|
||||
bug = defs + f'<g transform="translate(-20,-22) scale(.32)">{globe}{leaf}</g>' + text(138, 92, 'TERRA', 74, '#FFFFFF', BARLOW, '600', 'stroke="#071632" stroke-width="2"')
|
||||
sky = '<defs>' + vgrad('dawn', (0, '#07142E'), (.45, '#1D5C9E'), (.75, '#7FC7E8'), (1, '#CFEFF2')) + '</defs><rect width="1920" height="1080" fill="url(#dawn)"/>'
|
||||
far = ('<polygon points="0,640 180,500 330,590 520,380 700,560 880,420 1120,600 1340,360 1560,560 1740,450 1920,600 1920,800 0,800" fill="#4B6A8E"/>'
|
||||
'<polygon points="520,380 700,560 610,800 450,800" fill="#3A5676"/><polygon points="1340,360 1560,560 1480,800 1270,800" fill="#3A5676"/><polygon points="880,420 1120,600 1020,800 840,800" fill="#3A5676"/>'
|
||||
'<polygon points="520,380 582,440 548,458 512,430 470,462 452,445" fill="#F2F8FB"/><polygon points="1340,360 1412,425 1372,448 1336,418 1296,455 1262,430" fill="#F2F8FB"/><polygon points="880,420 930,462 900,475 872,455 842,472" fill="#F2F8FB"/>')
|
||||
water = '<defs>' + vgrad('lake', (0, '#2BB3A8'), (1, '#0E6E7E')) + '</defs><rect y="700" width="1920" height="200" fill="url(#lake)"/>'
|
||||
rng = random.Random(17)
|
||||
def ridge(y, colour, step, height, seed):
|
||||
r = random.Random(seed)
|
||||
pts, x = [f'0,1080', f'0,{y}'], 0
|
||||
while x < 1920:
|
||||
pts.append(f'{x},{y - r.randint(0, height)}')
|
||||
x += r.randint(step // 2, step)
|
||||
return f'<polygon points="{" ".join(pts)} 1920,{y} 1920,1080" fill="{colour}"/>'
|
||||
mid = ridge(800, '#1C6B46', 110, 90, 3)
|
||||
forest = ridge(910, '#0F4D33', 80, 70, 5)
|
||||
trees = ''
|
||||
x = -10
|
||||
while x < 1940:
|
||||
h = rng.randint(70, 150)
|
||||
trees += f'<polygon points="{x},{1090 - rng.randint(0, 60)} {x + 34},{950 - h + 60} {x + 68},{1090}" fill="{rng.choice(["#0A3524", "#0C3E2A", "#082C1E"])}"/>'
|
||||
x += rng.randint(30, 58)
|
||||
earth = ('<defs>' + rgrad('earthglow', (.1, '#4FB7E0'), (.8, '#123E7E'), (1, '#07142E')) + '</defs><g transform="translate(1570,215) scale(.56) translate(-960,-300)"><circle cx="960" cy="300" r="230" fill="url(#earthglow)"/>'
|
||||
'<path d="M850 190C930 150 1010 180 1020 230C1026 280 950 270 930 310C912 350 950 410 900 430C840 380 810 280 850 190Z" fill="#3E9B5C"/><path d="M1060 300C1110 280 1170 320 1162 380C1134 430 1076 470 1044 462C1052 410 1024 350 1060 300Z" fill="#3E9B5C"/><circle cx="960" cy="300" r="230" fill="none" stroke="#BDEBFF" stroke-width="6" opacity=".8"/></g>')
|
||||
layers = [('sky', sky + stars(12, 40, '#FFFFFF', 300)), ('earth', earth), ('peaks', far), ('water', water), ('ridge', mid), ('forest', forest + trees)]
|
||||
return dict(id='orbit-terra', name='Terra', tag='Natural history and wildlife', palette=[('Ocean blue', '#07142E'), ('Forest green', '#1C6B46'), ('Turquoise', '#2BB3A8'), ('Leaf', '#9BE564'), ('Highlight', '#EAF8FF')],
|
||||
accent='#9BE564', parts=parts, epg=epg, bug=bug, layers=layers, background='#07142E', base=['sky', 'peaks', 'water', 'ridge', 'forest'],
|
||||
motion=[('earth', .5)], rise={'peaks': 60, 'water': 110, 'ridge': 170, 'forest': 260}, trail=([[120, 620], [1760, 300]], [[0, 0], [-500, 120]], [[520, 120], [0, 0]]),
|
||||
reveal=[('globe', 2.3, 'fade'), ('orbit', 2.42, 'fade'), ('word', 2.42, 'rise'), ('sweep', 2.55, 'fade'), ('accent', 2.75, 'pop')], note='The landscape rises past the camera in layers, revealing Earth, a green orbital line draws, then the logo appears and the leaf settles on the globe.')
|
||||
|
||||
|
||||
def dark_files():
|
||||
steel = vgrad('steel', (0, '#FFFFFF'), (.55, '#D7DEE9'), (1, '#8FA0B8'))
|
||||
red = vgrad('evred', (0, '#E3263F'), (1, '#A7132A'))
|
||||
defs = '<defs>' + SILVER + steel + red + '</defs>'
|
||||
mark = defs + crescent() + ring('#C8102E')
|
||||
orbit = text(510, 100, 'ORBIT', 50, '#D7DEE9', BARLOW, '600', 'letter-spacing="24"')
|
||||
dark = text(486, 326, 'DARK', 214, 'url(#steel)', ANTON, '400', 'letter-spacing="26"')
|
||||
files = text(486, 552, 'FILES', 214, 'url(#evred)', ANTON, '400', 'letter-spacing="16"')
|
||||
sweep = '<path d="M300 600C720 620 1040 600 1320 530" fill="none" stroke="#C8102E" stroke-width="7"/>'
|
||||
parts = [('crescent', mark), ('orbit', defs + orbit), ('word', defs + dark), ('accent', defs + files), ('sweep', sweep)]
|
||||
small = f'<g transform="translate(-5,1) scale(.26)">{crescent()}{ring("#C8102E")}</g>'
|
||||
epg = defs + small + text(136, 46, 'ORBIT', 18, '#D7DEE9', BARLOW, '600', 'letter-spacing="8"') + text(134, 116, 'DARK', 62, '#F2F5FA', ANTON, '400', 'letter-spacing="2"') + text(278, 116, 'FILES', 62, '#E3263F', ANTON, '400', 'letter-spacing="2"')
|
||||
bug = defs + f'<g transform="translate(-7,-8) scale(.22)">{crescent("#FFFFFF")}{ring("#E3263F")}</g>' + text(104, 68, 'DARK', 50, '#FFFFFF', ANTON, '400', 'letter-spacing="3" stroke="#071632" stroke-width="1.5"') + text(104, 122, 'FILES', 50, '#FF3A50', ANTON, '400', 'letter-spacing="3" stroke="#071632" stroke-width="1.5"')
|
||||
wall = '<defs>' + vgrad('wall', (0, '#050A18'), (.65, '#0D1A33'), (1, '#16233F')) + '</defs><rect width="1920" height="1080" fill="url(#wall)"/>'
|
||||
pane = '<rect x="140" y="110" width="620" height="440" fill="#0A1730" stroke="#1E2C4A" stroke-width="10"/><line x1="450" y1="110" x2="450" y2="550" stroke="#1E2C4A" stroke-width="10"/><line x1="140" y1="330" x2="760" y2="330" stroke="#1E2C4A" stroke-width="10"/><path d="M640 170C590 165 568 240 620 260C594 234 604 196 640 170Z" fill="#B7CBE8" opacity=".55"/>'
|
||||
city = f'<g transform="translate(140,280) scale(.323,.25)">{skyline(44, "#050A18", "#FFDE59", 200, 760)}</g>'
|
||||
desk = '<defs>' + vgrad('desk', (0, '#3A2C22'), (1, '#1C1510')) + '</defs><polygon points="0,700 1920,660 1920,1080 0,1080" fill="url(#desk)"/>'
|
||||
folder = ('<g transform="rotate(-4 900 860)"><path d="M560 700H780L820 738H1260V1040H560Z" fill="#B99C6B"/><rect x="580" y="750" width="680" height="300" fill="#D8BE8E"/>'
|
||||
+ text(700, 930, 'CASE FILE', 92, '#C8102E', ANTON, '400', 'letter-spacing="8" opacity=".85"') + '<rect x="680" y="842" width="440" height="106" fill="none" stroke="#C8102E" stroke-width="7" opacity=".85"/></g>')
|
||||
def photo(x, y, angle, inner):
|
||||
return f'<g transform="translate({x},{y}) rotate({angle})"><rect width="280" height="210" fill="#EFE9DC"/><rect x="14" y="14" width="252" height="164" fill="#0D1525"/>{inner}</g>'
|
||||
moon = '<circle cx="190" cy="60" r="20" fill="#B7CBE8"/><polygon points="14,178 80,90 140,140 200,70 266,178" fill="#050A18"/>'
|
||||
house = '<polygon points="70,178 70,110 130,70 190,110 190,178" fill="#050A18"/><rect x="110" y="120" width="26" height="26" fill="#FFDE59" opacity=".8"/>'
|
||||
prints = ''.join(f'<ellipse cx="140" cy="100" rx="{12 + i * 11}" ry="{16 + i * 13}" fill="none" stroke="#B7CBE8" stroke-width="3"/>' for i in range(6))
|
||||
photos = [('photo_1', photo(1180, 640, 7, moon)), ('photo_2', photo(1370, 780, -5, prints)), ('photo_3', photo(300, 700, -9, house))]
|
||||
glow = '<defs>' + rgrad('lampglow', (0, '#FFE5A6', .8), (.45, '#FFD27A', .34), (1, '#FFD27A', 0)) + '</defs><ellipse cx="1320" cy="760" rx="820" ry="420" fill="url(#lampglow)"/>'
|
||||
lamp = ('<path d="M1820 1080V560C1820 440 1700 330 1560 290" fill="none" stroke="#1E2433" stroke-width="20"/><path d="M1590 170C1490 190 1380 290 1350 420L1660 340C1650 270 1630 210 1590 170Z" fill="#2A3040"/><path d="M1350 420L1660 340C1640 372 1520 420 1350 420Z" fill="#FFE9B5"/>')
|
||||
layers = [('wall', wall + pane + city), ('desk', desk), ('lamp', lamp), ('glow', glow), ('folder', folder)] + photos
|
||||
return dict(id='orbit-dark-files', name='Dark Files', tag='True crime, mystery and paranormal non-fiction', palette=[('Night', '#070B1A'), ('Charcoal', '#1B2232'), ('Steel', '#7F96B4'), ('File beige', '#D8BE8E'), ('Evidence red', '#C8102E'), ('Ghost glow', '#CFE3FF')],
|
||||
accent='#C8102E', parts=parts, epg=epg, bug=bug, layers=layers, background='#070B1A', base=['wall', 'desk', 'lamp'],
|
||||
motion=[('glow', .3), ('folder', .75), ('photo_1', 1.2), ('photo_2', 1.4), ('photo_3', 1.6)], slide={'folder': 90, 'photo_1': 60, 'photo_2': 60, 'photo_3': 60}, trail=([[220, 900], [1500, 560]], [[0, 0], [-340, 170]], [[340, 130], [0, 0]]),
|
||||
reveal=[('crescent', 2.3, 'fade'), ('orbit', 2.42, 'fade'), ('word', 2.42, 'rise'), ('accent', 2.6, 'rise'), ('sweep', 2.72, 'fade')], note='A desk lamp warms up, the case folder and photographs arrive one at a time, a red line draws, then the logo appears.')
|
||||
|
||||
|
||||
def pixelz():
|
||||
defs = '<defs>' + SILVER + vgrad('pix', (0, '#BDF3FF'), (.5, '#37E5FF'), (1, '#1F7DFF')) + vgrad('zed', (0, '#E6FF4D'), (1, '#6EC800')) + '</defs>'
|
||||
mark = defs + crescent() + ring('#E03BFF')
|
||||
orbit = text(520, 160, 'ORBIT', 50, '#E8EDF5', BARLOW, '600', 'letter-spacing="24"')
|
||||
word = text(470, 420, 'Pixel', 236, '#123C9C', ROUND, '700', 'stroke="#123C9C" stroke-width="30" stroke-linejoin="round"') + text(470, 420, 'Pixel', 236, 'url(#pix)', ROUND, '700', 'stroke="url(#pix)" stroke-width="14" stroke-linejoin="round"')
|
||||
zed = '<path d="M1140 96H1530C1566 96 1578 136 1554 164L1340 396H1516C1560 396 1560 500 1516 500H1124C1086 500 1072 462 1098 432L1312 202H1140C1096 202 1096 96 1140 96Z" fill="url(#zed)" stroke="#2C7A00" stroke-width="8"/>'
|
||||
rng = random.Random(6)
|
||||
bits = ''.join(cube(x, y, s, t, l, r_) for x, y, s, t, l, r_ in [(1010, 44, 26, '#D5FF45', '#7BC400', '#99E000'), (1090, 16, 18, '#62EBFF', '#1F7DFF', '#37B8FF'), (1050, 100, 15, '#EE7BFF', '#9A2BD6', '#C04BF0')])
|
||||
parts = [('crescent', mark), ('orbit', defs + orbit), ('word', defs + word), ('accent', defs + zed), ('sweep', bits)]
|
||||
small = f'<g transform="translate(-5,1) scale(.26)">{crescent()}{ring("#E03BFF")}</g>'
|
||||
epg = defs + small + text(136, 50, 'ORBIT', 18, '#E8EDF5', BARLOW, '600', 'letter-spacing="8"') + text(130, 122, 'Pixel', 70, 'url(#pix)', ROUND, '700', 'stroke="url(#pix)" stroke-width="4"') + f'<g transform="translate(36,7) scale(.27)">{zed}</g>'
|
||||
bug = defs + f'<g transform="translate(-7,-8) scale(.22)">{crescent("#FFFFFF")}{ring("#E03BFF")}</g>' + text(104, 96, 'Pixel', 76, '#071632', ROUND, '700', 'stroke="#071632" stroke-width="9"') + text(104, 96, 'Pixel', 76, '#62EBFF', ROUND, '700', 'stroke="#62EBFF" stroke-width="3.5"') + f'<g transform="translate(-6,-6) scale(.25)">{zed}</g>'
|
||||
sky = '<defs>' + vgrad('pixsky', (0, '#0B0E3A'), (.55, '#3E1A9E'), (1, '#8A2BE2')) + '</defs><rect width="1920" height="1080" fill="url(#pixsky)"/>'
|
||||
floor = ''
|
||||
tones = [('#62EBFF', '#1F7DFF', '#37B8FF'), ('#D5FF45', '#7BC400', '#99E000'), ('#EE7BFF', '#9A2BD6', '#C04BF0'), ('#5B3AD0', '#26127A', '#3A1FA0')]
|
||||
cells = []
|
||||
for row in range(10):
|
||||
for col in range(-2, 18):
|
||||
cells.append((row, col))
|
||||
r = random.Random(14)
|
||||
for row, col in cells:
|
||||
s = 78
|
||||
x = col * s * 1.74 + (row % 2) * s * .87
|
||||
y = 690 + row * s * .5 + r.randint(-16, 16)
|
||||
t = r.choices(tones, [2, 1, 2, 6])[0]
|
||||
floor += cube(x, y, s, *t)
|
||||
float_cubes = []
|
||||
for i, (x, y, s, t) in enumerate([(240, 240, 76, 0), (470, 130, 44, 1), (1660, 210, 92, 2), (1420, 110, 42, 0), (1780, 470, 50, 1), (120, 520, 52, 2), (930, 90, 34, 1)]):
|
||||
float_cubes.append((f'cube_{i + 1}', cube(x, y, s, *tones[t])))
|
||||
layers = [('sky', sky + stars(61, 60)), ('floor', floor)] + float_cubes
|
||||
return dict(id='orbit-pixelz', name='PixelZ', tag='CGI family films', palette=[('Electric cyan', '#37E5FF'), ('Lime', '#B7FF2E'), ('Bright purple', '#8B3BFF'), ('Night', '#0B0E3A')],
|
||||
accent='#B7FF2E', parts=parts, epg=epg, bug=bug, layers=layers, background='#0B0E3A', base=['sky', 'floor'],
|
||||
motion=[(name, .3 + i * .16) for i, (name, _) in enumerate(float_cubes)], drop={name for name, _ in float_cubes}, trail=([[140, 700], [1500, 470]], [[0, 0], [-360, 170]], [[360, 120], [0, 0]]),
|
||||
reveal=[('crescent', 2.2, 'fade'), ('orbit', 2.3, 'fade'), ('word', 2.34, 'rise'), ('sweep', 2.5, 'pop'), ('accent', 2.62, 'bounce')], note='Bright cubes drop in one at a time, a magenta line draws, the word forms, then the oversized lime Z bounces into place.')
|
||||
|
||||
|
||||
CHANNELS = {'ring-x': ring_x, 'riot': riot, 'odyssey': odyssey, 'terra': terra, 'dark-files': dark_files, 'pixelz': pixelz}
|
||||
|
||||
|
||||
def vc(src, dst, *options):
|
||||
subprocess.run(['vectorcraft-cli', 'convert', str(src), str(dst), *options], env=ENV, check=True, stdout=subprocess.DEVNULL)
|
||||
|
||||
|
||||
def review_board(c, primary, epg, bug, background):
|
||||
clip = '<defs><clipPath id="hero"><rect width="1920" height="1080"/></clipPath></defs>'
|
||||
background = f'{clip}<g clip-path="url(#hero)">{background}</g>'
|
||||
board = f'<rect width="1920" height="1440" fill="{NAVY}"/>' + text(70, 75, f'Orbit {c["name"]}', 32, 'white', BARLOW, '600') + text(70, 113, f'Branding proof 01 / {c["tag"]}', 20, MUTED)
|
||||
board += f'<g transform="translate(60,130) scale(.68)">{primary}</g>'
|
||||
board += text(1180, 170, 'Hero background', 22, MUTED) + f'<g transform="translate(1180,190) scale(.34)">{background}</g>'
|
||||
board += f'<path d="M70 590H1850" stroke="{BLUE}"/>' + text(70, 636, 'Compact EPG', 22, MUTED) + f'<rect x="70" y="660" width="720" height="200" fill="{PANEL}"/><g transform="translate(100,680)">{epg}</g>'
|
||||
board += text(870, 636, 'Playback bug, transparent', 22, MUTED) + f'<g transform="translate(900,700)">{bug}</g>'
|
||||
board += text(70, 915, 'Playback bug at 1080p size, over the hero background', 22, MUTED)
|
||||
board += f'<g transform="translate(70,940)"><g transform="scale(.46)">{background}</g><g transform="translate(40,420) scale(.375)" opacity=".85">{bug}</g></g>'
|
||||
x = 1000
|
||||
board += text(x, 915, 'Palette', 22, MUTED)
|
||||
for i, (label, colour) in enumerate(c['palette']):
|
||||
board += f'<rect x="{x + (i % 3) * 280}" y="{940 + (i // 3) * 130}" width="250" height="70" fill="{colour}" stroke="{BLUE}"/>' + text(x + (i % 3) * 280, 1035 + (i // 3) * 130, f'{label} {colour}', 20, MUTED)
|
||||
board += text(x, 1250, 'Original artwork, redrawn from the concept board.', 22, 'white') + text(x, 1285, 'Navy interface and yellow remote focus stay. No concept pixels used.', 22, MUTED)
|
||||
return svg(1920, 1440, board)
|
||||
|
||||
|
||||
def build_static(key):
|
||||
c = CHANNELS[key]()
|
||||
d = HERE / c['id']
|
||||
s, e, r = d / 'sources', d / 'exports', d / 'review'
|
||||
for folder in (s, e, r):
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
primary = ''.join(body for _, body in c['parts'])
|
||||
stem = c['id'].replace('-', '_')
|
||||
(s / f'{stem}_primary.svg').write_text(svg(1600, 640, primary))
|
||||
(s / f'{stem}_epg.svg').write_text(svg(512, 160, c['epg']))
|
||||
(s / f'{stem}_bug.svg').write_text(svg(384, 128, c['bug']))
|
||||
for name in ('primary', 'epg', 'bug'):
|
||||
src = s / f'{stem}_{name}.svg'
|
||||
vc(src, s / f'{stem}_{name}.vectorcraft')
|
||||
vc(src, e / f'{stem}_{name}.png')
|
||||
vc(src, e / f'{stem}_{name}.svg', '--outline-text')
|
||||
Image.open(e / f'{stem}_epg.png').convert('RGBA').resize((256, 80), Image.LANCZOS).save(e / f'{stem}_epg_app.webp', quality=90)
|
||||
Image.open(e / f'{stem}_bug.png').convert('RGBA').resize((144, 48), Image.LANCZOS).save(e / f'{stem}_bug_app.webp', quality=90)
|
||||
for name, body in c['parts']:
|
||||
part = s / f'logo_{name}.svg'
|
||||
part.write_text(svg(1600, 640, body))
|
||||
vc(part, e / f'logo_{name}.png')
|
||||
background = ''
|
||||
for name, body in c['layers']:
|
||||
background += body
|
||||
layer = s / f'bg_{name}.svg'
|
||||
layer.write_text(svg(1920, 1080, body))
|
||||
vc(layer, e / f'bg_{name}.png')
|
||||
(s / f'{stem}_background.svg').write_text(svg(1920, 1080, background))
|
||||
first, *rest = [n for n, _ in c['layers']]
|
||||
cmd = ['photocraft-cli', 'run', str(e / f'bg_{first}.png')]
|
||||
for name in rest:
|
||||
cmd += ['--cmd', 'file.placeEmbedded', '--params', json.dumps({'path': str(e / f'bg_{name}.png'), 'fit': False, 'center': [960, 540]})]
|
||||
pcraft = s / f'{stem}_background.pcraft'
|
||||
subprocess.run(cmd + ['--out', str(pcraft)], check=True, stdout=subprocess.DEVNULL)
|
||||
subprocess.run(['photocraft-cli', 'convert', str(pcraft), str(e / f'{stem}_background.webp'), '--quality', '85'], check=True, stdout=subprocess.DEVNULL)
|
||||
board = s / f'{stem}_review.svg'
|
||||
board.write_text(review_board(c, primary, c['epg'], c['bug'], background))
|
||||
subprocess.run(['figcraft-cli', 'convert', str(board), str(r / f'{stem}_review.figcraft')], env=ENV, check=True, stdout=subprocess.DEVNULL)
|
||||
subprocess.run(['figcraft-cli', 'export', str(r / f'{stem}_review.figcraft'), '--out', str(r / f'{stem}_review.png')], env=ENV, check=True, stdout=subprocess.DEVNULL)
|
||||
return c, d, stem
|
||||
|
||||
|
||||
def build_ident(c, d, stem):
|
||||
s, e, r = d / 'sources', d / 'exports', d / 'review'
|
||||
end = 4.2
|
||||
steps = [{'command': 'comp.new', 'params': {'name': f'{c["name"]} ident', 'width': 1280, 'height': 720, 'frameRate': 25, 'duration': end, 'background': c['background']}}]
|
||||
|
||||
def cmd(command, **params):
|
||||
steps.append({'command': command, 'params': params})
|
||||
|
||||
def key(layer, path, t, v):
|
||||
cmd('prop.addKey', layer=layer, path=path, time=round(t, 3), value=v)
|
||||
|
||||
def load(path, name, scale):
|
||||
cmd('file.import', paths=[str(path)], addToComp=True)
|
||||
cmd('layer.rename', layer='#1', name=name)
|
||||
cmd('prop.set', layer=name, path='transform/scale', value=[scale, scale, 100])
|
||||
|
||||
motion = dict(c['motion'])
|
||||
for name, _ in c['layers']:
|
||||
layer = f'Background {name}'
|
||||
load(e / f'bg_{name}.png', layer, 66.6667)
|
||||
if name in motion:
|
||||
t = motion[name]
|
||||
# Every entrance ramps over at least 0.35 s, so nothing flashes.
|
||||
for at, v in [(0, 0), (t, 0), (t + .4, 100)]:
|
||||
key(layer, 'transform/opacity', at, v)
|
||||
if name in c.get('pop', ()):
|
||||
for at, v in [(t, [40, 40, 100]), (t + .22, [71, 71, 100]), (t + .36, [66.67, 66.67, 100])]:
|
||||
key(layer, 'transform/scale', at, v)
|
||||
if name in c.get('slide', {}):
|
||||
offset = c['slide'][name] * 2 / 3
|
||||
for at, v in [(t, [640, 360 + offset, 0]), (t + .4, [640, 360, 0])]:
|
||||
key(layer, 'transform/position', at, v)
|
||||
if name in c.get('drop', ()):
|
||||
for at, v in [(t, [640, 240, 0]), (t + .34, [640, 372, 0]), (t + .46, [640, 360, 0])]:
|
||||
key(layer, 'transform/position', at, v)
|
||||
if name in c.get('rise', {}):
|
||||
offset = c['rise'][name] * 2 / 3
|
||||
for at, v in [(0, [640, 360 + offset, 0]), (1.5, [640, 360, 0])]:
|
||||
key(layer, 'transform/position', at, v)
|
||||
vertices, tangents_in, tangents_out = c['trail']
|
||||
scaled = lambda points: [[round(v * 2 / 3, 1) for v in p] for p in points]
|
||||
path = {'t': 'Path', 'v': {'vertices': scaled(vertices), 'in_tangents': scaled(tangents_in), 'out_tangents': scaled(tangents_out), 'closed': False}}
|
||||
rgb = [int(c['accent'][i:i + 2], 16) / 255 for i in (1, 3, 5)]
|
||||
for name, width, opacity in [('Orbital trail glow', 10, 16), ('Orbital trail', 3, 100)]:
|
||||
cmd('layer.newShape', kind='none', name=name)
|
||||
for kind in ('path', 'stroke', 'trim'):
|
||||
cmd('layer.addShapeItem', layer=name, kind=kind)
|
||||
for prop, value in [('transform/position', [0, 0, 0]), ('contents/path/path', path), ('contents/stroke/color', rgb + [1]), ('contents/stroke/width', width), ('contents/stroke/opacity', opacity), ('contents/stroke/cap', 1)]:
|
||||
cmd('prop.set', layer=name, path=prop, value=value)
|
||||
key(name, 'contents/trim/end', 0, 0)
|
||||
key(name, 'contents/trim/end', 1.3, 0)
|
||||
key(name, 'contents/trim/end', 2.3, 100)
|
||||
# The line hands over to the logo's own sweep, so it never crosses the finished lettering.
|
||||
for t, v in [(0, 100), (2.3, 100), (2.8, 0)]:
|
||||
key(name, 'transform/opacity', t, v)
|
||||
if c.get('scrim', True):
|
||||
scrim = s / 'logo_scrim.svg'
|
||||
scrim.write_text(svg(1920, 1080, f'<defs>{rgrad("scrim", (0, c["background"], .82), (.62, c["background"], .62), (1, c["background"], 0))}</defs><ellipse cx="960" cy="500" rx="880" ry="380" fill="url(#scrim)"/>'))
|
||||
vc(scrim, e / 'logo_scrim.png')
|
||||
load(e / 'logo_scrim.png', 'Logo scrim', 66.6667)
|
||||
for t, v in [(0, 0), (2.2, 0), (2.7, 100), (3.95, 100), (end, 0)]:
|
||||
key('Logo scrim', 'transform/opacity', t, v)
|
||||
scale, centre = 62, [640, 330, 0]
|
||||
for name, t, style in c['reveal']:
|
||||
layer = f'Logo {name}'
|
||||
load(e / f'logo_{name}.png', layer, scale)
|
||||
cmd('prop.set', layer=layer, path='transform/position', value=centre)
|
||||
for at, v in [(0, 0), (t, 0), (t + .3, 100), (3.95, 100), (end, 0)]:
|
||||
key(layer, 'transform/opacity', at, v)
|
||||
if style == 'rise':
|
||||
for at, v in [(t, [640, 348, 0]), (t + .36, centre)]:
|
||||
key(layer, 'transform/position', at, v)
|
||||
elif style == 'slam':
|
||||
for at, v in [(t, [scale * 1.28, scale * 1.28, 100]), (t + .2, [scale * .98, scale * .98, 100]), (t + .32, [scale, scale, 100])]:
|
||||
key(layer, 'transform/scale', at, v)
|
||||
elif style == 'pop':
|
||||
for at, v in [(t, [scale * .8, scale * .8, 100]), (t + .24, [scale * 1.02, scale * 1.02, 100]), (t + .34, [scale, scale, 100])]:
|
||||
key(layer, 'transform/scale', at, v)
|
||||
elif style == 'bounce':
|
||||
for at, v in [(t, [640, 170, 0]), (t + .24, [640, 342, 0]), (t + .36, [640, 306, 0]), (t + .48, centre)]:
|
||||
key(layer, 'transform/position', at, v)
|
||||
commands = s / 'build-ident.json'
|
||||
commands.write_text(json.dumps(steps, indent=1))
|
||||
project = s / f'{stem}_ident.ecproj'
|
||||
subprocess.run(['effectcraft-cli', '--empty', 'run', '--commands', str(commands), '--save-as', str(project), '--json'], check=True, stdout=subprocess.DEVNULL)
|
||||
collected = s / 'ident-project'
|
||||
if collected.exists():
|
||||
shutil.rmtree(collected)
|
||||
subprocess.run(['effectcraft-cli', '--project', str(project), 'exec', 'file.collectFiles', '--params', json.dumps({'folder': str(collected)}), '--json'], check=True, stdout=subprocess.DEVNULL)
|
||||
subprocess.run(['effectcraft-cli', '--project', str(project), 'render', '--out', str(e / f'{stem}_ident.mp4'), '--format', 'h264', '--fps', '25', '--bitrate', '3500', '--audio', 'off'], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(['ffmpeg', '-y', '-v', 'error', '-i', str(e / f'{stem}_ident.mp4'), '-vf', 'select=not(mod(n\\,14)),scale=480:-1,tile=4x2', '-frames:v', '1', str(r / f'{stem}_ident_sheet.png')], check=True)
|
||||
|
||||
|
||||
def flash_check(video):
|
||||
"""A rough screen for flashing, not a formal photosensitivity test: counts large brightness swings."""
|
||||
w, h = 64, 36
|
||||
raw = subprocess.run(['ffmpeg', '-v', 'error', '-i', str(video), '-vf', f'scale={w}:{h},format=gray', '-f', 'rawvideo', '-'], check=True, capture_output=True).stdout
|
||||
frames = [raw[i:i + w * h] for i in range(0, len(raw), w * h)]
|
||||
means = [sum(f) / len(f) / 255 for f in frames]
|
||||
deltas = [b - a for a, b in zip(means, means[1:])]
|
||||
swings = [d for d in deltas if abs(d) >= .1]
|
||||
reversals = sum(1 for a, b in zip(swings, swings[1:]) if a * b < 0)
|
||||
return dict(frames=len(frames), largestFrameChange=round(max(abs(d) for d in deltas), 4), framesChangingOver10Percent=len(swings), brightnessReversals=reversals)
|
||||
|
||||
|
||||
def document(c, d, stem, static):
|
||||
s, e = d / 'sources', d / 'exports'
|
||||
report = dict(status='design-proof-not-integrated')
|
||||
for name in ('primary', 'epg', 'bug'):
|
||||
alpha = Image.open(e / f'{stem}_{name}.png').convert('RGBA').getchannel('A').getextrema()
|
||||
info = json.loads(subprocess.check_output(['vectorcraft-cli', 'info', str(s / f'{stem}_{name}.vectorcraft')], env=ENV, text=True))
|
||||
missing = [f for f in info.get('fonts', []) if f.get('missing')]
|
||||
assert alpha == (0, 255) and not missing, (name, alpha, missing)
|
||||
report[name] = dict(alpha=list(alpha), fonts=[f.get('family') or f.get('name') for f in info.get('fonts', [])])
|
||||
layers = json.loads(subprocess.check_output(['photocraft-cli', 'info', str(s / f'{stem}_background.pcraft')], text=True))['layers']
|
||||
assert len(layers) == len(c['layers'])
|
||||
report['photoCraftLayers'] = len(layers)
|
||||
report['fileSizes'] = {p.name: p.stat().st_size for p in [e / f'{stem}_epg_app.webp', e / f'{stem}_bug_app.webp', e / f'{stem}_background.webp']}
|
||||
if not static:
|
||||
video = e / f'{stem}_ident.mp4'
|
||||
report['ident'] = flash_check(video)
|
||||
report['fileSizes'][video.name] = video.stat().st_size
|
||||
collected = s / 'ident-project' / f'{stem}_ident.ecproj'
|
||||
subprocess.run(['effectcraft-cli', '--project', str(collected), 'render-frame', '--time', '3.4', '--out', str(d / 'review' / f'{stem}_portable_ident_check.png')], check=True, stdout=subprocess.DEVNULL)
|
||||
report['collectedProjectRendered'] = True
|
||||
(d / 'verification.json').write_text(json.dumps(report, indent=2))
|
||||
manifest = dict(status='design-proof-not-integrated', presetId=c['id'], displayName=f'Orbit {c["name"]}', channelNumber=None,
|
||||
networkTokens=dict(background=NAVY, panel=PANEL, navigation=BLUE, focus=FOCUS, muted=MUTED, text='#FFFFFF'),
|
||||
palette=dict((label, colour) for label, colour in c['palette']),
|
||||
assets=dict(primary=f'exports/{stem}_primary.svg', epg=f'exports/{stem}_epg_app.webp', bug=f'exports/{stem}_bug_app.webp', background=f'exports/{stem}_background.webp', ident=f'exports/{stem}_ident.mp4'),
|
||||
proposedOverlay=dict(default='off', anchor='bottom-left', widthAt1080p=144, heightAt1080p=48, safeInsetPercent=5, opacity=.8, hideForProgrammeStrip=True, hideForSubtitles=True),
|
||||
ident=dict(durationSeconds=4.2, fps=25, width=1280, height=720, codec='h264', audio=False, alpha=False, schedulePolicy='optional; never delays scheduled media; a longer ident needs an explicit scheduled slot'))
|
||||
(d / 'branding-manifest.json').write_text(json.dumps(manifest, indent=2))
|
||||
(d / 'README.md').write_text(f"""# Orbit {c['name']} — branding proof 01
|
||||
|
||||
{c['tag']}. Original artwork, redrawn from Paul's concept board. The board is direction only: no pixels are copied from it, and it's kept in `design/references`.
|
||||
|
||||
## Ident
|
||||
|
||||
{c['note']} 4.2 seconds, silent H.264, 1280x720, 25 fps. It isn't in the app and can't delay a programme.
|
||||
|
||||
## Files
|
||||
|
||||
- `review/{stem}_review.png`: logo, EPG, bug, background and palette. Editable as `.figcraft`.
|
||||
- `review/{stem}_ident_sheet.png`: frames through the ident.
|
||||
- `exports/`: transparent logos (PNG, outlined SVG), app-sized `_epg_app.webp` (256x80) and `_bug_app.webp` (144x48), background WebP, ident MP4, and the separate layers the ident uses.
|
||||
- `sources/`: VectorCraft logo files with live text, layered PhotoCraft background, source SVGs, and `ident-project/` holding the self-contained EffectCraft project.
|
||||
|
||||
`../build-network-brands.py` rebuilds all of this. Fonts are in `../network-fonts`, with licences in the project's `licenses/` folder.
|
||||
|
||||
## Status
|
||||
|
||||
A design proof for review, not integrated. Android drawing, the bug's visibility over real programmes, subtitle behaviour and any ident timing still need testing on the box. `verification.json` records the checks; its brightness figures are a rough screen, not a formal photosensitivity test.
|
||||
""")
|
||||
|
||||
|
||||
def network_sheet():
|
||||
tiles = []
|
||||
for key in CHANNELS:
|
||||
c = CHANNELS[key]()
|
||||
stem = c['id'].replace('-', '_')
|
||||
d = HERE / c['id']
|
||||
frame = d / 'review' / f'{stem}_portable_ident_check.png'
|
||||
tiles.append(Image.open(frame).convert('RGB').resize((960, 540), Image.LANCZOS))
|
||||
sheet = Image.new('RGB', (1920 + 20, 540 * 3 + 40), NAVY)
|
||||
for i, tile in enumerate(tiles):
|
||||
sheet.paste(tile, ((i % 2) * 980, (i // 2) * 560))
|
||||
sheet.save(HERE / 'network-review.png')
|
||||
|
||||
|
||||
def main():
|
||||
args = [a for a in sys.argv[1:] if not a.startswith('--')]
|
||||
static = '--static' in sys.argv
|
||||
for key in args or CHANNELS:
|
||||
c, d, stem = build_static(key)
|
||||
if not static:
|
||||
build_ident(c, d, stem)
|
||||
document(c, d, stem, static)
|
||||
print('built', c['id'], flush=True)
|
||||
if not static and not args:
|
||||
network_sheet()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,20 @@
|
||||
# Orbit Dark Files — branding proof 01
|
||||
|
||||
True crime, mystery and paranormal non-fiction. Original artwork, redrawn from Paul's concept board. The board is direction only: no pixels are copied from it, and it's kept in `design/references`.
|
||||
|
||||
## Ident
|
||||
|
||||
A desk lamp warms up, the case folder and photographs arrive one at a time, a red line draws, then the logo appears. 4.2 seconds, silent H.264, 1280x720, 25 fps. It isn't in the app and can't delay a programme.
|
||||
|
||||
## Files
|
||||
|
||||
- `review/orbit_dark_files_review.png`: logo, EPG, bug, background and palette. Editable as `.figcraft`.
|
||||
- `review/orbit_dark_files_ident_sheet.png`: frames through the ident.
|
||||
- `exports/`: transparent logos (PNG, outlined SVG), app-sized `_epg_app.webp` (256x80) and `_bug_app.webp` (144x48), background WebP, ident MP4, and the separate layers the ident uses.
|
||||
- `sources/`: VectorCraft logo files with live text, layered PhotoCraft background, source SVGs, and `ident-project/` holding the self-contained EffectCraft project.
|
||||
|
||||
`../build-network-brands.py` rebuilds all of this. Fonts are in `../network-fonts`, with licences in the project's `licenses/` folder.
|
||||
|
||||
## Status
|
||||
|
||||
A design proof for review, not integrated. Android drawing, the bug's visibility over real programmes, subtitle behaviour and any ident timing still need testing on the box. `verification.json` records the checks; its brightness figures are a rough screen, not a formal photosensitivity test.
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"status": "design-proof-not-integrated",
|
||||
"presetId": "orbit-dark-files",
|
||||
"displayName": "Orbit Dark Files",
|
||||
"channelNumber": null,
|
||||
"networkTokens": {
|
||||
"background": "#071632",
|
||||
"panel": "#12356B",
|
||||
"navigation": "#194C91",
|
||||
"focus": "#FFDE59",
|
||||
"muted": "#B7CBE8",
|
||||
"text": "#FFFFFF"
|
||||
},
|
||||
"palette": {
|
||||
"Night": "#070B1A",
|
||||
"Charcoal": "#1B2232",
|
||||
"Steel": "#7F96B4",
|
||||
"File beige": "#D8BE8E",
|
||||
"Evidence red": "#C8102E",
|
||||
"Ghost glow": "#CFE3FF"
|
||||
},
|
||||
"assets": {
|
||||
"primary": "exports/orbit_dark_files_primary.svg",
|
||||
"epg": "exports/orbit_dark_files_epg_app.webp",
|
||||
"bug": "exports/orbit_dark_files_bug_app.webp",
|
||||
"background": "exports/orbit_dark_files_background.webp",
|
||||
"ident": "exports/orbit_dark_files_ident.mp4"
|
||||
},
|
||||
"proposedOverlay": {
|
||||
"default": "off",
|
||||
"anchor": "bottom-left",
|
||||
"widthAt1080p": 144,
|
||||
"heightAt1080p": 48,
|
||||
"safeInsetPercent": 5,
|
||||
"opacity": 0.8,
|
||||
"hideForProgrammeStrip": true,
|
||||
"hideForSubtitles": true
|
||||
},
|
||||
"ident": {
|
||||
"durationSeconds": 4.2,
|
||||
"fps": 25,
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"codec": "h264",
|
||||
"audio": false,
|
||||
"alpha": false,
|
||||
"schedulePolicy": "optional; never delays scheduled media; a longer ident needs an explicit scheduled slot"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="384" height="128" viewBox="0 0 384 128">
|
||||
<title>orbit_dark_files_bug.svg</title>
|
||||
<g id="Layer_1" data-name="Layer 1">
|
||||
<g>
|
||||
<path d="M66.7 21.04 C24.02 17.08 7.52 76.48 49.54 96.5 C24.46 71.86 33.7 37.54 66.7 21.04 Z" fill="#ffffff"/>
|
||||
<path d="M21.38 73.18 C15.44 79.78 17.42 85.5 28.42 86.16 C51.74 87.04 87.82 66.8 90.9 55.58 C93.1 47 82.1 47 74.18 49.42" fill="none" stroke="#e3263f" stroke-width="2.42"/>
|
||||
<circle cx="87.6" cy="54.04" r="1.98" fill="#e3263f"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M105.904 68 L105.904 25.031 L117.721 25.031 C120.813 25.031 123.141 25.89 124.703 27.607 C126.266 29.324 127.047 31.835 127.047 35.139 L127.047 55.256 C127.047 59.325 126.335 62.466 124.911 64.68 C123.486 66.893 120.992 68 117.428 68 Z M114.547 60.407 L116.036 60.407 C117.615 60.407 118.404 59.642 118.404 58.112 L118.404 35.944 C118.404 34.512 118.213 33.588 117.831 33.173 C117.448 32.758 116.671 32.551 115.499 32.551 L114.547 32.551 Z M132.391 68 L136.541 25.031 L151.116 25.031 L155.193 68 L147.063 68 L146.453 61.066 L141.277 61.066 L140.74 68 Z M141.888 54.206 L145.794 54.206 L143.914 32.355 L143.523 32.355 Z M160.83 68 L160.83 25.031 L174.014 25.031 C176.211 25.031 177.871 25.532 178.994 26.533 C180.117 27.534 180.87 28.933 181.252 30.732 C181.635 32.53 181.826 34.642 181.826 37.067 C181.826 39.411 181.529 41.283 180.935 42.683 C180.341 44.082 179.222 45.051 177.578 45.588 C178.929 45.865 179.877 46.536 180.422 47.602 C180.968 48.668 181.24 50.048 181.24 51.74 L181.24 68 L172.769 68 L172.769 51.179 C172.769 49.925 172.512 49.148 172 48.847 C171.487 48.546 170.661 48.396 169.521 48.396 L169.521 68 Z M169.57 40.949 L171.646 40.949 C172.834 40.949 173.428 39.655 173.428 37.067 C173.428 35.391 173.298 34.292 173.037 33.771 C172.777 33.251 172.288 32.99 171.572 32.99 L169.57 32.99 Z M187.658 68 L187.658 25.031 L196.154 25.031 L196.154 42.243 L200.158 25.031 L208.801 25.031 L203.991 44.709 L209.802 68 L200.891 68 L196.203 47.199 L196.203 68 Z" fill="#ffffff" stroke="#071632" stroke-width="1.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M105.904 122 L105.904 79.031 L123.092 79.031 L123.092 87.405 L114.547 87.405 L114.547 94.241 L122.652 94.241 L122.652 102.518 L114.547 102.518 L114.547 122 Z M128.46 122 L128.46 79.031 L136.761 79.031 L136.761 122 Z M143.179 122 L143.179 79.031 L151.772 79.031 L151.772 114.676 L160.61 114.676 L160.61 122 Z M166.052 122 L166.052 79.031 L183.239 79.031 L183.239 87.332 L174.792 87.332 L174.792 95.706 L182.897 95.706 L182.897 103.787 L174.792 103.787 L174.792 113.626 L183.801 113.626 L183.801 122 Z M199.838 122.391 C195.915 122.391 193.087 121.414 191.354 119.461 C189.621 117.508 188.754 114.399 188.754 110.135 L188.754 105.936 L197.25 105.936 L197.25 111.307 C197.25 112.299 197.401 113.077 197.702 113.638 C198.003 114.2 198.528 114.48 199.276 114.48 C200.058 114.48 200.599 114.253 200.9 113.797 C201.201 113.341 201.352 112.592 201.352 111.551 C201.352 110.232 201.221 109.13 200.961 108.243 C200.701 107.356 200.249 106.509 199.606 105.704 C198.963 104.898 198.072 103.958 196.933 102.884 L193.075 99.222 C190.194 96.504 188.754 93.395 188.754 89.896 C188.754 86.233 189.604 83.442 191.305 81.521 C193.006 79.601 195.468 78.641 198.69 78.641 C202.629 78.641 205.425 79.69 207.077 81.79 C208.729 83.89 209.555 87.08 209.555 91.36 L200.814 91.36 L200.814 88.406 C200.814 87.82 200.648 87.365 200.314 87.039 C199.98 86.714 199.529 86.551 198.959 86.551 C198.275 86.551 197.775 86.742 197.458 87.125 C197.14 87.507 196.981 87.999 196.981 88.602 C196.981 89.204 197.144 89.855 197.47 90.555 C197.795 91.255 198.438 92.06 199.398 92.972 L204.354 97.732 C205.347 98.676 206.259 99.673 207.089 100.723 C207.919 101.773 208.586 102.994 209.091 104.385 C209.595 105.777 209.848 107.474 209.848 109.476 C209.848 113.512 209.103 116.674 207.614 118.96 C206.125 121.247 203.533 122.391 199.838 122.391 Z" fill="#ff3a50" stroke="#071632" stroke-width="1.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="160" viewBox="0 0 512 160">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient-1" x1="32.976" y1="35.097" x2="32.976" y2="124.5" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ffffff"/>
|
||||
<stop offset="0.44" stop-color="#e8edf5"/>
|
||||
<stop offset="0.5" stop-color="#b7cbe8"/>
|
||||
<stop offset="1" stop-color="#f5f7ff"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<title>orbit_dark_files_epg.svg</title>
|
||||
<g id="Layer_1" data-name="Layer 1">
|
||||
<g>
|
||||
<path d="M82.1 35.32 C31.66 30.64 12.16 100.84 61.82 124.5 C32.18 95.38 43.1 54.82 82.1 35.32 Z" fill="url(#linear-gradient-1)"/>
|
||||
<path d="M28.54 96.94 C21.52 104.74 23.86 111.5 36.86 112.28 C64.42 113.32 107.06 89.4 110.7 76.14 C113.3 66 100.3 66 90.94 68.86" fill="none" stroke="#c8102e" stroke-width="2.86"/>
|
||||
<circle cx="106.8" cy="74.32" r="2.34" fill="#c8102e"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M141.58 46.18 C140.68 46.18 139.882 45.997 139.186 45.631 C138.49 45.265 137.953 44.746 137.575 44.074 C137.197 43.402 137.008 42.628 137.008 41.752 L137.008 37.648 C137.008 36.784 137.2 36.019 137.584 35.353 C137.968 34.687 138.505 34.171 139.195 33.805 C139.885 33.439 140.68 33.256 141.58 33.256 C142.492 33.256 143.293 33.439 143.983 33.805 C144.673 34.171 145.21 34.687 145.594 35.353 C145.978 36.019 146.17 36.784 146.17 37.648 L146.17 41.752 C146.17 42.628 145.978 43.402 145.594 44.074 C145.21 44.746 144.673 45.265 143.983 45.631 C143.293 45.997 142.492 46.18 141.58 46.18 Z M141.58 44.38 C142.336 44.38 142.942 44.146 143.398 43.678 C143.854 43.21 144.082 42.592 144.082 41.824 L144.082 37.63 C144.082 36.85 143.854 36.226 143.398 35.758 C142.942 35.29 142.336 35.056 141.58 35.056 C140.836 35.056 140.236 35.29 139.78 35.758 C139.324 36.226 139.096 36.85 139.096 37.63 L139.096 41.824 C139.096 42.592 139.324 43.21 139.78 43.678 C140.236 44.146 140.836 44.38 141.58 44.38 Z M163.566 46 C163.446 46 163.362 45.946 163.314 45.838 L160.938 40.654 C160.914 40.606 160.878 40.582 160.83 40.582 L158.67 40.582 C158.61 40.582 158.58 40.612 158.58 40.672 L158.58 45.784 C158.58 45.844 158.559 45.895 158.517 45.937 C158.475 45.979 158.424 46 158.364 46 L156.708 46 C156.648 46 156.597 45.979 156.555 45.937 C156.513 45.895 156.492 45.844 156.492 45.784 L156.492 33.616 C156.492 33.556 156.513 33.505 156.555 33.463 C156.597 33.421 156.648 33.4 156.708 33.4 L161.658 33.4 C162.39 33.4 163.038 33.553 163.602 33.859 C164.166 34.165 164.604 34.597 164.916 35.155 C165.228 35.713 165.384 36.352 165.384 37.072 C165.384 37.9 165.171 38.605 164.745 39.187 C164.319 39.769 163.728 40.174 162.972 40.402 C162.948 40.402 162.93 40.414 162.918 40.438 C162.906 40.462 162.906 40.486 162.918 40.51 L165.456 45.748 C165.48 45.796 165.492 45.832 165.492 45.856 C165.492 45.952 165.426 46 165.294 46 Z M158.67 35.2 C158.61 35.2 158.58 35.23 158.58 35.29 L158.58 38.872 C158.58 38.932 158.61 38.962 158.67 38.962 L161.37 38.962 C161.946 38.962 162.411 38.791 162.765 38.449 C163.119 38.107 163.296 37.654 163.296 37.09 C163.296 36.526 163.119 36.07 162.765 35.722 C162.411 35.374 161.946 35.2 161.37 35.2 Z M182.564 39.43 C182.492 39.466 182.492 39.502 182.564 39.538 C183.788 40.114 184.4 41.104 184.4 42.508 C184.4 43.648 184.019 44.515 183.257 45.109 C182.495 45.703 181.502 46 180.278 46 L175.742 46 C175.682 46 175.631 45.979 175.589 45.937 C175.547 45.895 175.526 45.844 175.526 45.784 L175.526 33.616 C175.526 33.556 175.547 33.505 175.589 33.463 C175.631 33.421 175.682 33.4 175.742 33.4 L180.134 33.4 C181.442 33.4 182.45 33.682 183.158 34.246 C183.866 34.81 184.22 35.662 184.22 36.802 C184.22 38.062 183.668 38.938 182.564 39.43 Z M177.704 35.2 C177.644 35.2 177.614 35.23 177.614 35.29 L177.614 38.62 C177.614 38.68 177.644 38.71 177.704 38.71 L180.134 38.71 C180.77 38.71 181.271 38.557 181.637 38.251 C182.003 37.945 182.186 37.522 182.186 36.982 C182.186 36.43 182.003 35.995 181.637 35.677 C181.271 35.359 180.77 35.2 180.134 35.2 Z M180.278 44.182 C180.902 44.182 181.397 44.014 181.763 43.678 C182.129 43.342 182.312 42.886 182.312 42.31 C182.312 41.722 182.126 41.263 181.754 40.933 C181.382 40.603 180.878 40.438 180.242 40.438 L177.704 40.438 C177.644 40.438 177.614 40.468 177.614 40.528 L177.614 44.092 C177.614 44.152 177.644 44.182 177.704 44.182 Z M194.938 46 C194.878 46 194.827 45.979 194.785 45.937 C194.743 45.895 194.722 45.844 194.722 45.784 L194.722 33.616 C194.722 33.556 194.743 33.505 194.785 33.463 C194.827 33.421 194.878 33.4 194.938 33.4 L196.594 33.4 C196.654 33.4 196.705 33.421 196.747 33.463 C196.789 33.505 196.81 33.556 196.81 33.616 L196.81 45.784 C196.81 45.844 196.789 45.895 196.747 45.937 C196.705 45.979 196.654 46 196.594 46 Z M215.718 33.4 C215.778 33.4 215.829 33.421 215.871 33.463 C215.913 33.505 215.934 33.556 215.934 33.616 L215.934 35.002 C215.934 35.062 215.913 35.113 215.871 35.155 C215.829 35.197 215.778 35.218 215.718 35.218 L212.406 35.218 C212.346 35.218 212.316 35.248 212.316 35.308 L212.316 45.784 C212.316 45.844 212.295 45.895 212.253 45.937 C212.211 45.979 212.16 46 212.1 46 L210.444 46 C210.384 46 210.333 45.979 210.291 45.937 C210.249 45.895 210.228 45.844 210.228 45.784 L210.228 35.308 C210.228 35.248 210.198 35.218 210.138 35.218 L206.952 35.218 C206.892 35.218 206.841 35.197 206.799 35.155 C206.757 35.113 206.736 35.062 206.736 35.002 L206.736 33.616 C206.736 33.556 206.757 33.505 206.799 33.463 C206.841 33.421 206.892 33.4 206.952 33.4 Z" fill="#d7dee9"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M136.361 116 L136.361 62.719 L151.014 62.719 C154.848 62.719 157.734 63.783 159.672 65.913 C161.609 68.042 162.578 71.155 162.578 75.252 L162.578 100.197 C162.578 105.243 161.695 109.138 159.929 111.883 C158.163 114.628 155.07 116 150.65 116 Z M147.078 106.585 L148.925 106.585 C150.882 106.585 151.861 105.636 151.861 103.739 L151.861 76.251 C151.861 74.475 151.624 73.33 151.15 72.815 C150.676 72.3 149.712 72.043 148.259 72.043 L147.078 72.043 Z M167.484 116 L172.631 62.719 L190.704 62.719 L195.76 116 L185.679 116 L184.922 107.402 L178.504 107.402 L177.838 116 Z M179.261 98.896 L184.104 98.896 L181.773 71.801 L181.289 71.801 Z M201.029 116 L201.029 62.719 L217.377 62.719 C220.102 62.719 222.16 63.339 223.553 64.581 C224.945 65.822 225.879 67.557 226.353 69.788 C226.827 72.018 227.064 74.636 227.064 77.644 C227.064 80.55 226.696 82.871 225.959 84.606 C225.223 86.342 223.835 87.543 221.797 88.209 C223.472 88.552 224.648 89.385 225.324 90.707 C226 92.028 226.338 93.739 226.338 95.838 L226.338 116 L215.833 116 L215.833 95.142 C215.833 93.588 215.515 92.624 214.879 92.25 C214.244 91.877 213.219 91.69 211.807 91.69 L211.807 116 Z M211.867 82.457 L214.44 82.457 C215.914 82.457 216.65 80.853 216.65 77.644 C216.65 75.565 216.489 74.202 216.166 73.557 C215.843 72.911 215.238 72.588 214.35 72.588 L211.867 72.588 Z M232.576 116 L232.576 62.719 L243.111 62.719 L243.111 84.062 L248.076 62.719 L258.793 62.719 L252.829 87.119 L260.034 116 L248.984 116 L243.172 90.207 L243.172 116 Z" fill="#f2f5fa"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M280.361 116 L280.361 62.719 L301.674 62.719 L301.674 73.103 L291.078 73.103 L291.078 81.579 L301.129 81.579 L301.129 91.842 L291.078 91.842 L291.078 116 Z M306.61 116 L306.61 62.719 L316.903 62.719 L316.903 116 Z M323.142 116 L323.142 62.719 L333.798 62.719 L333.798 106.918 L344.757 106.918 L344.757 116 Z M349.784 116 L349.784 62.719 L371.097 62.719 L371.097 73.012 L360.622 73.012 L360.622 83.396 L370.673 83.396 L370.673 93.416 L360.622 93.416 L360.622 105.616 L371.793 105.616 L371.793 116 Z M389.959 116.484 C385.095 116.484 381.588 115.273 379.439 112.852 C377.29 110.43 376.215 106.575 376.215 101.287 L376.215 96.08 L386.75 96.08 L386.75 102.74 C386.75 103.971 386.937 104.935 387.31 105.631 C387.683 106.328 388.334 106.676 389.263 106.676 C390.231 106.676 390.903 106.393 391.276 105.828 C391.649 105.263 391.836 104.335 391.836 103.043 C391.836 101.408 391.674 100.041 391.352 98.941 C391.029 97.841 390.469 96.792 389.671 95.792 C388.874 94.793 387.769 93.628 386.356 92.296 L381.573 87.755 C378.001 84.384 376.215 80.53 376.215 76.19 C376.215 71.649 377.269 68.188 379.378 65.807 C381.487 63.425 384.54 62.234 388.536 62.234 C393.42 62.234 396.887 63.536 398.935 66.14 C400.984 68.743 402.008 72.699 402.008 78.007 L391.17 78.007 L391.17 74.344 C391.17 73.617 390.963 73.052 390.549 72.648 C390.136 72.245 389.576 72.043 388.869 72.043 C388.021 72.043 387.401 72.28 387.007 72.754 C386.614 73.229 386.417 73.839 386.417 74.586 C386.417 75.333 386.619 76.14 387.022 77.008 C387.426 77.876 388.223 78.875 389.414 80.005 L395.56 85.908 C396.791 87.079 397.921 88.315 398.95 89.617 C399.979 90.918 400.807 92.432 401.433 94.158 C402.058 95.883 402.371 97.987 402.371 100.47 C402.371 105.475 401.448 109.395 399.601 112.231 C397.754 115.067 394.54 116.484 389.959 116.484 Z" fill="#e3263f"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1600" height="640" viewBox="0 0 1600 640">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient-1" x1="146.061" y1="131.141" x2="146.061" y2="475" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ffffff"/>
|
||||
<stop offset="0.44" stop-color="#e8edf5"/>
|
||||
<stop offset="0.5" stop-color="#b7cbe8"/>
|
||||
<stop offset="1" stop-color="#f5f7ff"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-2" x1="486" y1="74.278" x2="486" y2="396.428" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ffffff"/>
|
||||
<stop offset="0.55" stop-color="#d7dee9"/>
|
||||
<stop offset="1" stop-color="#8fa0b8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-3" x1="486" y1="300.278" x2="486" y2="622.428" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#e3263f"/>
|
||||
<stop offset="1" stop-color="#a7132a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<title>orbit_dark_files_primary.svg</title>
|
||||
<g id="Layer_1" data-name="Layer 1">
|
||||
<path d="M335 132 C141 114 66 384 257 475 C143 363 185 207 335 132 Z" fill="url(#linear-gradient-1)"/>
|
||||
<path d="M129 369 C102 399 111 425 161 428 C267 432 431 340 445 289 C455 250 405 250 369 261" fill="none" stroke="#c8102e" stroke-width="11"/>
|
||||
<circle cx="430" cy="282" r="9" fill="#c8102e"/>
|
||||
<g>
|
||||
<path d="M525.5 100.5 C523 100.5 520.783 99.992 518.85 98.975 C516.917 97.958 515.425 96.517 514.375 94.65 C513.325 92.783 512.8 90.633 512.8 88.2 L512.8 76.8 C512.8 74.4 513.333 72.275 514.4 70.425 C515.467 68.575 516.958 67.142 518.875 66.125 C520.792 65.108 523 64.6 525.5 64.6 C528.033 64.6 530.258 65.108 532.175 66.125 C534.092 67.142 535.583 68.575 536.65 70.425 C537.717 72.275 538.25 74.4 538.25 76.8 L538.25 88.2 C538.25 90.633 537.717 92.783 536.65 94.65 C535.583 96.517 534.092 97.958 532.175 98.975 C530.258 99.992 528.033 100.5 525.5 100.5 Z M525.5 95.5 C527.6 95.5 529.283 94.85 530.55 93.55 C531.817 92.25 532.45 90.533 532.45 88.4 L532.45 76.75 C532.45 74.583 531.817 72.85 530.55 71.55 C529.283 70.25 527.6 69.6 525.5 69.6 C523.433 69.6 521.767 70.25 520.5 71.55 C519.233 72.85 518.6 74.583 518.6 76.75 L518.6 88.4 C518.6 90.533 519.233 92.25 520.5 93.55 C521.767 94.85 523.433 95.5 525.5 95.5 Z M588.35 100 C588.017 100 587.783 99.85 587.65 99.55 L581.05 85.15 C580.983 85.017 580.883 84.95 580.75 84.95 L574.75 84.95 C574.583 84.95 574.5 85.033 574.5 85.2 L574.5 99.4 C574.5 99.567 574.442 99.708 574.325 99.825 C574.208 99.942 574.067 100 573.9 100 L569.3 100 C569.133 100 568.992 99.942 568.875 99.825 C568.758 99.708 568.7 99.567 568.7 99.4 L568.7 65.6 C568.7 65.433 568.758 65.292 568.875 65.175 C568.992 65.058 569.133 65 569.3 65 L583.05 65 C585.083 65 586.883 65.425 588.45 66.275 C590.017 67.125 591.233 68.325 592.1 69.875 C592.967 71.425 593.4 73.2 593.4 75.2 C593.4 77.5 592.808 79.458 591.625 81.075 C590.442 82.692 588.8 83.817 586.7 84.45 C586.633 84.45 586.583 84.483 586.55 84.55 C586.517 84.617 586.517 84.683 586.55 84.75 L593.6 99.3 C593.667 99.433 593.7 99.533 593.7 99.6 C593.7 99.867 593.517 100 593.15 100 Z M574.75 70 C574.583 70 574.5 70.083 574.5 70.25 L574.5 80.2 C574.5 80.367 574.583 80.45 574.75 80.45 L582.25 80.45 C583.85 80.45 585.142 79.975 586.125 79.025 C587.108 78.075 587.6 76.817 587.6 75.25 C587.6 73.683 587.108 72.417 586.125 71.45 C585.142 70.483 583.85 70 582.25 70 Z M642.9 81.75 C642.7 81.85 642.7 81.95 642.9 82.05 C646.3 83.65 648 86.4 648 90.3 C648 93.467 646.942 95.875 644.825 97.525 C642.708 99.175 639.95 100 636.55 100 L623.95 100 C623.783 100 623.642 99.942 623.525 99.825 C623.408 99.708 623.35 99.567 623.35 99.4 L623.35 65.6 C623.35 65.433 623.408 65.292 623.525 65.175 C623.642 65.058 623.783 65 623.95 65 L636.15 65 C639.783 65 642.583 65.783 644.55 67.35 C646.517 68.917 647.5 71.283 647.5 74.45 C647.5 77.95 645.967 80.383 642.9 81.75 Z M629.4 70 C629.233 70 629.15 70.083 629.15 70.25 L629.15 79.5 C629.15 79.667 629.233 79.75 629.4 79.75 L636.15 79.75 C637.917 79.75 639.308 79.325 640.325 78.475 C641.342 77.625 641.85 76.45 641.85 74.95 C641.85 73.417 641.342 72.208 640.325 71.325 C639.308 70.442 637.917 70 636.15 70 Z M636.55 94.95 C638.283 94.95 639.658 94.483 640.675 93.55 C641.692 92.617 642.2 91.35 642.2 89.75 C642.2 88.117 641.683 86.842 640.65 85.925 C639.617 85.008 638.217 84.55 636.45 84.55 L629.4 84.55 C629.233 84.55 629.15 84.633 629.15 84.8 L629.15 94.7 C629.15 94.867 629.233 94.95 629.4 94.95 Z M679.05 100 C678.883 100 678.742 99.942 678.625 99.825 C678.508 99.708 678.45 99.567 678.45 99.4 L678.45 65.6 C678.45 65.433 678.508 65.292 678.625 65.175 C678.742 65.058 678.883 65 679.05 65 L683.65 65 C683.817 65 683.958 65.058 684.075 65.175 C684.192 65.292 684.25 65.433 684.25 65.6 L684.25 99.4 C684.25 99.567 684.192 99.708 684.075 99.825 C683.958 99.942 683.817 100 683.65 100 Z M738.55 65 C738.717 65 738.858 65.058 738.975 65.175 C739.092 65.292 739.15 65.433 739.15 65.6 L739.15 69.45 C739.15 69.617 739.092 69.758 738.975 69.875 C738.858 69.992 738.717 70.05 738.55 70.05 L729.35 70.05 C729.183 70.05 729.1 70.133 729.1 70.3 L729.1 99.4 C729.1 99.567 729.042 99.708 728.925 99.825 C728.808 99.942 728.667 100 728.5 100 L723.9 100 C723.733 100 723.592 99.942 723.475 99.825 C723.358 99.708 723.3 99.567 723.3 99.4 L723.3 70.3 C723.3 70.133 723.217 70.05 723.05 70.05 L714.2 70.05 C714.033 70.05 713.892 69.992 713.775 69.875 C713.658 69.758 713.6 69.617 713.6 69.45 L713.6 65.6 C713.6 65.433 713.658 65.292 713.775 65.175 C713.892 65.058 714.033 65 714.2 65 Z" fill="#d7dee9"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M494.15 326 L494.15 142.094 L544.725 142.094 C557.96 142.094 567.922 145.768 574.609 153.118 C581.297 160.467 584.641 171.212 584.641 185.354 L584.641 271.455 C584.641 288.87 581.593 302.315 575.498 311.789 C569.402 321.263 558.727 326 543.471 326 Z M531.141 293.503 L537.515 293.503 C544.272 293.503 547.65 290.229 547.65 283.681 L547.65 188.802 C547.65 182.672 546.832 178.718 545.195 176.942 C543.558 175.166 540.231 174.277 535.216 174.277 L531.141 174.277 Z M620.672 326 L638.436 142.094 L700.817 142.094 L718.268 326 L683.472 326 L680.859 296.324 L658.707 296.324 L656.408 326 Z M661.319 266.962 L678.038 266.962 L669.992 173.441 L668.32 173.441 Z M755.553 326 L755.553 142.094 L811.979 142.094 C821.383 142.094 828.488 144.236 833.295 148.52 C838.102 152.804 841.323 158.795 842.96 166.493 C844.597 174.19 845.416 183.229 845.416 193.608 C845.416 203.64 844.145 211.651 841.602 217.642 C839.059 223.632 834.27 227.777 827.234 230.076 C833.016 231.26 837.074 234.134 839.408 238.697 C841.741 243.26 842.908 249.163 842.908 256.408 L842.908 326 L806.649 326 L806.649 254.005 C806.649 248.641 805.552 245.315 803.358 244.026 C801.164 242.737 797.628 242.093 792.752 242.093 L792.752 326 Z M792.961 210.223 L801.843 210.223 C806.928 210.223 809.471 204.685 809.471 193.608 C809.471 186.433 808.913 181.731 807.799 179.502 C806.684 177.273 804.594 176.158 801.529 176.158 L792.961 176.158 Z M883.537 326 L883.537 142.094 L919.9 142.094 L919.9 215.761 L937.037 142.094 L974.027 142.094 L953.442 226.314 L978.312 326 L940.172 326 L920.109 236.973 L920.109 326 Z" fill="url(#linear-gradient-2)"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M494.15 552 L494.15 368.094 L567.713 368.094 L567.713 403.935 L531.141 403.935 L531.141 433.192 L565.832 433.192 L565.832 468.615 L531.141 468.615 L531.141 552 Z M593.849 552 L593.849 368.094 L629.376 368.094 L629.376 552 Z M660.005 552 L660.005 368.094 L696.786 368.094 L696.786 520.652 L734.612 520.652 L734.612 552 Z M761.062 552 L761.062 368.094 L834.624 368.094 L834.624 403.621 L798.47 403.621 L798.47 439.462 L833.161 439.462 L833.161 474.049 L798.47 474.049 L798.47 516.159 L837.027 516.159 L837.027 552 Z M908.826 553.672 C892.038 553.672 879.934 549.492 872.515 541.133 C865.096 532.773 861.387 519.468 861.387 501.217 L861.387 483.244 L897.75 483.244 L897.75 506.232 C897.75 510.482 898.394 513.808 899.683 516.211 C900.972 518.615 903.218 519.816 906.423 519.816 C909.767 519.816 912.083 518.841 913.372 516.891 C914.66 514.94 915.305 511.736 915.305 507.277 C915.305 501.635 914.747 496.915 913.633 493.119 C912.518 489.322 910.585 485.7 907.833 482.251 C905.082 478.803 901.268 474.78 896.392 470.183 L879.882 454.509 C867.552 442.875 861.387 429.57 861.387 414.593 C861.387 398.919 865.027 386.972 872.306 378.752 C879.586 370.532 890.122 366.422 903.915 366.422 C920.773 366.422 932.737 370.915 939.808 379.901 C946.879 388.888 950.414 402.541 950.414 420.862 L913.006 420.862 L913.006 408.219 C913.006 405.711 912.292 403.76 910.864 402.367 C909.436 400.974 907.503 400.277 905.064 400.277 C902.139 400.277 899.997 401.096 898.638 402.733 C897.28 404.37 896.601 406.477 896.601 409.055 C896.601 411.632 897.297 414.419 898.69 417.414 C900.084 420.41 902.835 423.858 906.945 427.759 L928.157 448.135 C932.407 452.175 936.308 456.442 939.86 460.935 C943.413 465.428 946.269 470.653 948.429 476.609 C950.588 482.565 951.668 489.827 951.668 498.396 C951.668 515.672 948.481 529.203 942.107 538.991 C935.733 548.778 924.639 553.672 908.826 553.672 Z" fill="url(#linear-gradient-3)"/>
|
||||
</g>
|
||||
<path d="M300 600 C720 620 1040 600 1320 530" fill="none" stroke="#c8102e" stroke-width="7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 311 KiB |
|
After Width: | Height: | Size: 395 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><defs><linearGradient id="desk" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#3A2C22"/><stop offset="1" stop-color="#1C1510"/></linearGradient></defs><polygon points="0,700 1920,660 1920,1080 0,1080" fill="url(#desk)"/></svg>
|
||||
|
After Width: | Height: | Size: 328 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><g transform="rotate(-4 900 860)"><path d="M560 700H780L820 738H1260V1040H560Z" fill="#B99C6B"/><rect x="580" y="750" width="680" height="300" fill="#D8BE8E"/><text x="700" y="930" font-family="Anton" font-size="92" font-weight="400" fill="#C8102E" letter-spacing="8" opacity=".85">CASE FILE</text><rect x="680" y="842" width="440" height="106" fill="none" stroke="#C8102E" stroke-width="7" opacity=".85"/></g></svg>
|
||||
|
After Width: | Height: | Size: 507 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><defs><radialGradient id="lampglow"><stop offset="0" stop-color="#FFE5A6" stop-opacity="0.8"/><stop offset="0.45" stop-color="#FFD27A" stop-opacity="0.34"/><stop offset="1" stop-color="#FFD27A" stop-opacity="0"/></radialGradient></defs><ellipse cx="1320" cy="760" rx="820" ry="420" fill="url(#lampglow)"/></svg>
|
||||
|
After Width: | Height: | Size: 402 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><path d="M1820 1080V560C1820 440 1700 330 1560 290" fill="none" stroke="#1E2433" stroke-width="20"/><path d="M1590 170C1490 190 1380 290 1350 420L1660 340C1650 270 1630 210 1590 170Z" fill="#2A3040"/><path d="M1350 420L1660 340C1640 372 1520 420 1350 420Z" fill="#FFE9B5"/></svg>
|
||||
|
After Width: | Height: | Size: 370 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><g transform="translate(1180,640) rotate(7)"><rect width="280" height="210" fill="#EFE9DC"/><rect x="14" y="14" width="252" height="164" fill="#0D1525"/><circle cx="190" cy="60" r="20" fill="#B7CBE8"/><polygon points="14,178 80,90 140,140 200,70 266,178" fill="#050A18"/></g></svg>
|
||||
|
After Width: | Height: | Size: 372 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><g transform="translate(1370,780) rotate(-5)"><rect width="280" height="210" fill="#EFE9DC"/><rect x="14" y="14" width="252" height="164" fill="#0D1525"/><ellipse cx="140" cy="100" rx="12" ry="16" fill="none" stroke="#B7CBE8" stroke-width="3"/><ellipse cx="140" cy="100" rx="23" ry="29" fill="none" stroke="#B7CBE8" stroke-width="3"/><ellipse cx="140" cy="100" rx="34" ry="42" fill="none" stroke="#B7CBE8" stroke-width="3"/><ellipse cx="140" cy="100" rx="45" ry="55" fill="none" stroke="#B7CBE8" stroke-width="3"/><ellipse cx="140" cy="100" rx="56" ry="68" fill="none" stroke="#B7CBE8" stroke-width="3"/><ellipse cx="140" cy="100" rx="67" ry="81" fill="none" stroke="#B7CBE8" stroke-width="3"/></g></svg>
|
||||
|
After Width: | Height: | Size: 795 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><g transform="translate(300,700) rotate(-9)"><rect width="280" height="210" fill="#EFE9DC"/><rect x="14" y="14" width="252" height="164" fill="#0D1525"/><polygon points="70,178 70,110 130,70 190,110 190,178" fill="#050A18"/><rect x="110" y="120" width="26" height="26" fill="#FFDE59" opacity=".8"/></g></svg>
|
||||
|
After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="486" y="552" font-family="Anton" font-size="214" font-weight="400" fill="url(#evred)" letter-spacing="16">FILES</text></svg>
|
||||
|
After Width: | Height: | Size: 811 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><path d="M335 132C141 114 66 384 257 475C143 363 185 207 335 132Z" fill="url(#silver)"/><path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289C455 250 405 250 369 261" fill="none" stroke="#C8102E" stroke-width="11"/><circle cx="430" cy="282" r="9" fill="#C8102E"/></svg>
|
||||
|
After Width: | Height: | Size: 959 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="510" y="100" font-family="Barlow" font-size="50" font-weight="600" fill="#D7DEE9" letter-spacing="24">ORBIT</text></svg>
|
||||
|
After Width: | Height: | Size: 807 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"><defs><radialGradient id="scrim"><stop offset="0" stop-color="#070B1A" stop-opacity="0.82"/><stop offset="0.62" stop-color="#070B1A" stop-opacity="0.62"/><stop offset="1" stop-color="#070B1A" stop-opacity="0"/></radialGradient></defs><ellipse cx="960" cy="500" rx="880" ry="380" fill="url(#scrim)"/></svg>
|
||||
|
After Width: | Height: | Size: 396 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><path d="M300 600C720 620 1040 600 1320 530" fill="none" stroke="#C8102E" stroke-width="7"/></svg>
|
||||
|
After Width: | Height: | Size: 187 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="486" y="326" font-family="Anton" font-size="214" font-weight="400" fill="url(#steel)" letter-spacing="26">DARK</text></svg>
|
||||
|
After Width: | Height: | Size: 810 B |
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="384" height="128" viewBox="0 0 384 128"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><g transform="translate(-7,-8) scale(.22)"><path d="M335 132C141 114 66 384 257 475C143 363 185 207 335 132Z" fill="#FFFFFF"/><path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289C455 250 405 250 369 261" fill="none" stroke="#E3263F" stroke-width="11"/><circle cx="430" cy="282" r="9" fill="#E3263F"/></g><text x="104" y="68" font-family="Anton" font-size="50" font-weight="400" fill="#FFFFFF" letter-spacing="3" stroke="#071632" stroke-width="1.5">DARK</text><text x="104" y="122" font-family="Anton" font-size="50" font-weight="400" fill="#FF3A50" letter-spacing="3" stroke="#071632" stroke-width="1.5">FILES</text></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="160" viewBox="0 0 512 160"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><g transform="translate(-5,1) scale(.26)"><path d="M335 132C141 114 66 384 257 475C143 363 185 207 335 132Z" fill="url(#silver)"/><path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289C455 250 405 250 369 261" fill="none" stroke="#C8102E" stroke-width="11"/><circle cx="430" cy="282" r="9" fill="#C8102E"/></g><text x="136" y="46" font-family="Barlow" font-size="18" font-weight="600" fill="#D7DEE9" letter-spacing="8">ORBIT</text><text x="134" y="116" font-family="Anton" font-size="62" font-weight="400" fill="#F2F5FA" letter-spacing="2">DARK</text><text x="278" y="116" font-family="Anton" font-size="62" font-weight="400" fill="#E3263F" letter-spacing="2">FILES</text></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="640" viewBox="0 0 1600 640"><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><path d="M335 132C141 114 66 384 257 475C143 363 185 207 335 132Z" fill="url(#silver)"/><path d="M129 369C102 399 111 425 161 428C267 432 431 340 445 289C455 250 405 250 369 261" fill="none" stroke="#C8102E" stroke-width="11"/><circle cx="430" cy="282" r="9" fill="#C8102E"/><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="510" y="100" font-family="Barlow" font-size="50" font-weight="600" fill="#D7DEE9" letter-spacing="24">ORBIT</text><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="486" y="326" font-family="Anton" font-size="214" font-weight="400" fill="url(#steel)" letter-spacing="26">DARK</text><defs><linearGradient id="silver" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.44" stop-color="#E8EDF5"/><stop offset="0.5" stop-color="#B7CBE8"/><stop offset="1" stop-color="#F5F7FF"/></linearGradient><linearGradient id="steel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.55" stop-color="#D7DEE9"/><stop offset="1" stop-color="#8FA0B8"/></linearGradient><linearGradient id="evred" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#E3263F"/><stop offset="1" stop-color="#A7132A"/></linearGradient></defs><text x="486" y="552" font-family="Anton" font-size="214" font-weight="400" fill="url(#evred)" letter-spacing="16">FILES</text><path d="M300 600C720 620 1040 600 1320 530" fill="none" stroke="#C8102E" stroke-width="7"/></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"status": "design-proof-not-integrated",
|
||||
"primary": {
|
||||
"alpha": [
|
||||
0,
|
||||
255
|
||||
],
|
||||
"fonts": [
|
||||
"Anton",
|
||||
"Barlow"
|
||||
]
|
||||
},
|
||||
"epg": {
|
||||
"alpha": [
|
||||
0,
|
||||
255
|
||||
],
|
||||
"fonts": [
|
||||
"Anton",
|
||||
"Barlow"
|
||||
]
|
||||
},
|
||||
"bug": {
|
||||
"alpha": [
|
||||
0,
|
||||
255
|
||||
],
|
||||
"fonts": [
|
||||
"Anton"
|
||||
]
|
||||
},
|
||||
"photoCraftLayers": 8,
|
||||
"fileSizes": {
|
||||
"orbit_dark_files_epg_app.webp": 6036,
|
||||
"orbit_dark_files_bug_app.webp": 3636,
|
||||
"orbit_dark_files_background.webp": 48436,
|
||||
"orbit_dark_files_ident.mp4": 1777769
|
||||
},
|
||||
"ident": {
|
||||
"frames": 105,
|
||||
"largestFrameChange": 0.0082,
|
||||
"framesChangingOver10Percent": 0,
|
||||
"brightnessReversals": 0
|
||||
},
|
||||
"collectedProjectRendered": true
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# Orbit Odyssey — branding proof 01
|
||||
|
||||
Science, history, exploration. Original artwork, redrawn from Paul's concept board. The board is direction only: no pixels are copied from it, and it's kept in `design/references`.
|
||||
|
||||
## Ident
|
||||
|
||||
Sun rises over the Earth, a gold orbital line traces across it, then the logo appears with its discovery star. 4.2 seconds, silent H.264, 1280x720, 25 fps. It isn't in the app and can't delay a programme.
|
||||
|
||||
## Files
|
||||
|
||||
- `review/orbit_odyssey_review.png`: logo, EPG, bug, background and palette. Editable as `.figcraft`.
|
||||
- `review/orbit_odyssey_ident_sheet.png`: frames through the ident.
|
||||
- `exports/`: transparent logos (PNG, outlined SVG), app-sized `_epg_app.webp` (256x80) and `_bug_app.webp` (144x48), background WebP, ident MP4, and the separate layers the ident uses.
|
||||
- `sources/`: VectorCraft logo files with live text, layered PhotoCraft background, source SVGs, and `ident-project/` holding the self-contained EffectCraft project.
|
||||
|
||||
`../build-network-brands.py` rebuilds all of this. Fonts are in `../network-fonts`, with licences in the project's `licenses/` folder.
|
||||
|
||||
## Status
|
||||
|
||||
A design proof for review, not integrated. Android drawing, the bug's visibility over real programmes, subtitle behaviour and any ident timing still need testing on the box. `verification.json` records the checks; its brightness figures are a rough screen, not a formal photosensitivity test.
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"status": "design-proof-not-integrated",
|
||||
"presetId": "orbit-odyssey",
|
||||
"displayName": "Orbit Odyssey",
|
||||
"channelNumber": null,
|
||||
"networkTokens": {
|
||||
"background": "#071632",
|
||||
"panel": "#12356B",
|
||||
"navigation": "#194C91",
|
||||
"focus": "#FFDE59",
|
||||
"muted": "#B7CBE8",
|
||||
"text": "#FFFFFF"
|
||||
},
|
||||
"palette": {
|
||||
"Orbit navy": "#07142E",
|
||||
"Expedition blue": "#0E3E7A",
|
||||
"Atlantic teal": "#138A8A",
|
||||
"Orbit silver": "#D6E2F3",
|
||||
"Discovery gold": "#FFC766"
|
||||
},
|
||||
"assets": {
|
||||
"primary": "exports/orbit_odyssey_primary.svg",
|
||||
"epg": "exports/orbit_odyssey_epg_app.webp",
|
||||
"bug": "exports/orbit_odyssey_bug_app.webp",
|
||||
"background": "exports/orbit_odyssey_background.webp",
|
||||
"ident": "exports/orbit_odyssey_ident.mp4"
|
||||
},
|
||||
"proposedOverlay": {
|
||||
"default": "off",
|
||||
"anchor": "bottom-left",
|
||||
"widthAt1080p": 144,
|
||||
"heightAt1080p": 48,
|
||||
"safeInsetPercent": 5,
|
||||
"opacity": 0.8,
|
||||
"hideForProgrammeStrip": true,
|
||||
"hideForSubtitles": true
|
||||
},
|
||||
"ident": {
|
||||
"durationSeconds": 4.2,
|
||||
"fps": 25,
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"codec": "h264",
|
||||
"audio": false,
|
||||
"alpha": false,
|
||||
"schedulePolicy": "optional; never delays scheduled media; a longer ident needs an explicit scheduled slot"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 42 KiB |