diff --git a/design/whats-on/README.md b/design/whats-on/README.md index d1681a7..a24addc 100644 --- a/design/whats-on/README.md +++ b/design/whats-on/README.md @@ -20,3 +20,16 @@ The full set of boards (states, components, navigation map, wireframe) is on the The spec is https://claude.ai/artifact/BBUQyr3BUAva8uhaFodKU1 Fonts: Barlow, Barlow Condensed and Anton, from design/fonts and the app's res/font. + +## v2: simplified (Paul, 4 November 2026, 16:59) + +These are now the current designs. v1 above is superseded. +- `build-v2.py` writes the `v2/` frames. It reuses v1's helpers and assets. +- The frames: + 1. Home: the categories in the centre; + 2. What's On on one screen: Tonight's Pick, Tonight on Orbit, Coming Up; + 3. the What's On pop-up, with Remind me and Back; + 4. the Drive-In on one screen, with its art blended into navy; + 5. the TV Guide in the new colours, opened on a category; + 6. the remote navigation map. +- Each frame is in `v2/` as `.figcraft`, `.fig` and `.png`. Mock data throughout. diff --git a/design/whats-on/build-v2.py b/design/whats-on/build-v2.py new file mode 100644 index 0000000..13fd78e --- /dev/null +++ b/design/whats-on/build-v2.py @@ -0,0 +1,323 @@ +"""What's On v2 (Paul, 4 November 2026, 16:59): one top bar, a quiet Home of categories, What's On on one screen with a +pop-up, the Drive-In on one screen, and the TV Guide in the same colours. Design only; every programme, time and date is +MOCK DATA. Run: python3 design/whats-on/build-v2.py, then design/whats-on/convert.sh v2. +""" +import importlib.util, io, base64, math +from pathlib import Path +from PIL import Image + +HERE = Path(__file__).parent +spec = importlib.util.spec_from_file_location("v1", HERE / "build-whats-on.py") +v1 = importlib.util.module_from_spec(spec); spec.loader.exec_module(v1) +Screen, LOGO, LOT, TICKET = v1.Screen, v1.LOGO, v1.LOT, v1.TICKET +NAVY, DEEP, PANEL, BLUE, GOLD, MUTED, WHITE = v1.NAVY, v1.DEEP, v1.PANEL, v1.BLUE, v1.GOLD, v1.MUTED, v1.WHITE +SKY, MINT, PINK, LIVE = v1.SKY, v1.MINT, v1.PINK, v1.LIVE +BODY, COND, HEAD = v1.BODY, v1.COND, v1.HEAD +RES = v1.RES +OUT = HERE / "v2" +OUT.mkdir(exist_ok=True) + +for name, file in {"one": "orbit_one_epg", "gold": "orbit_gold_epg", "toonz": "toonz_epg", "wild": "orbit_wild_epg", "odyssey": "orbit_odyssey_epg", + "evidence": "evidence_epg", "heroes": "heroes_epg", "scifi": "orbit_sci_fi_epg"}.items(): + LOGO[name] = v1.data_uri(RES / f"{file}.webp") + + +def icon(name, colour): + """A category icon, recoloured: white on blue, navy on the gold focused tile, as the app tints it.""" + im = Image.open(RES / f"orbit_icon_{name}.webp").convert("RGBA") + r, g, b = int(colour[1:3], 16), int(colour[3:5], 16), int(colour[5:7], 16) + tinted = Image.new("RGBA", im.size, (r, g, b, 0)); tinted.putalpha(im.getchannel("A")) + buf = io.BytesIO(); tinted.save(buf, "PNG") + return "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode() + + +class Screen2(Screen): + def save(self): + self.parts.append("") + (OUT / f"{self.name}.svg").write_text("\n".join(self.parts)) + + def bar(self, active, clock=True): + """The one top bar, on every screen. The focused tab is gold; the current destination is underlined in gold.""" + self.group("Top bar") + self.img(96, 60, 208, 52, LOGO["orbit"], "Orbit logo") + x = 344 + for tab in ["Home", "What's On", "TV Guide", "Drive-In", "Arcade"]: + w = int(len(tab) * 14.5) + 44 + on = tab == active + self.text(x + w / 2, 96, tab, 26, WHITE if on else MUTED, BODY, 600, "middle") + if on: + self.rect(x + 14, 108, w - 28, 4, GOLD, rx=2, id="Current destination") + x += w + 8 + if clock: + self.text(1824, 92, "18:42", 40, WHITE, COND, 500, "end") + self.text(1824, 116, "Saturday 14 November", 20, MUTED, BODY, 400, "end") + self.rect(96, 134, 1728, 2, BLUE) + self.end() + + def shade(self, id, stops, vertical=False): + """A navy gradient over artwork, so it blends into the interface.""" + a = 'x1="0" x2="0" y1="0" y2="1"' if vertical else 'x1="0" x2="1" y1="0" y2="0"' + s = "".join(f'' for o, op in stops) + self.parts.append(f'{s}') + + +def home(): + s = Screen2("1-home", "Home") + s.bar("Home") + s.mock(y=150) + s.group("Categories") + s.text(960, 290, "What would you like to watch?", 40, WHITE, HEAD, anchor="middle") + cats = [("all", "All Channels"), ("entertainment", "Entertainment"), ("movies", "Movies"), ("comedy", "Comedy"), + ("cartoons", "Cartoons"), ("kids", "Kids"), ("documentaries", "Documentaries"), ("sport", "Sport")] + for i, (key, label) in enumerate(cats): + col, row = i % 4, i // 4 + x, y = 270 + col * 352, 350 + row * 262 + focused = i == 2 + s.group(f"Category {label}") + s.rect(x, y, 328, 238, GOLD if focused else PANEL, rx=14) + s.img(x + 124, y + 46, 80, 80, icon(key, NAVY if focused else WHITE), f"{label} icon") + s.text(x + 164, y + 176, label, 30, NAVY if focused else WHITE, BODY, 600, "middle") + if focused: + s.focus(x, y, 328, 238, 14) + s.end() + s.end() + s.group("Gentle pointer to What's On") + s.text(960, 930, "Tonight's Pick and the evening's highlights are in What's On", 22, MUTED, anchor="middle") + s.end() + s.hints([("OK", "Open the category's channels"), ("◀ ▶ ▲ ▼", "Move"), ("▲", "Top bar"), ("Back", "Close Orbit")]) + s.save() + + +def tonights_pick(s, focused=True): + s.group("Tonight's Pick") + x, y, w, h = 96, 168, 1120, 560 + s.img(x, y, w, h, LOT, "Programme artwork (Emby backdrop; this frame uses the Drive-In art as a stand-in)", "xMidYMid slice") + s.shade("pickfade", [(0, 0.97), (0.45, 0.88), (0.75, 0.35), (1, 0.15)]) + s.rect(x, y, w, h, "url(#pickfade)", id="Navy blend") + s.rect(x, y, w, h, "none", rx=14, stroke=BLUE) + s.tag(x + 32, y + 30, "TONIGHT'S PICK", GOLD, 22) + s.img(x + 32, y + 92, 192, 60, LOGO["afterdark"], "Channel badge L") + s.text(x + 32, y + 200, "Tonight 21:00", 40, GOLD, COND, 500) + s.text(x + 32, y + 270, "JOE BOB SATURDAY", 62, WHITE, HEAD) + s.text(x + 32, y + 318, "Tourist Trap (1979)", 30, WHITE, BODY, 600) + s.text(x + 32, y + 368, "The drive-in host introduces a cult mannequin", 24, "#E4ECF8") + s.text(x + 32, y + 400, "chiller. A weekly After Dark event.", 24, "#E4ECF8") + s.tag(x + 32, y + 490, "WEEKLY EVENT", GOLD, 18) + s.text(x + 230, y + 510, "131 min · OK for details and Remind me", 20, MUTED) + s.text(x + w - 24, y + h - 20, "Artwork: the programme's Emby backdrop (stand-in shown)", 16, MUTED, anchor="end") + if focused: + s.focus(x, y, w, h, 14) + s.end() + + +def whats_on(name="2-whats-on", dim=False): + s = Screen2(name, "What's On") + s.bar("What's On") + s.mock(y=150) + tonights_pick(s, not dim) + s.group("Tonight on Orbit") + s.text(1248, 196, "TONIGHT ON ORBIT", 30, WHITE, HEAD) + rows = [("19:30", "riot", "Futurama", "Next in turn"), ("20:00", "drivein", "Back to the Future", "Orbit Marquee"), + ("21:00", "three", "Scottish Comedy Night", "Still Game, Limmy's Show!"), ("22:00", "paradox", "The X-Files", "A complete two-part story"), + ("22:30", "ringx", "Saturday Night Main Event", "Ring X Saturday")] + for i, (t, logo, title, sub) in enumerate(rows): + y = 218 + i * 102 + s.group(f"Tonight row {i + 1}") + s.rect(1248, y, 576, 92, PANEL, rx=10) + s.text(1268, y + 58, t, 36, GOLD, COND, 500) + s.img(1372, y + 10, 112, 35, LOGO[logo], "Channel badge S") + s.text(1372, y + 70, title, 22, WHITE, BODY, 600) + s.text(1804, y + 30, sub, 16, MUTED, anchor="end") + s.end() + s.end() + s.group("Coming Up") + s.text(96, 790, "COMING UP", 30, WHITE, HEAD) + s.text(320, 788, "Premieres, specials and events, already booked", 20, MUTED) + cards = [("PPV SUNDAY", GOLD, "ringx", "WrestleMania III", "Sunday 19:08", None), + ("FIRST ON ORBIT", SKY, "premiere", "A new-arrival film", "Friday 20:00", None), + ("AT THE DRIVE-IN", GOLD, "drivein", "The Back to the Future Trilogy", "Saturday 19:00", "Go to the Drive-In ▶")] + for i, (tag, colour, logo, title, when, link) in enumerate(cards): + x = 96 + i * 584 + s.group(f"Coming Up {i + 1}") + s.rect(x, 812, 560, 172, PANEL, rx=12) + s.tag(x + 22, 830, tag, colour) + s.img(x + 426, 826, 112, 35, LOGO[logo], "Channel badge S") + s.text(x + 22, 906, title, 26, WHITE, BODY, 600) + s.text(x + 22, 950, when, 30, GOLD, COND, 500) + if link: + s.text(x + 538, 950, link, 19, GOLD, BODY, 600, "end") + s.end() + s.end() + s.group("Remote hints") + s.rect(96, 1006, 1728, 1, BLUE) + s.text(96, 1036, "OK", 19, GOLD, BODY, 600); s.text(132, 1036, "Details, then Watch or Remind me", 19, MUTED) + s.text(470, 1036, "◀ ▶ ▲ ▼", 19, GOLD, BODY, 600); s.text(568, 1036, "Move", 19, MUTED) + s.text(650, 1036, "Back", 19, GOLD, BODY, 600); s.text(706, 1036, "Home", 19, MUTED) + s.text(1824, 1036, "Chosen from confirmed bookings · refreshed daily at 12:00", 19, MUTED, anchor="end") + s.end() + if dim: + popup(s) + s.save() + + +def popup(s): + """Details as a pop-up over What's On: the style Paul liked, with Remind me and Back (Watch live when it's on now).""" + s.rect(0, 0, 1920, 1080, NAVY, id="Dim", opacity=0.78) + s.group("Details pop-up") + x, y, w, h = 360, 170, 1200, 740 + s.rect(x, y, w, h, DEEP, rx=18, stroke=BLUE) + s.img(x + 40, y + 36, 192, 60, LOGO["paradox"], "Channel badge L") + s.text(x + 40, y + 160, "THE X-FILES", 72, WHITE, HEAD) + s.text(x + 40, y + 210, "Season 2, Episode 25 · Anasazi", 30, WHITE, BODY, 600) + bx = x + 40 + bx += s.tag(bx, y + 236, "STORY · PART 1 OF 2", SKY, 18) + 12 + s.rect(bx, y + 236, 104, 30, "none", rx=4, stroke=MUTED); s.text(bx + 52, y + 258, "45 min", 18, WHITE, BODY, 600, "middle") + s.rect(x + 40, y + 290, w - 80, 120, PANEL, rx=12, id="Booked time") + s.text(x + 66, y + 346, "Tonight 22:00 to 22:45", 44, GOLD, COND, 500) + s.rect(x + 470, y + 316, 96, 32, "none", rx=4, stroke=MINT); s.text(x + 518, y + 339, "BOOKED", 17, MINT, BODY, 600, "middle") + s.text(x + 66, y + 390, "Then part 2, The Blessing Way, straight after at 22:45", 21, MUTED) + for i, line in enumerate(["Mulder receives leaked files that could prove the existence of extraterrestrial", "life, and the trail leads to a buried railcar in the New Mexico desert. [Emby synopsis]"]): + s.text(x + 40, y + 466 + i * 34, line, 23, "#E4ECF8") + s.text(x + 40, y + 552, "Why it's here: a complete two-part story tonight, on Paradox's late block.", 20, MUTED) + s.rect(x + 40, y + 610, 318, 72, GOLD, rx=8); s.text(x + 199, y + 656, "Remind me at 22:00", 26, NAVY, BODY, 600, "middle") + s.focus(x + 40, y + 610, 318, 72, 8) + s.rect(x + 378, y + 610, 150, 72, PANEL, rx=8); s.text(x + 453, y + 656, "Back", 26, WHITE, BODY, 600, "middle") + s.text(x + w - 40, y + 656, "On now? The first button is Watch live: one press to tune in.", 19, MUTED, anchor="end") + s.end() + + +def drive_in(): + s = Screen2("4-drive-in", "Orbit Drive-In") + s.img(0, 0, 1920, 1080, LOT, "Drive-In lot (approved artwork)", "xMidYMid slice") + s.shade("lotfade", [(0, 0.96), (0.42, 0.9), (0.62, 0.55), (1, 0.35)]) + s.rect(0, 0, 1920, 1080, "url(#lotfade)", id="Navy blend (horizontal)") + s.shade("lotfadev", [(0, 0.9), (0.2, 0.2), (0.75, 0.25), (1, 0.95)], vertical=True) + s.rect(0, 0, 1920, 1080, "url(#lotfadev)", id="Navy blend (vertical)") + s.bar("Drive-In") + s.mock(y=150) + s.group("Tonight's film") + s.img(96, 170, 220, 69, LOGO["drivein"], "Drive-In logo") + s.tag(96, 268, "TONIGHT · ORBIT MARQUEE", GOLD, 22) + s.text(96, 360, "Gates 19:55 · Feature 20:00", 42, GOLD, COND, 500) + s.text(96, 460, "BACK TO THE FUTURE", 92, WHITE, HEAD) + s.text(96, 512, "1985 · 116 min · then The Late Show at 23:00", 28, "#E4ECF8") + s.img(96, 590, 300, 93, TICKET, "Ticket") + s.text(420, 626, "Ticket held", 28, MINT, BODY, 600) + s.text(420, 662, "Reminder 5 minutes before, and at the start", 21, MUTED) + s.rect(96, 730, 300, 72, GOLD, rx=8); s.text(246, 776, "Return ticket", 26, NAVY, BODY, 600, "middle") + s.focus(96, 730, 300, 72, 8) + s.rect(416, 730, 300, 72, "none", rx=8, stroke=GOLD, sw=2); s.text(566, 776, "Go to the big screen", 24, GOLD, BODY, 600, "middle") + s.end() + s.group("Upcoming screenings") + s.rect(1216, 196, 608, 790, NAVY, rx=14, opacity=0.86) + s.text(1244, 246, "THIS WEEK'S BILLS", 30, WHITE, HEAD) + bills = [("SAT", "23:00", "THE LATE SHOW", "Evil Dead II", False), ("SUN", "20:00", "ORBIT MARQUEE", "Jaws", True), ("MON", "20:00", "ORBIT MARQUEE", "Ghostbusters", False), + ("FRI", "20:00", "DOUBLE BILL", "Terminator Double Bill", False), ("SAT", "19:00", "TRIPLE BILL", "Back to the Future Trilogy", False)] + for i, (dow, t, kind, title, held) in enumerate(bills): + y = 270 + i * 136 + s.rect(1236, y, 568, 124, PANEL, rx=10) + s.text(1258, y + 40, dow, 18, MUTED, BODY, 600) + s.text(1258, y + 84, t, 38, GOLD, COND, 500) + s.text(1360, y + 46, kind, 15, GOLD, BODY, 600, spacing=0.5) + s.text(1360, y + 82, title, 23, WHITE, BODY, 600) + if held: + s.tag(1360, y + 92, "TICKET HELD", MINT, 14) + else: + s.text(1782, y + 108, "OK: take a ticket", 16, GOLD, BODY, 600, "end") + s.end() + s.hints([("OK", "Ticket or big screen"), ("▶", "This week's bills"), ("◀ ▶ ▲ ▼", "Move"), ("Back", "Home")], "Bills come from the Drive-In's own booked calendar") + s.save() + + +def guide(): + s = Screen2("5-tv-guide", "TV Guide, opened on Movies") + s.bar("TV Guide") + s.mock(y=150) + s.group("Category chips (the guide's own filter, restyled)") + x = 96 + for i, label in enumerate(["All Channels", "Entertainment", "Movies", "Comedy", "Cartoons", "Kids", "Documentaries", "Sport"]): + w = int(len(label) * 12) + 40 + on = label == "Movies" + s.rect(x, 154, w, 44, GOLD if on else PANEL, rx=22) + s.text(x + w / 2, 184, label, 21, NAVY if on else WHITE, BODY, 600, "middle") + x += w + 10 + s.end() + s.group("Now and Next preview") + s.rect(96, 222, 1728, 190, DEEP, rx=12) + s.img(124, 246, 192, 60, LOGO["premiere"], "Channel badge L") + s.text(124, 350, "Raiders of the Lost Ark", 34, WHITE, HEAD) + s.text(124, 388, "Premiere · 18:15 to 20:10 · 1981 · 115 min", 21, MUTED) + s.rect(1180, 246, 620, 142, PANEL, rx=10, id="Live picture") + s.text(1490, 324, "Live picture of the focused channel", 20, MUTED, anchor="middle") + s.end() + s.group("Grid") + s.rect(96, 428, 1728, 46, BLUE, rx=6) + s.text(116, 459, "Saturday", 20, WHITE, BODY, 600) + for i, t in enumerate(["18:30", "19:00", "19:30", "20:00"]): + s.text(400 + i * 356, 459, t, 22, WHITE, COND, 500) + s.rect(400 + int(0.4 * 356), 474, 4, 472, GOLD, id="Now line", opacity=0.9) + nx = 400 + int(0.4 * 356) + 2 + s.parts.append(f'') + chans = [("premiere", "301", [("Raiders of the Lost Ark", 0, 1.6), ("The Goonies", 1.6, 2.4)]), + ("scifi", "303", [("Aliens", 0, 2.3), ("Tron", 2.3, 1.7)]), + ("afterdark", "305", [("Night of the Demons", 0, 1.2), ("The Fog", 1.2, 2.8)]), + ("drivein", "300", [("Gates open", 0, 2.9), ("Back to the Future", 2.9, 1.1)])] + for r, (logo, num, progs) in enumerate(chans): + y = 482 + r * 118 + s.group(f"Row {num}") + s.rect(96, y, 296, 110, PANEL, rx=8) + s.text(116, y + 40, num, 22, GOLD, COND, 500) + s.img(170, y + 36, 192, 60, LOGO[logo], "Channel badge") + for j, (title, start, span) in enumerate(progs): + px = 400 + int(start * 356); pw = int(span * 356) - 8 + focused = r == 0 and j == 0 + s.rect(px, y, pw, 110, GOLD if focused else "#0F2C5C", rx=8) + s.text(px + 18, y + 48, title, 23, NAVY if focused else WHITE, BODY, 600) + s.text(px + 18, y + 82, "18:15 to 20:10" if focused else "", 18, NAVY if focused else MUTED) + if focused: + s.focus(px, y, pw, 110, 8) + s.end() + s.end() + s.hints([("OK", "Watch, or details if later"), ("▲ ▼", "Channels"), ("◀ ▶", "Time"), ("▲ at the top", "Categories, then the top bar"), ("Back", "Home")]) + s.save() + + +def nav_map(): + s = Screen2("6-navigation", "Remote navigation between the screens") + s.bar("Home", clock=False) + s.group("Map") + s.text(96, 200, "ONE TOP BAR, FIVE DESTINATIONS, FEW PRESSES", 36, GOLD, HEAD) + s.text(96, 246, "The top bar: ◀ ▶ between the five destinations, ▼ into the screen, ▲ back up to the bar", 21, GOLD, BODY, 600) + top = ["Home", "What's On", "TV Guide", "Drive-In", "Arcade"] + for k, label in enumerate(top): + x = 96 + k * 352 + s.rect(x, 270, 320, 130, PANEL, rx=12, stroke=GOLD if label == "What's On" else BLUE, sw=3 if label == "What's On" else 2) + s.text(x + 160, 346, label, 30, WHITE, BODY, 600, "middle") + if k < 4: + s.text(x + 336, 346, "⇄", 26, GOLD, BODY, 600, "middle") + below = [(1, "Details pop-up", "OK on a card", "Back closes it"), (2, "Live TV (full screen)", "OK on a programme on now", "Back to the guide"), + (3, "Live TV (Drive-In)", "OK on Go to the big screen", "Back to the Drive-In")] + for k, label, down, up in below: + x = 96 + k * 352 + s.rect(x + 158, 400, 4, 130, GOLD, id=f"Arrow to {label}") + s.parts.append(f'') + s.text(x + 172, 446, down, 17, GOLD, BODY, 600) + s.text(x + 172, 474, up, 17, MUTED) + s.rect(x, 544, 320, 130, DEEP, rx=12, stroke=BLUE) + s.text(x + 160, 620, label, 26, WHITE, BODY, 600, "middle") + s.text(96, 620, "Home: OK on a", 19, GOLD, BODY, 600); s.text(96, 646, "category opens the", 19, MUTED); s.text(96, 672, "TV Guide filtered to it", 19, MUTED) + rules = ["Every screen has the same top bar. ▲ from a screen's top row reaches it; ◀ ▶ moves along it; ▼ goes into the screen.", + "Tune in fast: on What's On, OK on a Tonight row that's on now opens the pop-up with Watch live focused, so it's 2 presses.", + "In the TV Guide, OK on a programme on now tunes straight in: 1 press. Home's categories open the TV Guide filtered to them.", + "Back is always one step: the pop-up closes to its card; a screen goes to Home; Home leaves Orbit, as it does today.", + "Focus: 4 px gold ring 3 px outside the item, a 4% lift and a shadow; gold fill on tabs, chips and buttons. 120 ms moves.", + "What's On opens on Tonight's Pick. It is rebuilt once a day at 12:00 from confirmed bookings, never from proposals."] + for i, r in enumerate(rules): + s.text(96, 790 + i * 38, "· " + r, 21, "#E4ECF8") + s.end() + s.save() + + +if __name__ == "__main__": + home(); whats_on(); whats_on("3-whats-on-popup", dim=True); drive_in(); guide(); nav_map() + print("wrote", sorted(p.name for p in OUT.glob("*.svg"))) diff --git a/design/whats-on/v2/1-home.fig b/design/whats-on/v2/1-home.fig new file mode 100644 index 0000000..e3ad842 Binary files /dev/null and b/design/whats-on/v2/1-home.fig differ diff --git a/design/whats-on/v2/1-home.figcraft b/design/whats-on/v2/1-home.figcraft new file mode 100644 index 0000000..7aaf425 Binary files /dev/null and b/design/whats-on/v2/1-home.figcraft differ diff --git a/design/whats-on/v2/1-home.png b/design/whats-on/v2/1-home.png new file mode 100644 index 0000000..34642e4 Binary files /dev/null and b/design/whats-on/v2/1-home.png differ diff --git a/design/whats-on/v2/2-whats-on.fig b/design/whats-on/v2/2-whats-on.fig new file mode 100644 index 0000000..0d4969f Binary files /dev/null and b/design/whats-on/v2/2-whats-on.fig differ diff --git a/design/whats-on/v2/2-whats-on.figcraft b/design/whats-on/v2/2-whats-on.figcraft new file mode 100644 index 0000000..29c8fda Binary files /dev/null and b/design/whats-on/v2/2-whats-on.figcraft differ diff --git a/design/whats-on/v2/2-whats-on.png b/design/whats-on/v2/2-whats-on.png new file mode 100644 index 0000000..06222fe Binary files /dev/null and b/design/whats-on/v2/2-whats-on.png differ diff --git a/design/whats-on/v2/3-whats-on-popup.fig b/design/whats-on/v2/3-whats-on-popup.fig new file mode 100644 index 0000000..0dad5f8 Binary files /dev/null and b/design/whats-on/v2/3-whats-on-popup.fig differ diff --git a/design/whats-on/v2/3-whats-on-popup.figcraft b/design/whats-on/v2/3-whats-on-popup.figcraft new file mode 100644 index 0000000..1486c61 Binary files /dev/null and b/design/whats-on/v2/3-whats-on-popup.figcraft differ diff --git a/design/whats-on/v2/3-whats-on-popup.png b/design/whats-on/v2/3-whats-on-popup.png new file mode 100644 index 0000000..d11ea38 Binary files /dev/null and b/design/whats-on/v2/3-whats-on-popup.png differ diff --git a/design/whats-on/v2/4-drive-in.fig b/design/whats-on/v2/4-drive-in.fig new file mode 100644 index 0000000..290fb4d Binary files /dev/null and b/design/whats-on/v2/4-drive-in.fig differ diff --git a/design/whats-on/v2/4-drive-in.figcraft b/design/whats-on/v2/4-drive-in.figcraft new file mode 100644 index 0000000..05653ec Binary files /dev/null and b/design/whats-on/v2/4-drive-in.figcraft differ diff --git a/design/whats-on/v2/4-drive-in.png b/design/whats-on/v2/4-drive-in.png new file mode 100644 index 0000000..150d85c Binary files /dev/null and b/design/whats-on/v2/4-drive-in.png differ diff --git a/design/whats-on/v2/5-tv-guide.fig b/design/whats-on/v2/5-tv-guide.fig new file mode 100644 index 0000000..b9c41ca Binary files /dev/null and b/design/whats-on/v2/5-tv-guide.fig differ diff --git a/design/whats-on/v2/5-tv-guide.figcraft b/design/whats-on/v2/5-tv-guide.figcraft new file mode 100644 index 0000000..8da2f9a Binary files /dev/null and b/design/whats-on/v2/5-tv-guide.figcraft differ diff --git a/design/whats-on/v2/5-tv-guide.png b/design/whats-on/v2/5-tv-guide.png new file mode 100644 index 0000000..75a67a7 Binary files /dev/null and b/design/whats-on/v2/5-tv-guide.png differ diff --git a/design/whats-on/v2/6-navigation.fig b/design/whats-on/v2/6-navigation.fig new file mode 100644 index 0000000..448472b Binary files /dev/null and b/design/whats-on/v2/6-navigation.fig differ diff --git a/design/whats-on/v2/6-navigation.figcraft b/design/whats-on/v2/6-navigation.figcraft new file mode 100644 index 0000000..ec31665 Binary files /dev/null and b/design/whats-on/v2/6-navigation.figcraft differ diff --git a/design/whats-on/v2/6-navigation.png b/design/whats-on/v2/6-navigation.png new file mode 100644 index 0000000..7df6b3c Binary files /dev/null and b/design/whats-on/v2/6-navigation.png differ