From 700dbcd2859b6a341a33221d839e7da21264982b Mon Sep 17 00:00:00 2001 From: Renzo F <45401804+rennf93@users.noreply.github.com> Date: Sun, 19 Jul 2026 18:59:54 +0200 Subject: [PATCH] =?UTF-8?q?feat(tg):=20Mini=20App=20V5=20=E2=80=94=20brand?= =?UTF-8?q?=20typography,=20icon=20depth,=20motion,=20detail=20sheets=20(#?= =?UTF-8?q?583)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tg): Mini App V5 — brand typography, icon depth, motion, detail sheets Share Tech Mono (the vendored motion-brand face) becomes the cockpit's display voice via next/font/local scoped to #tg-shell; icon tiles, circle actions, and avatars get gradient/ring depth; a dependency-free motion vocabulary lands (spend count-up, tab rise-in, staggered sections, sparkline draw-in, sheet slide-up with native BackButton dismiss); the Board tab gains a tap-through task sheet (ACs, open findings, PR link), Today's fleet opens a full-roster sheet, and Board/Inbox join the /tg?demo=1 fixtures. * feat(tg): custom RoboCo icon set + operations ring The cockpit stops using stock lucide on its hero surfaces: a hand-drawn duotone icon set (speedometer, seal, bell, kanban, brand-cursor bubble, rocket, double-check, broom, robot head) covers the tab bar and the Today ring. The ring itself stops duplicating the tab bar and becomes real operations: Ship deep-focuses the release proposal in Approvals, Ack all bulk-acknowledges pending notifications, Sweep runs the stale-branch cleanup across every git-configured project behind a confirm sheet, and Fleet opens the roster. --------- Co-authored-by: Renn F --- .../(tg)/fonts/ShareTechMono-Regular.woff2 | Bin 0 -> 7408 bytes panel/src/app/(tg)/layout.tsx | 14 +- panel/src/app/(tg)/tg/page.tsx | 25 +- panel/src/app/globals.css | 83 ++++++ .../components/tasks/mobile-task-board.tsx | 47 +++- .../components/tg/__tests__/motion.test.tsx | 59 ++++ .../tg/__tests__/tg-task-sheet.test.tsx | 135 +++++++++ .../tg/__tests__/tg-today-tab.test.tsx | 126 ++++++++- panel/src/components/tg/charts.tsx | 4 +- panel/src/components/tg/motion.tsx | 105 +++++++ panel/src/components/tg/tg-approvals-tab.tsx | 22 +- panel/src/components/tg/tg-board-tab.tsx | 28 +- panel/src/components/tg/tg-icons.tsx | 175 ++++++++++++ panel/src/components/tg/tg-inbox-tab.tsx | 20 +- panel/src/components/tg/tg-tab-bar.tsx | 35 ++- panel/src/components/tg/tg-task-sheet.tsx | 151 ++++++++++ panel/src/components/tg/tg-today-tab.tsx | 261 +++++++++++++++--- panel/src/components/tg/ui.tsx | 40 +-- panel/src/lib/telegram/demo-data.ts | 238 +++++++++++++++- 19 files changed, 1467 insertions(+), 101 deletions(-) create mode 100644 panel/src/app/(tg)/fonts/ShareTechMono-Regular.woff2 create mode 100644 panel/src/components/tg/__tests__/motion.test.tsx create mode 100644 panel/src/components/tg/__tests__/tg-task-sheet.test.tsx create mode 100644 panel/src/components/tg/motion.tsx create mode 100644 panel/src/components/tg/tg-icons.tsx create mode 100644 panel/src/components/tg/tg-task-sheet.tsx diff --git a/panel/src/app/(tg)/fonts/ShareTechMono-Regular.woff2 b/panel/src/app/(tg)/fonts/ShareTechMono-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..24081c3ac1bf9e4fcc53c24b4a4934b4bcb94a1d GIT binary patch literal 7408 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 literal 0 HcmV?d00001 diff --git a/panel/src/app/(tg)/layout.tsx b/panel/src/app/(tg)/layout.tsx index 8a5841a1..f746a6e0 100644 --- a/panel/src/app/(tg)/layout.tsx +++ b/panel/src/app/(tg)/layout.tsx @@ -1,4 +1,16 @@ import Script from "next/script"; +import localFont from "next/font/local"; + +// The brand display face — the same vendored Share Tech Mono the motion/ +// video compositions use for their headline moments. Exposed as a CSS +// variable on the shell so `.tg-display` (globals.css) can reach it; body +// text stays the root layout's Inter. +const shareTechMono = localFont({ + src: "./fonts/ShareTechMono-Regular.woff2", + weight: "400", + variable: "--font-share-tech", + display: "swap", +}); /** * Slim shell for the Telegram Mini App surface (`/tg`) — no Sidebar/Header/ @@ -26,7 +38,7 @@ export default function TelegramLayout({ return (