From ad2c84950a76d16ab2849f3fe68a3a8b57874878 Mon Sep 17 00:00:00 2001 From: Jorrin Date: Fri, 8 Mar 2024 21:53:03 +0100 Subject: [PATCH] adjust colors to movie-web --- apps/expo/src/app/(tabs)/_layout.tsx | 8 +- apps/expo/src/app/_layout.tsx | 6 +- apps/expo/src/components/DownloadItem.tsx | 6 +- apps/expo/src/components/SvgTabBarIcon.tsx | 6 +- apps/expo/src/components/TabBarIcon.tsx | 13 +- .../components/player/AudioTrackSelector.tsx | 6 +- .../components/player/CaptionsSelector.tsx | 6 +- .../player/PlaybackSpeedSelector.tsx | 6 +- .../src/components/player/ScraperProcess.tsx | 28 +- .../player/SeasonEpisodeSelector.tsx | 14 +- .../src/components/player/SourceSelector.tsx | 8 +- .../src/components/player/VideoSlider.tsx | 10 +- apps/expo/src/components/ui/Searchbar.tsx | 10 +- apps/expo/src/lib/url.ts | 6 + apps/expo/tailwind.config.ts | 2 +- pnpm-lock.yaml | 19 + tooling/tailwind/base.ts | 12 - tooling/tailwind/colors.ts | 40 -- tooling/tailwind/native.ts | 26 +- tooling/tailwind/package.json | 6 +- tooling/tailwind/themes/all.ts | 11 + tooling/tailwind/themes/default.ts | 352 ++++++++++++++++++ tooling/tailwind/themes/index.ts | 9 + tooling/tailwind/themes/list/blue.ts | 259 +++++++++++++ tooling/tailwind/themes/list/gray.ts | 259 +++++++++++++ tooling/tailwind/themes/list/red.ts | 259 +++++++++++++ tooling/tailwind/themes/list/teal.ts | 259 +++++++++++++ tooling/tailwind/themes/types.ts | 18 + tooling/tailwind/web.ts | 40 -- 29 files changed, 1537 insertions(+), 167 deletions(-) create mode 100644 apps/expo/src/lib/url.ts delete mode 100644 tooling/tailwind/base.ts delete mode 100644 tooling/tailwind/colors.ts create mode 100644 tooling/tailwind/themes/all.ts create mode 100644 tooling/tailwind/themes/default.ts create mode 100644 tooling/tailwind/themes/index.ts create mode 100644 tooling/tailwind/themes/list/blue.ts create mode 100644 tooling/tailwind/themes/list/gray.ts create mode 100644 tooling/tailwind/themes/list/red.ts create mode 100644 tooling/tailwind/themes/list/teal.ts create mode 100644 tooling/tailwind/themes/types.ts delete mode 100644 tooling/tailwind/web.ts diff --git a/apps/expo/src/app/(tabs)/_layout.tsx b/apps/expo/src/app/(tabs)/_layout.tsx index 7bde24d..9ec283b 100644 --- a/apps/expo/src/app/(tabs)/_layout.tsx +++ b/apps/expo/src/app/(tabs)/_layout.tsx @@ -4,7 +4,7 @@ import * as Haptics from "expo-haptics"; import { Tabs } from "expo-router"; import * as ScreenOrientation from "expo-screen-orientation"; -import Colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { MovieWebSvg } from "~/components/Icon"; import SvgTabBarIcon from "~/components/SvgTabBarIcon"; @@ -19,7 +19,7 @@ export default function TabLayout() { ({ tabPress: () => { @@ -38,9 +38,9 @@ export default function TabLayout() { })} screenOptions={{ headerShown: false, - tabBarActiveTintColor: Colors.primary[100], + tabBarActiveTintColor: defaultTheme.extend.colors.tabBar.active, tabBarStyle: { - backgroundColor: Colors.secondary[700], + backgroundColor: defaultTheme.extend.colors.tabBar.background, borderTopColor: "transparent", borderTopRightRadius: 20, borderTopLeftRadius: 20, diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx index f146f34..dfbba6c 100644 --- a/apps/expo/src/app/_layout.tsx +++ b/apps/expo/src/app/_layout.tsx @@ -12,10 +12,10 @@ import { } from "@react-navigation/native"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import Colors from "@movie-web/tailwind-config/colors"; - import "../styles/global.css"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; + export { // Catch any errors thrown by the Layout component. ErrorBoundary, @@ -83,7 +83,7 @@ function RootLayoutNav() { presentation: "card", headerShown: false, contentStyle: { - backgroundColor: Colors.background, + backgroundColor: defaultTheme.extend.colors.background.main, }, }} > diff --git a/apps/expo/src/components/DownloadItem.tsx b/apps/expo/src/components/DownloadItem.tsx index 6c2616c..a3432de 100644 --- a/apps/expo/src/components/DownloadItem.tsx +++ b/apps/expo/src/components/DownloadItem.tsx @@ -2,7 +2,7 @@ import React from "react"; import { Text, View } from "react-native"; import { Bar as ProgressBar } from "react-native-progress"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; export interface DownloadItemProps { filename: string; @@ -38,8 +38,8 @@ export const DownloadItem: React.FC = ({ ; export default function TabBarIcon({ focused, ...rest }: Props) { - return ( - - ); + const color = focused + ? defaultTheme.extend.colors.tabBar.active + : defaultTheme.extend.colors.tabBar.inactive; + return ; } diff --git a/apps/expo/src/components/player/AudioTrackSelector.tsx b/apps/expo/src/components/player/AudioTrackSelector.tsx index d5db38a..91d46e8 100644 --- a/apps/expo/src/components/player/AudioTrackSelector.tsx +++ b/apps/expo/src/components/player/AudioTrackSelector.tsx @@ -3,7 +3,7 @@ import { Pressable, ScrollView, View } from "react-native"; import Modal from "react-native-modal"; import { MaterialCommunityIcons } from "@expo/vector-icons"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { useAudioTrack } from "~/hooks/player/useAudioTrack"; import { useBoolean } from "~/hooks/useBoolean"; @@ -62,7 +62,7 @@ export const AudioTrackSelector = () => { } /> @@ -97,7 +97,7 @@ export const AudioTrackSelector = () => { )} diff --git a/apps/expo/src/components/player/CaptionsSelector.tsx b/apps/expo/src/components/player/CaptionsSelector.tsx index d3b4474..50721b5 100644 --- a/apps/expo/src/components/player/CaptionsSelector.tsx +++ b/apps/expo/src/components/player/CaptionsSelector.tsx @@ -6,7 +6,7 @@ import { MaterialCommunityIcons } from "@expo/vector-icons"; import { parse } from "subsrt-ts"; import type { Stream } from "@movie-web/provider-utils"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { useBoolean } from "~/hooks/useBoolean"; import { useCaptionsStore } from "~/stores/captions"; @@ -59,7 +59,7 @@ export const CaptionsSelector = () => { } /> @@ -90,7 +90,7 @@ export const CaptionsSelector = () => { ))} diff --git a/apps/expo/src/components/player/PlaybackSpeedSelector.tsx b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx index e78ae91..a1254f6 100644 --- a/apps/expo/src/components/player/PlaybackSpeedSelector.tsx +++ b/apps/expo/src/components/player/PlaybackSpeedSelector.tsx @@ -2,7 +2,7 @@ import { Pressable, ScrollView, View } from "react-native"; import Modal from "react-native-modal"; import { MaterialCommunityIcons } from "@expo/vector-icons"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed"; import { useBoolean } from "~/hooks/useBoolean"; @@ -27,7 +27,7 @@ export const PlaybackSpeedSelector = () => { } /> @@ -59,7 +59,7 @@ export const PlaybackSpeedSelector = () => { )} diff --git a/apps/expo/src/components/player/ScraperProcess.tsx b/apps/expo/src/components/player/ScraperProcess.tsx index 76a899c..2528094 100644 --- a/apps/expo/src/components/player/ScraperProcess.tsx +++ b/apps/expo/src/components/player/ScraperProcess.tsx @@ -18,6 +18,7 @@ import { fetchMediaDetails, fetchSeasonDetails } from "@movie-web/tmdb"; import type { ItemData } from "../item/item"; import type { AudioTrack } from "./AudioTrackSelector"; +import { constructFullUrl } from "~/lib/url"; import { PlayerStatus } from "~/stores/player/slices/interface"; import { usePlayerStore } from "~/stores/player/store"; import { Text } from "../ui/Text"; @@ -64,14 +65,16 @@ export const ScraperProcess = ({ data }: ScraperProcessProps) => { setCheckedSource(event); setScrapeStatus({ status: ScrapeStatus.LOADING, progress: 10 }); } else if (isUpdateEvent(event)) { + console.log(event.status); switch (event.status) { - case ScrapeStatus.SUCCESS: + case "success": setScrapeStatus({ status: ScrapeStatus.SUCCESS, progress: 100 }); break; - case ScrapeStatus.ERROR as string: + case "failure": setScrapeStatus({ status: ScrapeStatus.ERROR, progress: 0 }); break; - case ScrapeStatus.LOADING as string: + case "pending": + case "notfound": } setCheckedSource(event.id); } else if (isInitEvent(event) || isDiscoverEmbedsEvent(event)) { @@ -131,7 +134,7 @@ export const ScraperProcess = ({ data }: ScraperProcessProps) => { const streamResult = await getVideoStream({ media: scrapeMedia, events: { - // init: handleEvent, + init: handleEvent, update: handleEvent, discoverEmbeds: handleEvent, start: handleEvent, @@ -151,27 +154,16 @@ export const ScraperProcess = ({ data }: ScraperProcessProps) => { if (tracks) setHlsTracks(tracks); - const constructFullUrl = (playlistUrl: string, uri: string) => { - const baseUrl = playlistUrl.substring( - 0, - playlistUrl.lastIndexOf("/") + 1, - ); - return uri.startsWith("http://") || uri.startsWith("https://") - ? uri - : baseUrl + uri; - }; - if (tracks?.audio.length) { const audioTracks: AudioTrack[] = tracks.audio.map((track) => ({ uri: constructFullUrl( (streamResult.stream as HlsBasedStream).playlist, track.uri, ), - name: (track.properties[0]?.attributes.name as string) ?? "Unknown", + name: track.properties[0]?.attributes.name?.toString() ?? "Unknown", language: - (track.properties[0]?.attributes.language as string) ?? "Unknown", - active: - (track.properties[0]?.attributes.default as boolean) ?? false, + track.properties[0]?.attributes.language?.toString() ?? "Unknown", + active: Boolean(track.properties[0]?.attributes.default) ?? false, })); const uniqueTracks = new Set(audioTracks.map((t) => t.language)); diff --git a/apps/expo/src/components/player/SeasonEpisodeSelector.tsx b/apps/expo/src/components/player/SeasonEpisodeSelector.tsx index e364140..2e2a958 100644 --- a/apps/expo/src/components/player/SeasonEpisodeSelector.tsx +++ b/apps/expo/src/components/player/SeasonEpisodeSelector.tsx @@ -9,7 +9,7 @@ import Modal from "react-native-modal"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { useQuery } from "@tanstack/react-query"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { fetchMediaDetails, fetchSeasonDetails } from "@movie-web/tmdb"; import { useBoolean } from "~/hooks/useBoolean"; @@ -45,7 +45,10 @@ const EpisodeSelector = ({ <> {isLoading && ( - + )} {data && ( @@ -120,7 +123,7 @@ export const SeasonSelector = () => { } /> @@ -140,7 +143,10 @@ export const SeasonSelector = () => { <> {isLoading && ( - + )} {data && ( diff --git a/apps/expo/src/components/player/SourceSelector.tsx b/apps/expo/src/components/player/SourceSelector.tsx index b409c44..4badc5f 100644 --- a/apps/expo/src/components/player/SourceSelector.tsx +++ b/apps/expo/src/components/player/SourceSelector.tsx @@ -4,7 +4,7 @@ import Modal from "react-native-modal"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { getBuiltinSources, providers } from "@movie-web/provider-utils"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { useEmbedScrape, @@ -55,14 +55,14 @@ const SourceItem = ({ )} {isError && ( )} {isPending && } @@ -141,7 +141,7 @@ export const SourceSelector = () => { } /> diff --git a/apps/expo/src/components/player/VideoSlider.tsx b/apps/expo/src/components/player/VideoSlider.tsx index 41b692b..08f416f 100644 --- a/apps/expo/src/components/player/VideoSlider.tsx +++ b/apps/expo/src/components/player/VideoSlider.tsx @@ -17,7 +17,7 @@ import Animated, { useSharedValue, } from "react-native-reanimated"; -import colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import { usePlayerStore } from "~/stores/player/store"; @@ -132,7 +132,7 @@ const VideoSlider = ({ onSlidingComplete }: VideoSliderProps) => { { height: trackSize_, borderRadius: trackSize_, - backgroundColor: colors.secondary[700], + backgroundColor: defaultTheme.extend.colors.video.context.slider, width, }, ]} @@ -142,7 +142,8 @@ const VideoSlider = ({ onSlidingComplete }: VideoSliderProps) => { { position: "absolute", height: trackSize_, - backgroundColor: colors.primary[300], + backgroundColor: + defaultTheme.extend.colors.video.context.sliderFilled, borderRadius: trackSize_ / 2, }, progressStyle, @@ -160,7 +161,8 @@ const VideoSlider = ({ onSlidingComplete }: VideoSliderProps) => { height: knobSize_, width: knobSize_, borderRadius: knobSize_ / 2, - backgroundColor: colors.primary[300], + backgroundColor: + defaultTheme.extend.colors.video.context.sliderFilled, }, scrollTranslationStyle, ]} diff --git a/apps/expo/src/components/ui/Searchbar.tsx b/apps/expo/src/components/ui/Searchbar.tsx index b5348b3..33c7a72 100644 --- a/apps/expo/src/components/ui/Searchbar.tsx +++ b/apps/expo/src/components/ui/Searchbar.tsx @@ -2,7 +2,7 @@ import { useContext, useEffect, useRef, useState } from "react"; import { TextInput, View } from "react-native"; import { FontAwesome5 } from "@expo/vector-icons"; -import Colors from "@movie-web/tailwind-config/colors"; +import { defaultTheme } from "@movie-web/tailwind-config/themes"; import SearchTabContext from "./SearchTabContext"; @@ -30,14 +30,18 @@ export function SearchBar({ return ( - + diff --git a/apps/expo/src/lib/url.ts b/apps/expo/src/lib/url.ts new file mode 100644 index 0000000..4be06d0 --- /dev/null +++ b/apps/expo/src/lib/url.ts @@ -0,0 +1,6 @@ +export const constructFullUrl = (playlistUrl: string, uri: string) => { + const baseUrl = playlistUrl.substring(0, playlistUrl.lastIndexOf("/") + 1); + return uri.startsWith("http://") || uri.startsWith("https://") + ? uri + : baseUrl + uri; +}; diff --git a/apps/expo/tailwind.config.ts b/apps/expo/tailwind.config.ts index 88e92ba..c1776a7 100644 --- a/apps/expo/tailwind.config.ts +++ b/apps/expo/tailwind.config.ts @@ -7,8 +7,8 @@ import baseConfig from "@movie-web/tailwind-config/native"; export default { content: ["./src/**/*.{ts,tsx}"], presets: [ - baseConfig, nativewind, + baseConfig, { theme: { extend: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6bac5c..5ab7921 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,6 +345,9 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.1) + tailwindcss-themer: + specifier: ^4.0.0 + version: 4.0.0(tailwindcss@3.4.1) devDependencies: '@movie-web/eslint-config': specifier: workspace:^0.2.0 @@ -7387,6 +7390,10 @@ packages: object.values: 1.1.7 dev: false + /just-unique@4.2.0: + resolution: {integrity: sha512-cxQGGUiit6CGUpuuiezY8N4m1wgF4o7127rXEXDFcxeDUFfdV7gSkwA26Fe2wWBiNQq2SZOgN4gSmMxB/StA8Q==} + dev: false + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -10422,6 +10429,18 @@ packages: tailwindcss: 3.4.1 dev: false + /tailwindcss-themer@4.0.0(tailwindcss@3.4.1): + resolution: {integrity: sha512-kngKDW+z36JtjvaNziX0aesO95r8f5+3FFdANVFDt1uzNHZsL6XLla1YDK6EBAYFqPichoPDbO4lrrTyB+UAbA==} + peerDependencies: + tailwindcss: ^3.1.0 + dependencies: + color: 4.2.3 + just-unique: 4.2.0 + lodash.merge: 4.6.2 + lodash.mergewith: 4.6.2 + tailwindcss: 3.4.1 + dev: false + /tailwindcss@3.4.1: resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} engines: {node: '>=14.0.0'} diff --git a/tooling/tailwind/base.ts b/tooling/tailwind/base.ts deleted file mode 100644 index e703270..0000000 --- a/tooling/tailwind/base.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Config } from "tailwindcss"; - -import colors from "./colors"; - -export default { - content: ["src/**/*.{ts,tsx}"], - theme: { - extend: { - colors, - }, - }, -} satisfies Config; diff --git a/tooling/tailwind/colors.ts b/tooling/tailwind/colors.ts deleted file mode 100644 index 65ab5eb..0000000 --- a/tooling/tailwind/colors.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { - black, - blue, - gray, - green, - indigo, - pink, - purple, - red, - white, - yellow, -} from "tailwindcss/colors"; - -export default { - black: black, - white: white, - gray: gray, - red: red, - yellow: yellow, - green: green, - blue: blue, - indigo: indigo, - purple: purple, - pink: pink, - primary: { - 100: "#C082FF", - 300: "#8D44D6", - 400: "#7831BF", - }, - secondary: { - 50: "#676790", - 200: "#3F3F60", - 300: "#32324F", - 700: "#131322", - }, - playerSettings: { - captionBackground: "#161b23", - }, - background: "#0a0a12", -}; diff --git a/tooling/tailwind/native.ts b/tooling/tailwind/native.ts index da3cdb8..bce7d16 100644 --- a/tooling/tailwind/native.ts +++ b/tooling/tailwind/native.ts @@ -1,14 +1,22 @@ import type { Config } from "tailwindcss"; +import themer from "tailwindcss-themer"; -import base from "./base"; -import colors from "./colors"; +import { allThemes, defaultTheme, safeThemeList } from "./themes"; export default { - content: base.content, - presets: [base], - theme: { - extend: { - colors, - }, - }, + content: ["src/**/*.{ts,tsx}"], + safelist: safeThemeList, + plugins: [ + themer({ + defaultTheme, + themes: [ + { + name: "default", + selectors: [".theme-default"], + ...defaultTheme, + }, + ...allThemes, + ], + }), + ], } satisfies Config; diff --git a/tooling/tailwind/package.json b/tooling/tailwind/package.json index df4dcc9..63a93ac 100644 --- a/tooling/tailwind/package.json +++ b/tooling/tailwind/package.json @@ -5,8 +5,7 @@ "type": "module", "exports": { "./native": "./native.ts", - "./web": "./web.ts", - "./colors": "./colors.ts" + "./themes": "./themes/index.ts" }, "license": "MIT", "scripts": { @@ -19,7 +18,8 @@ "autoprefixer": "^10.4.17", "postcss": "^8.4.32", "tailwindcss": "^3.4.0", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "tailwindcss-themer": "^4.0.0" }, "devDependencies": { "@movie-web/eslint-config": "workspace:^0.2.0", diff --git a/tooling/tailwind/themes/all.ts b/tooling/tailwind/themes/all.ts new file mode 100644 index 0000000..f59aac8 --- /dev/null +++ b/tooling/tailwind/themes/all.ts @@ -0,0 +1,11 @@ +import teal from "./list/teal"; +import blue from "./list/blue"; +import red from "./list/red"; +import gray from "./list/gray"; + +export const allThemes = [ + teal, + blue, + gray, + red +] diff --git a/tooling/tailwind/themes/default.ts b/tooling/tailwind/themes/default.ts new file mode 100644 index 0000000..a520f9f --- /dev/null +++ b/tooling/tailwind/themes/default.ts @@ -0,0 +1,352 @@ +const tokens = { + black: "#000000", + white: "#FFFFFF", + semantic: { + red: { + c100: "#F46E6E", + c200: "#E44F4F", + c300: "#D74747", + c400: "#B43434", + }, + green: { + c100: "#60D26A", + c200: "#40B44B", + c300: "#31A33C", + c400: "#237A2B", + }, + silver: { + c100: "#DEDEDE", + c200: "#B6CAD7", + c300: "#8EA3B0", + c400: "#617A8A", + }, + yellow: { + c100: "#FFF599", + c200: "#FCEC61", + c300: "#D8C947", + c400: "#AFA349", + }, + rose: { + c100: "#DB3D61", + c200: "#8A293B", + c300: "#812435", + c400: "#701B2B", + }, + }, + blue: { + c50: "#ADADF5", + c100: "#7979CC", + c200: "#5D5DAE", + c300: "#3B3B8C", + c400: "#2A2A71", + c500: "#1F1F50", + c600: "#1B1B41", + c700: "#171736", + c800: "#101020", + c900: "#0B0B13", + }, + purple: { + c50: "#D5AAFF", + c100: "#C082FF", + c200: "#A359EC", + c300: "#8D44D6", + c400: "#7831BF", + c500: "#572887", + c600: "#411F64", + c700: "#31184A", + c800: "#221134", + c900: "#160B22", + }, + ash: { + c50: "#7F8D9B", + c100: "#5B6B7B", + c200: "#445464", + c300: "#2B3D4E", + c400: "#203242", + c500: "#1C2C3C", + c600: "#172532", + c700: "#131E29", + c800: "#101820", + c900: "#0C1216", + }, + shade: { + c50: "#676790", + c100: "#52527A", + c200: "#3F3F60", + c300: "#32324F", + c400: "#272741", + c500: "#1E1E32", + c600: "#171728", + c700: "#131322", + c800: "#0F0F1B", + c900: "#0A0A12", + }, +}; + +export const defaultTheme = { + extend: { + colors: { + themePreview: { + primary: tokens.blue.c200, + secondary: tokens.shade.c50, + ghost: tokens.white, + }, + + // Branding + pill: { + background: tokens.shade.c300, + backgroundHover: tokens.shade.c200, + highlight: tokens.blue.c200, + + activeBackground: tokens.shade.c300, + }, + + // meta data for the theme itself + global: { + accentA: tokens.blue.c200, + accentB: tokens.blue.c300, + }, + + // light bar + lightBar: { + light: tokens.blue.c400, + }, + + // Buttons + buttons: { + toggle: tokens.purple.c300, + toggleDisabled: tokens.ash.c500, + danger: tokens.semantic.rose.c300, + dangerHover: tokens.semantic.rose.c200, + + secondary: tokens.ash.c700, + secondaryText: tokens.semantic.silver.c300, + secondaryHover: tokens.ash.c700, + primary: tokens.white, + primaryText: tokens.black, + primaryHover: tokens.semantic.silver.c100, + purple: tokens.purple.c500, + purpleHover: tokens.purple.c400, + cancel: tokens.ash.c500, + cancelHover: tokens.ash.c300, + }, + + // only used for body colors/textures + background: { + main: tokens.shade.c900, + secondary: tokens.shade.c600, + secondaryHover: tokens.shade.c400, + accentA: tokens.purple.c500, + accentB: tokens.blue.c500, + }, + + // Modals + modal: { + background: tokens.shade.c800, + }, + + // typography + type: { + logo: tokens.purple.c100, + emphasis: tokens.white, + text: tokens.shade.c50, + dimmed: tokens.shade.c50, + divider: tokens.ash.c500, + secondary: tokens.ash.c100, + danger: tokens.semantic.red.c100, + success: tokens.semantic.green.c100, + link: tokens.purple.c100, + linkHover: tokens.purple.c50, + }, + + // search bar + search: { + background: tokens.shade.c500, + hoverBackground: tokens.shade.c600, + focused: tokens.shade.c400, + placeholder: tokens.shade.c100, + icon: tokens.shade.c100, + text: tokens.white, + }, + + // media cards + mediaCard: { + hoverBackground: tokens.shade.c600, + hoverAccent: tokens.shade.c50, + hoverShadow: tokens.shade.c900, + shadow: tokens.shade.c700, + barColor: tokens.ash.c200, + barFillColor: tokens.purple.c100, + badge: tokens.shade.c700, + badgeText: tokens.ash.c100, + }, + + // Large card + largeCard: { + background: tokens.shade.c600, + icon: tokens.purple.c400, + }, + + // Dropdown + dropdown: { + background: tokens.shade.c600, + altBackground: tokens.shade.c700, + hoverBackground: tokens.shade.c500, + highlight: tokens.semantic.yellow.c400, + highlightHover: tokens.semantic.yellow.c200, + text: tokens.shade.c50, + secondary: tokens.shade.c100, + border: tokens.shade.c400, + contentBackground: tokens.shade.c500, + }, + + // Passphrase + authentication: { + border: tokens.shade.c300, + inputBg: tokens.shade.c600, + inputBgHover: tokens.shade.c500, + wordBackground: tokens.shade.c500, + copyText: tokens.shade.c100, + copyTextHover: tokens.ash.c50, + errorText: tokens.semantic.rose.c100, + }, + + // Settings page + settings: { + sidebar: { + activeLink: tokens.shade.c600, + badge: tokens.shade.c900, + + type: { + secondary: tokens.shade.c200, + inactive: tokens.shade.c50, + icon: tokens.shade.c50, + iconActivated: tokens.purple.c200, + activated: tokens.purple.c50, + }, + }, + + card: { + border: tokens.shade.c400, + background: tokens.shade.c400, + altBackground: tokens.shade.c400, + }, + + saveBar: { + background: tokens.shade.c800, + }, + }, + + // Utilities + utils: { + divider: tokens.ash.c300, + }, + + // Onboarding + onboarding: { + bar: tokens.shade.c400, + barFilled: tokens.purple.c300, + divider: tokens.shade.c200, + card: tokens.shade.c800, + cardHover: tokens.shade.c700, + border: tokens.shade.c600, + good: tokens.purple.c100, + best: tokens.semantic.yellow.c100, + link: tokens.purple.c100, + }, + + // Error page + errors: { + card: tokens.shade.c800, + border: tokens.ash.c500, + + type: { + secondary: tokens.ash.c100, + }, + }, + + // About page + about: { + circle: tokens.ash.c500, + circleText: tokens.ash.c50, + }, + + // About page + editBadge: { + bg: tokens.ash.c500, + bgHover: tokens.ash.c400, + text: tokens.ash.c50, + }, + + progress: { + background: tokens.ash.c50, + preloaded: tokens.ash.c50, + filled: tokens.purple.c200, + }, + + // video player + video: { + buttonBackground: tokens.ash.c200, + + autoPlay: { + background: tokens.ash.c700, + hover: tokens.ash.c500, + }, + + scraping: { + card: tokens.shade.c700, + error: tokens.semantic.red.c200, + success: tokens.semantic.green.c200, + loading: tokens.purple.c200, + noresult: tokens.ash.c100, + }, + + audio: { + set: tokens.purple.c200, + }, + + context: { + background: tokens.ash.c900, + light: tokens.shade.c50, + border: tokens.ash.c600, + hoverColor: tokens.ash.c600, + buttonFocus: tokens.ash.c500, + flagBg: tokens.ash.c500, + inputBg: tokens.ash.c600, + buttonOverInputHover: tokens.ash.c500, + inputPlaceholder: tokens.ash.c200, + cardBorder: tokens.ash.c700, + slider: tokens.ash.c50, + sliderFilled: tokens.purple.c200, + error: tokens.semantic.red.c200, + + buttons: { + list: tokens.ash.c700, + active: tokens.ash.c900, + }, + + closeHover: tokens.ash.c800, + + type: { + main: tokens.semantic.silver.c400, + secondary: tokens.ash.c200, + accent: tokens.purple.c200, + }, + }, + }, + + // tabBar + tabBar: { + background: tokens.shade.c700, + active: tokens.purple.c200, + inactive: tokens.shade.c300, + }, + + // download + download: { + progress: tokens.ash.c50, + progressFilled: tokens.purple.c200, + }, + }, + }, +}; diff --git a/tooling/tailwind/themes/index.ts b/tooling/tailwind/themes/index.ts new file mode 100644 index 0000000..04b121b --- /dev/null +++ b/tooling/tailwind/themes/index.ts @@ -0,0 +1,9 @@ +import { allThemes } from "./all"; + +export { defaultTheme } from "./default"; +export { allThemes } from "./all"; + +export const safeThemeList = allThemes + .flatMap(v=>v.selectors) + .filter(v=>v.startsWith(".")) + .map(v=>v.slice(1)); // remove dot from selector diff --git a/tooling/tailwind/themes/list/blue.ts b/tooling/tailwind/themes/list/blue.ts new file mode 100644 index 0000000..4266b3c --- /dev/null +++ b/tooling/tailwind/themes/list/blue.ts @@ -0,0 +1,259 @@ +import { createTheme } from "../types"; + +const tokens = { + purple: { + c50: "#aac5ff", + c100: "#82a9ff", + c200: "#4681ff", + c300: "#1a63ff", + c400: "#054eec", + c500: "#083aa7", + c600: "#072c7c", + c700: "#06215d", + c800: "#041741", + c900: "#03102a" + }, + shade: { + c50: "#756790", + c100: "#60527a", + c200: "#4a3f60", + c300: "#3c324f", + c400: "#302741", + c500: "#251e32", + c600: "#1d1728", + c700: "#181322", + c800: "#130f1b", + c900: "#0d0a12" + }, + ash: { + c50: "#7f859b", + c100: "#5b627b", + c200: "#444b64", + c300: "#2b344e", + c400: "#202842", + c500: "#1c243c", + c600: "#171d32", + c700: "#131829", + c800: "#101420", + c900: "#0c0f16" + }, + blue: { + c50: "#adb4f5", + c100: "#7981cc", + c200: "#5d65ae", + c300: "#3b438c", + c400: "#2a3171", + c500: "#1f2450", + c600: "#1b1f41", + c700: "#171b36", + c800: "#101120", + c900: "#0b0c13" + } +}; + +export default createTheme({ + name: "blue", + extend: { + colors: { + themePreview: { + primary: tokens.blue.c200, + secondary: tokens.shade.c50 + }, + + pill: { + background: tokens.shade.c300, + backgroundHover: tokens.shade.c200, + highlight: tokens.blue.c200, + + activeBackground: tokens.shade.c300, + }, + + global: { + accentA: tokens.blue.c200, + accentB: tokens.blue.c300 + }, + + lightBar: { + light: tokens.blue.c400 + }, + + buttons: { + toggle: tokens.purple.c300, + toggleDisabled: tokens.ash.c500, + + secondary: tokens.ash.c700, + secondaryHover: tokens.ash.c700, + purple: tokens.purple.c500, + purpleHover: tokens.purple.c400, + cancel: tokens.ash.c500, + cancelHover: tokens.ash.c300 + }, + + background: { + main: tokens.shade.c900, + secondary: tokens.shade.c600, + secondaryHover: tokens.shade.c400, + accentA: tokens.purple.c500, + accentB: tokens.blue.c500 + }, + + modal: { + background: tokens.shade.c800, + }, + + type: { + logo: tokens.purple.c100, + text: tokens.shade.c50, + dimmed: tokens.shade.c50, + divider: tokens.ash.c500, + secondary: tokens.ash.c100, + link: tokens.purple.c100, + linkHover: tokens.purple.c50 + }, + + search: { + background: tokens.shade.c500, + hoverBackground: tokens.shade.c600, + focused: tokens.shade.c400, + placeholder: tokens.shade.c100, + icon: tokens.shade.c100 + }, + + mediaCard: { + hoverBackground: tokens.shade.c600, + hoverAccent: tokens.shade.c50, + hoverShadow: tokens.shade.c900, + shadow: tokens.shade.c700, + barColor: tokens.ash.c200, + barFillColor: tokens.purple.c100, + badge: tokens.shade.c700, + badgeText: tokens.ash.c100 + }, + + largeCard: { + background: tokens.shade.c600, + icon: tokens.purple.c400 + }, + + dropdown: { + background: tokens.shade.c600, + altBackground: tokens.shade.c700, + hoverBackground: tokens.shade.c500, + text: tokens.shade.c50, + secondary: tokens.shade.c100, + border: tokens.shade.c400, + contentBackground: tokens.shade.c500 + }, + + authentication: { + border: tokens.shade.c300, + inputBg: tokens.shade.c600, + inputBgHover: tokens.shade.c500, + wordBackground: tokens.shade.c500, + copyText: tokens.shade.c100, + copyTextHover: tokens.ash.c50 + }, + + settings: { + sidebar: { + activeLink: tokens.shade.c600, + badge: tokens.shade.c900, + + type: { + secondary: tokens.shade.c200, + inactive: tokens.shade.c50, + icon: tokens.shade.c50, + iconActivated: tokens.purple.c200, + activated: tokens.purple.c50 + } + }, + + card: { + border: tokens.shade.c400, + background: tokens.shade.c400, + altBackground: tokens.shade.c400 + }, + + saveBar: { + background: tokens.shade.c800 + } + }, + + utils: { + divider: tokens.ash.c300 + }, + + errors: { + card: tokens.shade.c800, + border: tokens.ash.c500, + + type: { + secondary: tokens.ash.c100 + } + }, + + about: { + circle: tokens.ash.c500, + circleText: tokens.ash.c50 + }, + + editBadge: { + bg: tokens.ash.c500, + bgHover: tokens.ash.c400, + text: tokens.ash.c50 + }, + + progress: { + background: tokens.ash.c50, + preloaded: tokens.ash.c50, + filled: tokens.purple.c200 + }, + + video: { + buttonBackground: tokens.ash.c200, + + autoPlay: { + background: tokens.ash.c700, + hover: tokens.ash.c500 + }, + + scraping: { + card: tokens.shade.c700, + loading: tokens.purple.c200, + noresult: tokens.ash.c100 + }, + + audio: { + set: tokens.purple.c200 + }, + + context: { + background: tokens.ash.c900, + light: tokens.shade.c50, + border: tokens.ash.c600, + hoverColor: tokens.ash.c600, + buttonFocus: tokens.ash.c500, + flagBg: tokens.ash.c500, + inputBg: tokens.ash.c600, + buttonOverInputHover: tokens.ash.c500, + inputPlaceholder: tokens.ash.c200, + cardBorder: tokens.ash.c700, + slider: tokens.ash.c50, + sliderFilled: tokens.purple.c200, + + buttons: { + list: tokens.ash.c700, + active: tokens.ash.c900 + }, + + closeHover: tokens.ash.c800, + + type: { + secondary: tokens.ash.c200, + accent: tokens.purple.c200 + } + } + } + } + } +}); diff --git a/tooling/tailwind/themes/list/gray.ts b/tooling/tailwind/themes/list/gray.ts new file mode 100644 index 0000000..bf37f20 --- /dev/null +++ b/tooling/tailwind/themes/list/gray.ts @@ -0,0 +1,259 @@ +import { createTheme } from "../types"; + +const tokens = { + purple: { + c50: "#aaafff", + c100: "#8288fe", + c200: "#5a62eb", + c300: "#454cd4", + c400: "#333abe", + c500: "#292d86", + c600: "#1f2363", + c700: "#191b4a", + c800: "#111334", + c900: "#0b0d22" + }, + shade: { + c50: "#7c7c7c", + c100: "#666666", + c200: "#4f4f4f", + c300: "#404040", + c400: "#343434", + c500: "#282828", + c600: "#202020", + c700: "#1a1a1a", + c800: "#151515", + c900: "#0e0e0e" + }, + ash: { + c50: "#8d8d8d", + c100: "#6b6b6b", + c200: "#545454", + c300: "#3c3c3c", + c400: "#313131", + c500: "#2c2c2c", + c600: "#252525", + c700: "#1e1e1e", + c800: "#181818", + c900: "#111111" + }, + blue: { + c50: "#ccccd6", + c100: "#a2a2a2", + c200: "#868686", + c300: "#646464", + c400: "#4e4e4e", + c500: "#383838", + c600: "#2e2e2e", + c700: "#272727", + c800: "#181818", + c900: "#0f0f0f" + } +}; + +export default createTheme({ + name: "gray", + extend: { + colors: { + themePreview: { + primary: tokens.blue.c200, + secondary: tokens.shade.c50 + }, + + pill: { + background: tokens.shade.c300, + backgroundHover: tokens.shade.c200, + highlight: tokens.blue.c200, + + activeBackground: tokens.shade.c300, + }, + + global: { + accentA: tokens.blue.c200, + accentB: tokens.blue.c300 + }, + + lightBar: { + light: tokens.blue.c400 + }, + + buttons: { + toggle: tokens.purple.c300, + toggleDisabled: tokens.ash.c500, + + secondary: tokens.ash.c700, + secondaryHover: tokens.ash.c700, + purple: tokens.purple.c500, + purpleHover: tokens.purple.c400, + cancel: tokens.ash.c500, + cancelHover: tokens.ash.c300 + }, + + background: { + main: tokens.shade.c900, + secondary: tokens.shade.c600, + secondaryHover: tokens.shade.c400, + accentA: tokens.purple.c500, + accentB: tokens.blue.c500 + }, + + modal: { + background: tokens.shade.c800, + }, + + type: { + logo: tokens.purple.c100, + text: tokens.shade.c50, + dimmed: tokens.shade.c50, + divider: tokens.ash.c500, + secondary: tokens.ash.c100, + link: tokens.purple.c100, + linkHover: tokens.purple.c50 + }, + + search: { + background: tokens.shade.c500, + hoverBackground: tokens.shade.c600, + focused: tokens.shade.c400, + placeholder: tokens.shade.c100, + icon: tokens.shade.c100 + }, + + mediaCard: { + hoverBackground: tokens.shade.c600, + hoverAccent: tokens.shade.c50, + hoverShadow: tokens.shade.c900, + shadow: tokens.shade.c700, + barColor: tokens.ash.c200, + barFillColor: tokens.purple.c100, + badge: tokens.shade.c700, + badgeText: tokens.ash.c100 + }, + + largeCard: { + background: tokens.shade.c600, + icon: tokens.purple.c400 + }, + + dropdown: { + background: tokens.shade.c600, + altBackground: tokens.shade.c700, + hoverBackground: tokens.shade.c500, + text: tokens.shade.c50, + secondary: tokens.shade.c100, + border: tokens.shade.c400, + contentBackground: tokens.shade.c500 + }, + + authentication: { + border: tokens.shade.c300, + inputBg: tokens.shade.c600, + inputBgHover: tokens.shade.c500, + wordBackground: tokens.shade.c500, + copyText: tokens.shade.c100, + copyTextHover: tokens.ash.c50 + }, + + settings: { + sidebar: { + activeLink: tokens.shade.c600, + badge: tokens.shade.c900, + + type: { + secondary: tokens.shade.c200, + inactive: tokens.shade.c50, + icon: tokens.shade.c50, + iconActivated: tokens.purple.c200, + activated: tokens.purple.c50 + } + }, + + card: { + border: tokens.shade.c400, + background: tokens.shade.c400, + altBackground: tokens.shade.c400 + }, + + saveBar: { + background: tokens.shade.c800 + } + }, + + utils: { + divider: tokens.ash.c300 + }, + + errors: { + card: tokens.shade.c800, + border: tokens.ash.c500, + + type: { + secondary: tokens.ash.c100 + } + }, + + about: { + circle: tokens.ash.c500, + circleText: tokens.ash.c50 + }, + + editBadge: { + bg: tokens.ash.c500, + bgHover: tokens.ash.c400, + text: tokens.ash.c50 + }, + + progress: { + background: tokens.ash.c50, + preloaded: tokens.ash.c50, + filled: tokens.purple.c200 + }, + + video: { + buttonBackground: tokens.ash.c200, + + autoPlay: { + background: tokens.ash.c700, + hover: tokens.ash.c500 + }, + + scraping: { + card: tokens.shade.c700, + loading: tokens.purple.c200, + noresult: tokens.ash.c100 + }, + + audio: { + set: tokens.purple.c200 + }, + + context: { + background: tokens.ash.c900, + light: tokens.shade.c50, + border: tokens.ash.c600, + hoverColor: tokens.ash.c600, + buttonFocus: tokens.ash.c500, + flagBg: tokens.ash.c500, + inputBg: tokens.ash.c600, + buttonOverInputHover: tokens.ash.c500, + inputPlaceholder: tokens.ash.c200, + cardBorder: tokens.ash.c700, + slider: tokens.ash.c50, + sliderFilled: tokens.purple.c200, + + buttons: { + list: tokens.ash.c700, + active: tokens.ash.c900 + }, + + closeHover: tokens.ash.c800, + + type: { + secondary: tokens.ash.c200, + accent: tokens.purple.c200 + } + } + } + } + } +}); diff --git a/tooling/tailwind/themes/list/red.ts b/tooling/tailwind/themes/list/red.ts new file mode 100644 index 0000000..5b6fcb4 --- /dev/null +++ b/tooling/tailwind/themes/list/red.ts @@ -0,0 +1,259 @@ +import { createTheme } from "../types"; + +const tokens = { + purple: { + c50: "#feabac", + c100: "#fe8385", + c200: "#ea5b5e", + c300: "#d34648", + c400: "#bd3436", + c500: "#852a2b", + c600: "#632021", + c700: "#49191a", + c800: "#331112", + c900: "#220c0c" + }, + shade: { + c50: "#9c605c", + c100: "#834d49", + c200: "#673b38", + c300: "#542f2c", + c400: "#452422", + c500: "#361c1a", + c600: "#2b1614", + c700: "#241210", + c800: "#1c0e0d", + c900: "#130909" + }, + ash: { + c50: "#ac6e6f", + c100: "#8b4b4c", + c200: "#703739", + c300: "#572225", + c400: "#49191a", + c500: "#421617", + c600: "#371212", + c700: "#2e0e0f", + c800: "#230c0d", + c900: "#19090b" + }, + blue: { + c50: "#f5adb4", + c100: "#cc7981", + c200: "#ae5d65", + c300: "#8c3b43", + c400: "#712a31", + c500: "#501f24", + c600: "#411b1f", + c700: "#36171b", + c800: "#201011", + c900: "#130b0c" + } +}; + +export default createTheme({ + name: "red", + extend: { + colors: { + themePreview: { + primary: tokens.blue.c200, + secondary: tokens.shade.c50 + }, + + pill: { + background: tokens.shade.c300, + backgroundHover: tokens.shade.c200, + highlight: tokens.blue.c200, + + activeBackground: tokens.shade.c300, + }, + + global: { + accentA: tokens.blue.c200, + accentB: tokens.blue.c300 + }, + + lightBar: { + light: tokens.blue.c400 + }, + + buttons: { + toggle: tokens.purple.c300, + toggleDisabled: tokens.ash.c500, + + secondary: tokens.ash.c700, + secondaryHover: tokens.ash.c700, + purple: tokens.purple.c500, + purpleHover: tokens.purple.c400, + cancel: tokens.ash.c500, + cancelHover: tokens.ash.c300 + }, + + background: { + main: tokens.shade.c900, + secondary: tokens.shade.c600, + secondaryHover: tokens.shade.c400, + accentA: tokens.purple.c500, + accentB: tokens.blue.c500 + }, + + modal: { + background: tokens.shade.c800, + }, + + type: { + logo: tokens.purple.c100, + text: tokens.shade.c50, + dimmed: tokens.shade.c50, + divider: tokens.ash.c500, + secondary: tokens.ash.c100, + link: tokens.purple.c100, + linkHover: tokens.purple.c50 + }, + + search: { + background: tokens.shade.c500, + hoverBackground: tokens.shade.c600, + focused: tokens.shade.c400, + placeholder: tokens.shade.c100, + icon: tokens.shade.c100 + }, + + mediaCard: { + hoverBackground: tokens.shade.c600, + hoverAccent: tokens.shade.c50, + hoverShadow: tokens.shade.c900, + shadow: tokens.shade.c700, + barColor: tokens.ash.c200, + barFillColor: tokens.purple.c100, + badge: tokens.shade.c700, + badgeText: tokens.ash.c100 + }, + + largeCard: { + background: tokens.shade.c600, + icon: tokens.purple.c400 + }, + + dropdown: { + background: tokens.shade.c600, + altBackground: tokens.shade.c700, + hoverBackground: tokens.shade.c500, + text: tokens.shade.c50, + secondary: tokens.shade.c100, + border: tokens.shade.c400, + contentBackground: tokens.shade.c500 + }, + + authentication: { + border: tokens.shade.c300, + inputBg: tokens.shade.c600, + inputBgHover: tokens.shade.c500, + wordBackground: tokens.shade.c500, + copyText: tokens.shade.c100, + copyTextHover: tokens.ash.c50 + }, + + settings: { + sidebar: { + activeLink: tokens.shade.c600, + badge: tokens.shade.c900, + + type: { + secondary: tokens.shade.c200, + inactive: tokens.shade.c50, + icon: tokens.shade.c50, + iconActivated: tokens.purple.c200, + activated: tokens.purple.c50 + } + }, + + card: { + border: tokens.shade.c400, + background: tokens.shade.c400, + altBackground: tokens.shade.c400 + }, + + saveBar: { + background: tokens.shade.c800 + } + }, + + utils: { + divider: tokens.ash.c300 + }, + + errors: { + card: tokens.shade.c800, + border: tokens.ash.c500, + + type: { + secondary: tokens.ash.c100 + } + }, + + about: { + circle: tokens.ash.c500, + circleText: tokens.ash.c50 + }, + + editBadge: { + bg: tokens.ash.c500, + bgHover: tokens.ash.c400, + text: tokens.ash.c50 + }, + + progress: { + background: tokens.ash.c50, + preloaded: tokens.ash.c50, + filled: tokens.purple.c200 + }, + + video: { + buttonBackground: tokens.ash.c200, + + autoPlay: { + background: tokens.ash.c700, + hover: tokens.ash.c500 + }, + + scraping: { + card: tokens.shade.c700, + loading: tokens.purple.c200, + noresult: tokens.ash.c100 + }, + + audio: { + set: tokens.purple.c200 + }, + + context: { + background: tokens.ash.c900, + light: tokens.shade.c50, + border: tokens.ash.c600, + hoverColor: tokens.ash.c600, + buttonFocus: tokens.ash.c500, + flagBg: tokens.ash.c500, + inputBg: tokens.ash.c600, + buttonOverInputHover: tokens.ash.c500, + inputPlaceholder: tokens.ash.c200, + cardBorder: tokens.ash.c700, + slider: tokens.ash.c50, + sliderFilled: tokens.purple.c200, + + buttons: { + list: tokens.ash.c700, + active: tokens.ash.c900 + }, + + closeHover: tokens.ash.c800, + + type: { + secondary: tokens.ash.c200, + accent: tokens.purple.c200 + } + } + } + } + } +}); diff --git a/tooling/tailwind/themes/list/teal.ts b/tooling/tailwind/themes/list/teal.ts new file mode 100644 index 0000000..ea0f132 --- /dev/null +++ b/tooling/tailwind/themes/list/teal.ts @@ -0,0 +1,259 @@ +import { createTheme } from "../types"; + +const tokens = { + purple: { + c50: "#aad7ff", + c100: "#82c4ff", + c200: "#59a8ec", + c300: "#4491d6", + c400: "#317dbf", + c500: "#285b87", + c600: "#1f4464", + c700: "#18334a", + c800: "#112434", + c900: "#0b1822" + }, + shade: { + c50: "#677c90", + c100: "#52667a", + c200: "#3f4f60", + c300: "#32404f", + c400: "#273441", + c500: "#1e2832", + c600: "#172028", + c700: "#131a22", + c800: "#0f151b", + c900: "#0a0e12" + }, + ash: { + c50: "#7f9b9b", + c100: "#5b7b7b", + c200: "#446463", + c300: "#2b4e4d", + c400: "#204241", + c500: "#1c3c3b", + c600: "#173232", + c700: "#132929", + c800: "#102020", + c900: "#0c1615" + }, + blue: { + c50: "#adf5d6", + c100: "#79cca8", + c200: "#5dae8b", + c300: "#3b8c69", + c400: "#2a7152", + c500: "#1f503b", + c600: "#1b4130", + c700: "#173629", + c800: "#102019", + c900: "#0b1310" + } +}; + +export default createTheme({ + name: "teal", + extend: { + colors: { + themePreview: { + primary: tokens.blue.c200, + secondary: tokens.shade.c50 + }, + + pill: { + background: tokens.shade.c300, + backgroundHover: tokens.shade.c200, + highlight: tokens.blue.c200, + + activeBackground: tokens.shade.c300, + }, + + global: { + accentA: tokens.blue.c200, + accentB: tokens.blue.c300 + }, + + lightBar: { + light: tokens.blue.c400 + }, + + buttons: { + toggle: tokens.purple.c300, + toggleDisabled: tokens.ash.c500, + + secondary: tokens.ash.c700, + secondaryHover: tokens.ash.c700, + purple: tokens.purple.c500, + purpleHover: tokens.purple.c400, + cancel: tokens.ash.c500, + cancelHover: tokens.ash.c300 + }, + + background: { + main: tokens.shade.c900, + secondary: tokens.shade.c600, + secondaryHover: tokens.shade.c400, + accentA: tokens.purple.c500, + accentB: tokens.blue.c500 + }, + + modal: { + background: tokens.shade.c800, + }, + + type: { + logo: tokens.purple.c100, + text: tokens.shade.c50, + dimmed: tokens.shade.c50, + divider: tokens.ash.c500, + secondary: tokens.ash.c100, + link: tokens.purple.c100, + linkHover: tokens.purple.c50 + }, + + search: { + background: tokens.shade.c500, + hoverBackground: tokens.shade.c600, + focused: tokens.shade.c400, + placeholder: tokens.shade.c100, + icon: tokens.shade.c100 + }, + + mediaCard: { + hoverBackground: tokens.shade.c600, + hoverAccent: tokens.shade.c50, + hoverShadow: tokens.shade.c900, + shadow: tokens.shade.c700, + barColor: tokens.ash.c200, + barFillColor: tokens.purple.c100, + badge: tokens.shade.c700, + badgeText: tokens.ash.c100 + }, + + largeCard: { + background: tokens.shade.c600, + icon: tokens.purple.c400 + }, + + dropdown: { + background: tokens.shade.c600, + altBackground: tokens.shade.c700, + hoverBackground: tokens.shade.c500, + text: tokens.shade.c50, + secondary: tokens.shade.c100, + border: tokens.shade.c400, + contentBackground: tokens.shade.c500 + }, + + authentication: { + border: tokens.shade.c300, + inputBg: tokens.shade.c600, + inputBgHover: tokens.shade.c500, + wordBackground: tokens.shade.c500, + copyText: tokens.shade.c100, + copyTextHover: tokens.ash.c50 + }, + + settings: { + sidebar: { + activeLink: tokens.shade.c600, + badge: tokens.shade.c900, + + type: { + secondary: tokens.shade.c200, + inactive: tokens.shade.c50, + icon: tokens.shade.c50, + iconActivated: tokens.purple.c200, + activated: tokens.purple.c50 + } + }, + + card: { + border: tokens.shade.c400, + background: tokens.shade.c400, + altBackground: tokens.shade.c400 + }, + + saveBar: { + background: tokens.shade.c800 + } + }, + + utils: { + divider: tokens.ash.c300 + }, + + errors: { + card: tokens.shade.c800, + border: tokens.ash.c500, + + type: { + secondary: tokens.ash.c100 + } + }, + + about: { + circle: tokens.ash.c500, + circleText: tokens.ash.c50 + }, + + editBadge: { + bg: tokens.ash.c500, + bgHover: tokens.ash.c400, + text: tokens.ash.c50 + }, + + progress: { + background: tokens.ash.c50, + preloaded: tokens.ash.c50, + filled: tokens.purple.c200 + }, + + video: { + buttonBackground: tokens.ash.c200, + + autoPlay: { + background: tokens.ash.c700, + hover: tokens.ash.c500 + }, + + scraping: { + card: tokens.shade.c700, + loading: tokens.purple.c200, + noresult: tokens.ash.c100 + }, + + audio: { + set: tokens.purple.c200 + }, + + context: { + background: tokens.ash.c900, + light: tokens.shade.c50, + border: tokens.ash.c600, + hoverColor: tokens.ash.c600, + buttonFocus: tokens.ash.c500, + flagBg: tokens.ash.c500, + inputBg: tokens.ash.c600, + buttonOverInputHover: tokens.ash.c500, + inputPlaceholder: tokens.ash.c200, + cardBorder: tokens.ash.c700, + slider: tokens.ash.c50, + sliderFilled: tokens.purple.c200, + + buttons: { + list: tokens.ash.c700, + active: tokens.ash.c900 + }, + + closeHover: tokens.ash.c800, + + type: { + secondary: tokens.ash.c200, + accent: tokens.purple.c200 + } + } + } + } + } +}); diff --git a/tooling/tailwind/themes/types.ts b/tooling/tailwind/themes/types.ts new file mode 100644 index 0000000..f65e8f4 --- /dev/null +++ b/tooling/tailwind/themes/types.ts @@ -0,0 +1,18 @@ +import type { defaultTheme } from "./default"; + +type DeepPartial = { + [P in keyof T]?: DeepPartial; +}; + +export interface Theme { + name: string; + extend: DeepPartial<(typeof defaultTheme)["extend"]>; +} + +export function createTheme(theme: Theme) { + return { + name: theme.name, + selectors: [`.theme-${theme.name}`], + extend: theme.extend, + }; +} diff --git a/tooling/tailwind/web.ts b/tooling/tailwind/web.ts deleted file mode 100644 index 0729477..0000000 --- a/tooling/tailwind/web.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { Config } from "tailwindcss"; -import animate from "tailwindcss-animate"; - -import base from "./base"; - -export default { - content: base.content, - presets: [base], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, - plugins: [animate], -} satisfies Config;