492 lines · 19.7 KB · HTML
RawDownload
<!doctype html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta      name="viewport"      content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content"    />    <meta name="theme-color" content="#0a0a0a" />    <link rel="icon" href="/favicon.ico" sizes="48x48" />    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />    <link rel="manifest" href="/manifest.webmanifest" />    <script>      (() => {        const LIGHT_BACKGROUND = "#ffffff";        const DARK_BACKGROUND = "#0a0a0a";        const CUSTOM_THEMES_STORAGE_KEY = "t3code:themes:v1";        const THEME_FOLLOW_SYSTEM_STORAGE_KEY = "t3code:theme-follow-system";        const THEME_APPEARANCE_MODE_STORAGE_KEY = "t3code:theme-appearance-mode";        const THEME_HALVES_STORAGE_KEY = "t3code:theme-halves:v1";        const SPLASH_COLORS = {          light: {            background: "#ffffff",            foreground: "#262626",            accent: "#4f46e5",          },          dark: {            background: "#0a0a0a",            foreground: "#f5f5f5",            accent: "#818cf8",          },        };        // These are the runtime defaults used to complete a custom palette        // when a stored theme omits a role. Keep them separate from the        // unselected splash so a partial custom theme does not flash generic        // app colors before React mounts.        const DEFAULT_THEME_PALETTES = {          light: {            background: "oklch(0.982446 0.010114 325.653)",            foreground: "oklch(0.325698 0.116116 325.037)",            accent: "oklch(0.591646 0.217985 0.584)",            chrome: "oklch(0.982446 0.010114 325.653)",          },          dark: {            background: "oklch(0.22813 0.020366 307.469)",            foreground: "oklch(0.980735 0.004092 301.426)",            accent: "oklch(0.460685 0.185347 4.099)",            chrome: "oklch(0.22813 0.020366 307.469)",          },        };        // Keep this small boot-time copy in sync with the built-in palettes so        // the selected theme is visible before the app has mounted.        const BUILT_IN_THEME_PALETTES = {          "t3-chat": {            light: {              background: "oklch(0.982446 0.010114 325.653)",              foreground: "oklch(0.325698 0.116116 325.037)",              accent: "oklch(0.591646 0.217985 0.584)",              chrome: "oklch(0.982446 0.010114 325.653)",            },            dark: {              background: "oklch(0.22813 0.020366 307.469)",              foreground: "oklch(0.980735 0.004092 301.426)",              accent: "oklch(0.460685 0.185347 4.099)",              chrome: "oklch(0.22813 0.020366 307.469)",            },          },          grove: {            light: {              background: "oklch(0.972369 0.005497 157.15)",              foreground: "oklch(0.222003 0.03479 328.979)",              accent: "oklch(0.523295 0.112292 158.089)",              chrome: "oklch(0.972369 0.005497 157.15)",            },            dark: {              background: "oklch(0.260865 0.02152 162.75)",              foreground: "oklch(0.990339 0.008411 325.64)",              accent: "oklch(0.796228 0.133058 157.319)",              chrome: "oklch(0.260865 0.02152 162.75)",            },          },          ocean: {            light: {              background: "oklch(0.974199 0.002856 241.597)",              foreground: "oklch(0.222003 0.03479 328.979)",              accent: "oklch(0.536684 0.120219 247.01)",              chrome: "oklch(0.974199 0.002856 241.597)",            },            dark: {              background: "oklch(0.242641 0.024125 250.573)",              foreground: "oklch(0.990339 0.008411 325.64)",              accent: "oklch(0.758933 0.105833 241.548)",              chrome: "oklch(0.242641 0.024125 250.573)",            },          },          ember: {            light: {              background: "oklch(0.976527 0.002685 60.725)",              foreground: "oklch(0.222003 0.03479 328.979)",              accent: "oklch(0.552831 0.129438 44.656)",              chrome: "oklch(0.976527 0.002685 60.725)",            },            dark: {              background: "oklch(0.245899 0.019144 42.044)",              foreground: "oklch(0.990339 0.008411 325.64)",              accent: "oklch(0.762174 0.124117 52.082)",              chrome: "oklch(0.245899 0.019144 42.044)",            },          },          iris: {            light: {              background: "oklch(0.976531 0.003855 303.226)",              foreground: "oklch(0.222003 0.03479 328.979)",              accent: "oklch(0.525348 0.15373 294.176)",              chrome: "oklch(0.976531 0.003855 303.226)",            },            dark: {              background: "oklch(0.225975 0.031062 293.741)",              foreground: "oklch(0.990339 0.008411 325.64)",              accent: "oklch(0.671712 0.169136 293.929)",              chrome: "oklch(0.225975 0.031062 293.741)",            },          },        };        // Keep the built-in mode list in sync with the runtime so the selected        // T3 Chat palette is visible before React has mounted.        const BUILT_IN_THEME_MODES = Object.fromEntries(          Object.entries(BUILT_IN_THEME_PALETTES).map(([id, palettes]) => [            id,            Object.keys(palettes),          ]),        );        const RESERVED_THEME_IDS = [          "system",          "light",          "dark",          "t3-chat",          "grove",          "ocean",          "ember",          "iris",          "t3-chat-dark",          "t3-grove",          "t3-ocean",          "t3-ember",          "t3-iris",        ];        // Update every theme-color meta so any element another layer added        // carries the resolved color too.        const setThemeColor = (color) => {          for (const meta of document.querySelectorAll('meta[name="theme-color"]')) {            meta.setAttribute("content", color);          }        };         // The runtime decodes the same literal CSS formats into OKLCH. Keep        // contextual colors out: they cannot be resolved from stored data.        const SYSTEM_COLOR_KEYWORD =          /^(?:accentcolor(?:text)?|active(?:border|caption|text)|appworkspace|background|button(?:border|face|highlight|shadow|text)|canvas(?:text)?|captiontext|field(?:text)?|graytext|highlight(?:text)?|inactive(?:border|caption(?:text)?)|info(?:background|text)|linktext|mark(?:text)?|menu(?:text)?|scrollbar|selecteditem(?:text)?|threed(?:darkshadow|face|highlight|lightshadow|shadow)|visitedtext|window(?:frame|text)?)$/i;        const isThemeColor = (value) => {          if (typeof value !== "string" || typeof CSS === "undefined") return false;          const color = value.trim();          if (            /^(?:currentcolor|inherit|initial|revert|revert-layer|unset)$/i.test(color) ||            SYSTEM_COLOR_KEYWORD.test(color) ||            /\bfrom\b|(?:var|env|attr|calc|min|max|clamp)\(/i.test(color)          ) {            return false;          }          const isLiteralColor =            /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color) ||            /^[a-z]+$/i.test(color) ||            /^(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\(/i.test(color);          return isLiteralColor && CSS.supports("color", color);        };        const isRecord = (value) =>          typeof value === "object" && value !== null && !Array.isArray(value);        const isThemeId = (value) =>          typeof value === "string" && /^[a-z0-9](?:[a-z0-9-]{0,47})$/.test(value);        const isThemeLabel = (value) =>          typeof value === "string" && value.trim().length > 0 && value.trim().length <= 48;        const isThemePreferenceMode = (value) =>          value === "light" || value === "dark" || value === "system";        const isThemeAppearance = (value) => value === "light" || value === "dark";        const isStoredCustomTheme = (value) => {          if (            !isRecord(value) ||            !isThemeId(value.id) ||            RESERVED_THEME_IDS.includes(value.id) ||            !isThemeLabel(value.label) ||            !isThemeAppearance(value.appearance) ||            !isRecord(value.colors)          ) {            return false;          }          if (value.variants === undefined) return true;          if (!isRecord(value.variants)) return false;          return Object.entries(value.variants).every(            ([appearance, colors]) =>              isThemeAppearance(appearance) &&              (appearance === value.appearance || isRecord(colors)),          );        };        const findCustomTheme = (themeId) => {          if (RESERVED_THEME_IDS.includes(themeId)) return null;          try {            const parsed = JSON.parse(              window.localStorage.getItem(CUSTOM_THEMES_STORAGE_KEY) ?? "null",            );            if (!Array.isArray(parsed)) return null;            return (              parsed.find((value) => isStoredCustomTheme(value) && value.id === themeId) ?? null            );          } catch {            return null;          }        };         try {          const storedTheme = window.localStorage.getItem("t3code:theme");          const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;          // Older builds stored the dark T3 Chat palette as its own theme id          // and every maintainer theme under a t3- prefix; keep those          // preferences readable. Mirrors the runtime's legacy alias table.          const LEGACY_THEME_IDS = {            "t3-chat-dark": "t3-chat",            "t3-grove": "grove",            "t3-ocean": "ocean",            "t3-ember": "ember",            "t3-iris": "iris",          };          const isLegacyT3ChatDark = storedTheme === "t3-chat-dark";          const themeId =            storedTheme === null ? "" : (LEGACY_THEME_IDS[storedTheme] ?? storedTheme);          const legacyMode = isLegacyT3ChatDark ? "dark" : null;          const builtInModes = BUILT_IN_THEME_MODES[themeId] ?? null;          const customTheme = builtInModes ? null : findCustomTheme(themeId);          const themeModes =            builtInModes ??            (customTheme              ? ["light", "dark"].filter(                  (mode) => mode === customTheme.appearance || customTheme.variants?.[mode],                )              : null);          // Mirrors the runtime's isKnownThemePreference.          const isKnownTheme =            storedTheme === "light" ||            storedTheme === "dark" ||            storedTheme === "system" ||            themeModes !== null;          const theme = isKnownTheme && storedTheme ? storedTheme : "system";          const isThemed = isKnownTheme && themeModes !== null;          const baseAppearance = customTheme ? customTheme.appearance : "light";          const systemMode = prefersDark ? "dark" : "light";          const storedAppearanceMode = window.localStorage.getItem(            THEME_APPEARANCE_MODE_STORAGE_KEY,          );          const storedFollowSystem = window.localStorage.getItem(THEME_FOLLOW_SYSTEM_STORAGE_KEY);          // Mirrors the runtime's getThemePreferenceMode fallback: a bare          // "light"/"dark" preference names its own mode.          const preferenceMode =            theme === "light" || theme === "dark" ? theme : (legacyMode ?? baseAppearance);          const appearanceMode = isThemePreferenceMode(storedAppearanceMode)            ? storedAppearanceMode            : storedFollowSystem === "true"              ? "system"              : storedFollowSystem === "false"                ? preferenceMode                : theme === "system"                  ? "system"                  : preferenceMode;          // A valid mix half for the wanted appearance takes over: it decides          // light vs dark even when the base theme cannot render that mode.          // Mirrors the runtime's halves-aware resolveThemeAppearance.          const wantedMode = appearanceMode === "system" ? systemMode : appearanceMode;          let halfThemeId = null;          let halfCustomTheme = null;          try {            const halvesRaw = JSON.parse(              window.localStorage.getItem(THEME_HALVES_STORAGE_KEY) ?? "null",            );            const candidate = isRecord(halvesRaw) ? halvesRaw[wantedMode] : null;            if (typeof candidate === "string") {              const halfId = LEGACY_THEME_IDS[candidate] ?? candidate;              const halfBuiltIn = BUILT_IN_THEME_MODES[halfId] ?? null;              const halfCustom = halfBuiltIn ? null : findCustomTheme(halfId);              const halfModes =                halfBuiltIn ??                (halfCustom                  ? ["light", "dark"].filter(                      (mode) => mode === halfCustom.appearance || halfCustom.variants?.[mode],                    )                  : null);              if (halfModes && halfModes.includes(wantedMode)) {                halfThemeId = halfId;                halfCustomTheme = halfCustom;              }            }          } catch {            // A malformed mix degrades to the base preference.          }          const themeMode = !isThemed            ? null            : appearanceMode === "system"              ? themeModes.includes(systemMode)                ? systemMode                : baseAppearance              : themeModes.includes(appearanceMode)                ? appearanceMode                : baseAppearance;          const isDark =            halfThemeId !== null              ? wantedMode === "dark"              : isThemed                ? themeMode === "dark"                : appearanceMode === "system"                  ? prefersDark                  : appearanceMode === "dark";          const effectiveIsThemed = halfThemeId !== null || isThemed;          const effectiveThemeId = halfThemeId ?? themeId;          const effectiveCustomTheme = halfThemeId !== null ? halfCustomTheme : customTheme;          const effectiveThemeMode = halfThemeId !== null ? wantedMode : themeMode;          const customColors =            effectiveIsThemed && effectiveCustomTheme              ? effectiveThemeMode === effectiveCustomTheme.appearance                ? effectiveCustomTheme.colors                : (effectiveCustomTheme.variants?.[effectiveThemeMode] ??                  effectiveCustomTheme.colors)              : null;          const customDefaults =            effectiveCustomTheme && effectiveThemeMode              ? DEFAULT_THEME_PALETTES[effectiveThemeMode]              : null;          // The runtime tolerates individual malformed colors, so fall back          // per role rather than dropping the theme.          const builtInSplash =            effectiveIsThemed && !effectiveCustomTheme && effectiveThemeMode              ? (BUILT_IN_THEME_PALETTES[effectiveThemeId]?.[effectiveThemeMode] ?? null)              : null;          const fallbackSplash = isDark ? SPLASH_COLORS.dark : SPLASH_COLORS.light;          const customSplash = customColors            ? {                background: isThemeColor(customColors.canvas)                  ? customColors.canvas                  : (customDefaults?.background ?? fallbackSplash.background),                foreground: isThemeColor(customColors.text)                  ? customColors.text                  : (customDefaults?.foreground ?? fallbackSplash.foreground),                accent: isThemeColor(customColors.accent)                  ? customColors.accent                  : (customDefaults?.accent ?? fallbackSplash.accent),              }            : null;          if (effectiveIsThemed) {            document.documentElement.dataset.themeId = effectiveCustomTheme              ? effectiveCustomTheme.id              : effectiveThemeId;          } else {            delete document.documentElement.dataset.themeId;          }          // A resolved half is a selection even when the base theme is gone          // (deleting the base leaves the mix pointing at a real theme).          const hasSelection = halfThemeId !== null || (isKnownTheme && storedTheme !== null);          if (hasSelection) {            document.documentElement.dataset.themeSelected = "true";          } else {            delete document.documentElement.dataset.themeSelected;          }          document.documentElement.classList.toggle("dark", isDark);          const chromeColor = customColors            ? isThemeColor(customColors.chrome)              ? customColors.chrome              : (customDefaults?.chrome ?? fallbackSplash.background)            : builtInSplash              ? builtInSplash.chrome              : isDark                ? DARK_BACKGROUND                : LIGHT_BACKGROUND;          document.documentElement.style.backgroundColor = chromeColor;          if (hasSelection) {            const splashColors = customSplash ?? builtInSplash ?? fallbackSplash;            for (const [name, value] of Object.entries(splashColors)) {              document.documentElement.style.setProperty(`--boot-${name}`, value);            }          }          setThemeColor(chromeColor);        } catch {          // Mirror the runtime's storage-failure fallback: follow the OS.          let prefersDark = true;          try {            prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;          } catch {            // Keep the dark default when even matchMedia is unavailable.          }          delete document.documentElement.dataset.themeId;          delete document.documentElement.dataset.themeSelected;          document.documentElement.classList.toggle("dark", prefersDark);          const fallbackColor = prefersDark ? DARK_BACKGROUND : LIGHT_BACKGROUND;          document.documentElement.style.backgroundColor = fallbackColor;          setThemeColor(fallbackColor);        }      })();    </script>    <style>      html,      body,      #root {        width: 100%;        height: 100%;        margin: 0;      }       body {        background: #ffffff;        color: #262626;        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;      }       html.dark body {        background: #0a0a0a;        color: #f5f5f5;      }       #boot-shell {        position: relative;        overflow: hidden;        display: flex;        min-height: 100%;        align-items: center;        justify-content: center;        background: inherit;        color: inherit;      }       html[data-theme-selected="true"] #boot-shell {        background: var(--boot-background);        color: var(--boot-foreground);      }       #boot-shell-card {        position: relative;        z-index: 1;        display: flex;        align-items: center;        justify-content: center;        width: 96px;        height: 96px;      }       #boot-shell-logo {        width: 64px;        height: 64px;        object-fit: contain;      }       #boot-error {        display: grid;        justify-items: center;        gap: 16px;        max-width: 600px;        padding: 24px;        text-align: center;      }       #boot-error p {        margin: 0;        overflow-wrap: anywhere;      }       #boot-error button {        padding: 8px 16px;        border: 1px solid currentColor;        border-radius: 4px;        background: transparent;        color: inherit;        font: inherit;        cursor: pointer;      }    </style>    <title>T3 Code (Alpha)</title>  </head>  <body>    <div id="root">      <div id="boot-shell">        <div id="boot-shell-card" aria-label="T3 Code splash screen">          <img id="boot-shell-logo" src="/apple-touch-icon.png" alt="T3 Code" />        </div>      </div>    </div>    <script type="module" src="/src/bootstrap.ts"></script>  </body></html>