1export type LoopbackAuthorizationStage = "dev" | "nightly" | "latest";
2
3declare const __T3CODE_BUILD_CHANNEL__: "nightly" | "latest" | undefined;
4
5function resolveLoopbackAuthorizationStage(): LoopbackAuthorizationStage {
6 return typeof __T3CODE_BUILD_CHANNEL__ === "undefined" ? "dev" : __T3CODE_BUILD_CHANNEL__;
7}
8
9const stageBrands = {
10 dev: "T3 Code (Dev)",
11 nightly: "T3 Code (Nightly)",
12 latest: "T3 Code",
13} as const satisfies Record<LoopbackAuthorizationStage, string>;
14
15export function renderLoopbackAuthorizationCompleteHtml(
16 stage: LoopbackAuthorizationStage = resolveLoopbackAuthorizationStage(),
17): string {
18 const stageBrand = stageBrands[stage];
19
20 return `<!doctype html>
21<html lang="en">
22 <head>
23 <meta charset="utf-8" />
24 <meta name="viewport" content="width=device-width, initial-scale=1" />
25 <meta name="color-scheme" content="light dark" />
26 <title>T3 Connect authorization complete</title>
27 <style>
28 :root {
29 color-scheme: light dark;
30 font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
31 background: #f6f7f9;
32 color: #17191f;
33 }
34 * { box-sizing: border-box; }
35 body {
36 min-height: 100vh;
37 margin: 0;
38 display: grid;
39 place-items: center;
40 padding: 32px 16px;
41 background:
42 radial-gradient(48rem 22rem at 50% -8rem, rgba(47, 119, 235, 0.15), transparent),
43 #f6f7f9;
44 }
45 main {
46 width: min(100%, 576px);
47 overflow: hidden;
48 border: 1px solid rgba(23, 25, 31, 0.1);
49 border-radius: 20px;
50 background: rgba(255, 255, 255, 0.94);
51 box-shadow: 0 24px 64px rgba(16, 24, 40, 0.16);
52 }
53 .stage {
54 position: relative;
55 height: 96px;
56 overflow: hidden;
57 padding: 22px 24px;
58 color: white;
59 }
60 .stage-latest {
61 background:
62 radial-gradient(circle at 76% 18%, rgba(136, 204, 255, 0.52), transparent 38%),
63 linear-gradient(135deg, #2468df, #172f82);
64 }
65 .stage-dev {
66 background: linear-gradient(145deg, #5ab8fa 0%, #347ff8 46%, #1939bd 100%);
67 }
68 .stage-dev::before {
69 content: "";
70 position: absolute;
71 inset: 0;
72 opacity: 0.42;
73 background-image:
74 linear-gradient(rgba(234, 246, 255, 0.25) 1px, transparent 1px),
75 linear-gradient(90deg, rgba(234, 246, 255, 0.25) 1px, transparent 1px),
76 linear-gradient(rgba(234, 246, 255, 0.12) 1px, transparent 1px),
77 linear-gradient(90deg, rgba(234, 246, 255, 0.12) 1px, transparent 1px);
78 background-size: 32px 32px, 32px 32px, 8px 8px, 8px 8px;
79 }
80 .stage-nightly {
81 background:
82 radial-gradient(22rem 8rem at 78% 18%, rgba(81, 101, 216, 0.42), transparent 58%),
83 linear-gradient(145deg, #07152f 0%, #151443 52%, #32155b 100%);
84 }
85 .stage-nightly::before {
86 content: "";
87 position: absolute;
88 inset: 0;
89 opacity: 0.78;
90 background-image:
91 radial-gradient(circle at 12px 12px, rgba(228, 234, 255, 0.9) 0 1px, transparent 1.5px),
92 radial-gradient(circle at 38px 28px, rgba(228, 234, 255, 0.58) 0 0.8px, transparent 1.3px),
93 radial-gradient(circle at 58px 9px, rgba(200, 215, 255, 0.72) 0 0.9px, transparent 1.4px);
94 background-size: 72px 48px, 96px 64px, 128px 56px;
95 }
96 .stage::after {
97 content: "";
98 position: absolute;
99 inset: 0;
100 background:
101 radial-gradient(circle at 78% 20%, rgba(210, 255, 255, 0.36), transparent 34%),
102 linear-gradient(to bottom, transparent 24%, rgba(8, 28, 89, 0.38));
103 }
104 .stage-content {
105 position: relative;
106 z-index: 1;
107 height: 100%;
108 display: flex;
109 align-items: center;
110 justify-content: space-between;
111 }
112 .brand {
113 margin: 0;
114 font-size: 10px;
115 font-weight: 700;
116 letter-spacing: 0.2em;
117 text-transform: uppercase;
118 }
119 .brand { color: rgba(255, 255, 255, 0.82); }
120 .content { padding: 30px 32px 34px; }
121 .eyebrow {
122 margin: 0 0 8px;
123 color: #2866cc;
124 font-size: 10px;
125 font-weight: 700;
126 letter-spacing: 0.18em;
127 text-transform: uppercase;
128 }
129 h1 { margin: 0; font-size: clamp(26px, 5vw, 34px); line-height: 1.12; letter-spacing: -0.035em; }
130 .description { margin: 12px 0 0; color: #646975; font-size: 15px; line-height: 1.6; }
131 @media (prefers-color-scheme: dark) {
132 :root { background: #101115; color: #f1f3f7; }
133 body { background: radial-gradient(48rem 22rem at 50% -8rem, rgba(55, 102, 210, 0.2), transparent), #101115; }
134 main { border-color: rgba(255, 255, 255, 0.1); background: rgba(25, 27, 33, 0.96); }
135 .eyebrow { color: #77a8ff; }
136 .description { color: #a8adb8; }
137 }
138 </style>
139 </head>
140 <body>
141 <main>
142 <header class="stage stage-${stage}" data-stage="${stage}">
143 <div class="stage-content">
144 <p class="brand">${stageBrand}</p>
145 </div>
146 </header>
147 <section class="content">
148 <p class="eyebrow">Browser authorization complete</p>
149 <h1>You're connected</h1>
150 <p class="description">Return to your terminal to finish setting up T3 Connect. You can close this window.</p>
151 </section>
152 </main>
153 </body>
154</html>`;
155}