Files
OrbitTv/design/create-classic-osd.py
pauljdandClaude Opus 5.5 934f82d805
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 1m48s
pauljd/davidson-ci: Davidson CI / ai-review (push) Successful in 49s
Orbit TV at 0.16.0-tuning-screen
First commit, imported from the working folder: Android TV app, loopback
guide server, design sources and per-release verification notes.

Includes the 0.16 tuning screen, built and tested but not yet confirmed
on the box.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-01 17:25:30 +00:00

20 lines
1.8 KiB
Python

from pathlib import Path
from html import escape
p=Path(__file__).parent
parts=['<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080">', '<defs><linearGradient id="night" x2="0" y2="1"><stop stop-color="#030915"/><stop offset="1" stop-color="#12356b"/></linearGradient></defs>', '<rect width="1920" height="1080" fill="url(#night)"/>']
def rect(x,y,w,h,color):parts.append(f'<rect x="{x}" y="{y}" width="{w}" height="{h}" fill="{color}"/>')
def text(x,y,value,size=30,color='#fff',bold=False):parts.append(f'<text x="{x}" y="{y}" font-family="DejaVu Sans" font-size="{size}" font-weight="{700 if bold else 400}" fill="{color}">{escape(value)}</text>')
# Original abstract video stand-in, not captured provider content.
parts.append('<circle cx="960" cy="415" r="160" fill="#112748" stroke="#255482" stroke-width="5"/><ellipse cx="960" cy="415" rx="330" ry="60" transform="rotate(-22 960 415)" fill="none" stroke="#d5aa54" stroke-opacity=".55" stroke-width="6"/>')
for x,y,r in [(180,180,3),(420,340,2),(1560,140,3),(1680,480,2),(1300,250,2),(700,140,2),(300,600,3)]:parts.append(f'<circle cx="{x}" cy="{y}" r="{r}" fill="#b7cbe8"/>')
x=134;y=794;w=1652
rect(x-2,y-2,w+4,234,'#e8edf5')
rect(x,y,w,44,'#e8edf5');text(x+24,y+32,'Orbit Preview',28,'#071632',True);text(x+w-360,y+31,'21:30 Sun 1 Nov',26,'#071632')
rect(x,y+44,w,128,'#194c91')
text(x+28,y+98,'NOW',28,'#ffde59',True);text(x+168,y+99,'The Last Shuttle Home',40,'#fff',True)
text(x+28,y+144,'INFO',26,'#b7cbe8',True);text(x+168,y+144,'Movie • 96 min',28)
rect(x,y+172,w,58,'#e8edf5')
for px,icon,label in [(x+28,'▲ ▼','Channel'),(x+390,'↶','TV guide'),(x+760,'CC','Subtitles')]:
text(px,y+211,icon,32,'#071632',True);text(px+92,y+211,label,28,'#071632',True)
parts.append('</svg>');(p/'classic-programme-strip.svg').write_text('\n'.join(parts))