diff --git a/.tamagui/tamagui.config.cjs b/.tamagui/tamagui.config.cjs index ecf059fc..986e0172 100644 --- a/.tamagui/tamagui.config.cjs +++ b/.tamagui/tamagui.config.cjs @@ -3634,6 +3634,14 @@ var lightTheme = { blue11: "#4338CA" // Indigo 700 }; +var adminLightTheme = { + ...lightTheme, + accentSoft: tokens3.color.accentSoft, + colorMuted: "#64748B", + // Slate 500 + colorSubtle: "#94A3B8" + // Slate 400 +}; var guestLightTheme = { ...themes2.light, primary: "var(--guest-primary, #FF5A5F)", @@ -3686,6 +3694,33 @@ var darkTheme = { blue10: "#FF5C5C", blue11: "#FF8A8A" }; +var adminDarkTheme = { + ...darkTheme, + background: "#0F172A", + backgroundHover: "#101A36", + backgroundPress: "#132142", + backgroundStrong: "#16223A", + backgroundTransparent: "rgba(15, 23, 42, 0)", + color: "#F8FAFF", + colorHover: "#FFFFFF", + colorPress: "#E8EEFF", + colorFocus: "#FFFFFF", + borderColor: "rgba(148, 163, 184, 0.25)", + borderColorHover: "rgba(148, 163, 184, 0.35)", + borderColorPress: "rgba(148, 163, 184, 0.45)", + shadowColor: "rgba(2, 6, 23, 0.7)", + shadowColorPress: "rgba(2, 6, 23, 0.8)", + shadowColorFocus: "rgba(2, 6, 23, 0.8)", + surface: "#16223A", + muted: "#1C2844", + blue3: "rgba(255, 90, 95, 0.18)", + blue6: "#FF5A5F", + blue10: "#FF5A5F", + blue11: "#FF8A8A", + accentSoft: "rgba(255, 90, 95, 0.18)", + colorMuted: "rgba(248, 250, 255, 0.68)", + colorSubtle: "rgba(248, 250, 255, 0.5)" +}; var guestNightTheme = { ...themes2.dark, primary: "var(--guest-primary, #FF4FD8)", @@ -3717,6 +3752,8 @@ var themes3 = { ...themes2, light: lightTheme, dark: darkTheme, + adminLight: adminLightTheme, + adminDark: adminDarkTheme, guestLight: { ...guestLightTheme }, guestDark: { ...darkTheme }, guestNight: { ...guestNightTheme } diff --git a/.tamagui/tamagui.config.json b/.tamagui/tamagui.config.json index 56369e91..327538a2 100644 --- a/.tamagui/tamagui.config.json +++ b/.tamagui/tamagui.config.json @@ -31787,6 +31787,676 @@ } }, "themes": { + "adminDark": { + "blue1Light": "hsl(206, 100%, 99.2%)", + "blue2Light": "hsl(210, 100%, 98.0%)", + "blue3Light": "hsl(209, 100%, 96.5%)", + "blue4Light": "hsl(210, 98.8%, 94.0%)", + "blue5Light": "hsl(209, 95.0%, 90.1%)", + "blue6Light": "hsl(209, 81.2%, 84.5%)", + "blue7Light": "hsl(208, 77.5%, 76.9%)", + "blue8Light": "hsl(206, 81.9%, 65.3%)", + "blue9Light": "hsl(206, 100%, 50.0%)", + "blue10Light": "hsl(208, 100%, 47.3%)", + "blue11Light": "hsl(211, 100%, 43.2%)", + "blue12Light": "hsl(211, 100%, 15.0%)", + "gray1Light": "hsl(0, 0%, 99.0%)", + "gray2Light": "hsl(0, 0%, 97.3%)", + "gray3Light": "hsl(0, 0%, 95.1%)", + "gray4Light": "hsl(0, 0%, 93.0%)", + "gray5Light": "hsl(0, 0%, 90.9%)", + "gray6Light": "hsl(0, 0%, 88.7%)", + "gray7Light": "hsl(0, 0%, 85.8%)", + "gray8Light": "hsl(0, 0%, 78.0%)", + "gray9Light": "hsl(0, 0%, 56.1%)", + "gray10Light": "hsl(0, 0%, 52.3%)", + "gray11Light": "hsl(0, 0%, 43.5%)", + "gray12Light": "hsl(0, 0%, 9.0%)", + "green1Light": "hsl(136, 50.0%, 98.9%)", + "green2Light": "hsl(138, 62.5%, 96.9%)", + "green3Light": "hsl(139, 55.2%, 94.5%)", + "green4Light": "hsl(140, 48.7%, 91.0%)", + "green5Light": "hsl(141, 43.7%, 86.0%)", + "green6Light": "hsl(143, 40.3%, 79.0%)", + "green7Light": "hsl(146, 38.5%, 69.0%)", + "green8Light": "hsl(151, 40.2%, 54.1%)", + "green9Light": "hsl(151, 55.0%, 41.5%)", + "green10Light": "hsl(152, 57.5%, 37.6%)", + "green11Light": "hsl(153, 67.0%, 28.5%)", + "green12Light": "hsl(155, 40.0%, 14.0%)", + "orange1Light": "hsl(24, 70.0%, 99.0%)", + "orange2Light": "hsl(24, 83.3%, 97.6%)", + "orange3Light": "hsl(24, 100%, 95.3%)", + "orange4Light": "hsl(25, 100%, 92.2%)", + "orange5Light": "hsl(25, 100%, 88.2%)", + "orange6Light": "hsl(25, 100%, 82.8%)", + "orange7Light": "hsl(24, 100%, 75.3%)", + "orange8Light": "hsl(24, 94.5%, 64.3%)", + "orange9Light": "hsl(24, 94.0%, 50.0%)", + "orange10Light": "hsl(24, 100%, 46.5%)", + "orange11Light": "hsl(24, 100%, 37.0%)", + "orange12Light": "hsl(15, 60.0%, 17.0%)", + "pink1Light": "hsl(322, 100%, 99.4%)", + "pink2Light": "hsl(323, 100%, 98.4%)", + "pink3Light": "hsl(323, 86.3%, 96.5%)", + "pink4Light": "hsl(323, 78.7%, 94.2%)", + "pink5Light": "hsl(323, 72.2%, 91.1%)", + "pink6Light": "hsl(323, 66.3%, 86.6%)", + "pink7Light": "hsl(323, 62.0%, 80.1%)", + "pink8Light": "hsl(323, 60.3%, 72.4%)", + "pink9Light": "hsl(322, 65.0%, 54.5%)", + "pink10Light": "hsl(322, 63.9%, 50.7%)", + "pink11Light": "hsl(322, 75.0%, 46.0%)", + "pink12Light": "hsl(320, 70.0%, 13.5%)", + "purple1Light": "hsl(280, 65.0%, 99.4%)", + "purple2Light": "hsl(276, 100%, 99.0%)", + "purple3Light": "hsl(276, 83.1%, 97.0%)", + "purple4Light": "hsl(275, 76.4%, 94.7%)", + "purple5Light": "hsl(275, 70.8%, 91.8%)", + "purple6Light": "hsl(274, 65.4%, 87.8%)", + "purple7Light": "hsl(273, 61.0%, 81.7%)", + "purple8Light": "hsl(272, 60.0%, 73.5%)", + "purple9Light": "hsl(272, 51.0%, 54.0%)", + "purple10Light": "hsl(272, 46.8%, 50.3%)", + "purple11Light": "hsl(272, 50.0%, 45.8%)", + "purple12Light": "hsl(272, 66.0%, 16.0%)", + "red1Light": "hsl(359, 100%, 99.4%)", + "red2Light": "hsl(359, 100%, 98.6%)", + "red3Light": "hsl(360, 100%, 96.8%)", + "red4Light": "hsl(360, 97.9%, 94.8%)", + "red5Light": "hsl(360, 90.2%, 91.9%)", + "red6Light": "hsl(360, 81.7%, 87.8%)", + "red7Light": "hsl(359, 74.2%, 81.7%)", + "red8Light": "hsl(359, 69.5%, 74.3%)", + "red9Light": "hsl(358, 75.0%, 59.0%)", + "red10Light": "hsl(358, 69.4%, 55.2%)", + "red11Light": "hsl(358, 65.0%, 48.7%)", + "red12Light": "hsl(354, 50.0%, 14.6%)", + "yellow1Light": "hsl(60, 54.0%, 98.5%)", + "yellow2Light": "hsl(52, 100%, 95.5%)", + "yellow3Light": "hsl(55, 100%, 90.9%)", + "yellow4Light": "hsl(54, 100%, 86.6%)", + "yellow5Light": "hsl(52, 97.9%, 82.0%)", + "yellow6Light": "hsl(50, 89.4%, 76.1%)", + "yellow7Light": "hsl(47, 80.4%, 68.0%)", + "yellow8Light": "hsl(48, 100%, 46.1%)", + "yellow9Light": "hsl(53, 92.0%, 50.0%)", + "yellow10Light": "hsl(50, 100%, 48.5%)", + "yellow11Light": "hsl(42, 100%, 29.0%)", + "yellow12Light": "hsl(40, 55.0%, 13.5%)", + "blue1Dark": "hsl(212, 35.0%, 9.2%)", + "blue2Dark": "hsl(216, 50.0%, 11.8%)", + "blue3Dark": "hsl(214, 59.4%, 15.3%)", + "blue4Dark": "hsl(214, 65.8%, 17.9%)", + "blue5Dark": "hsl(213, 71.2%, 20.2%)", + "blue6Dark": "hsl(212, 77.4%, 23.1%)", + "blue7Dark": "hsl(211, 85.1%, 27.4%)", + "blue8Dark": "hsl(211, 89.7%, 34.1%)", + "blue9Dark": "hsl(206, 100%, 50.0%)", + "blue10Dark": "hsl(209, 100%, 60.6%)", + "blue11Dark": "hsl(210, 100%, 66.1%)", + "blue12Dark": "hsl(206, 98.0%, 95.8%)", + "gray1Dark": "hsl(0, 0%, 8.5%)", + "gray2Dark": "hsl(0, 0%, 11.0%)", + "gray3Dark": "hsl(0, 0%, 13.6%)", + "gray4Dark": "hsl(0, 0%, 15.8%)", + "gray5Dark": "hsl(0, 0%, 17.9%)", + "gray6Dark": "hsl(0, 0%, 20.5%)", + "gray7Dark": "hsl(0, 0%, 24.3%)", + "gray8Dark": "hsl(0, 0%, 31.2%)", + "gray9Dark": "hsl(0, 0%, 43.9%)", + "gray10Dark": "hsl(0, 0%, 49.4%)", + "gray11Dark": "hsl(0, 0%, 62.8%)", + "gray12Dark": "hsl(0, 0%, 93.0%)", + "green1Dark": "hsl(146, 30.0%, 7.4%)", + "green2Dark": "hsl(155, 44.2%, 8.4%)", + "green3Dark": "hsl(155, 46.7%, 10.9%)", + "green4Dark": "hsl(154, 48.4%, 12.9%)", + "green5Dark": "hsl(154, 49.7%, 14.9%)", + "green6Dark": "hsl(154, 50.9%, 17.6%)", + "green7Dark": "hsl(153, 51.8%, 21.8%)", + "green8Dark": "hsl(151, 51.7%, 28.4%)", + "green9Dark": "hsl(151, 55.0%, 41.5%)", + "green10Dark": "hsl(151, 49.3%, 46.5%)", + "green11Dark": "hsl(151, 50.0%, 53.2%)", + "green12Dark": "hsl(137, 72.0%, 94.0%)", + "orange1Dark": "hsl(30, 70.0%, 7.2%)", + "orange2Dark": "hsl(28, 100%, 8.4%)", + "orange3Dark": "hsl(26, 91.1%, 11.6%)", + "orange4Dark": "hsl(25, 88.3%, 14.1%)", + "orange5Dark": "hsl(24, 87.6%, 16.6%)", + "orange6Dark": "hsl(24, 88.6%, 19.8%)", + "orange7Dark": "hsl(24, 92.4%, 24.0%)", + "orange8Dark": "hsl(25, 100%, 29.0%)", + "orange9Dark": "hsl(24, 94.0%, 50.0%)", + "orange10Dark": "hsl(24, 100%, 58.5%)", + "orange11Dark": "hsl(24, 100%, 62.2%)", + "orange12Dark": "hsl(24, 97.0%, 93.2%)", + "pink1Dark": "hsl(318, 25.0%, 9.6%)", + "pink2Dark": "hsl(319, 32.2%, 11.6%)", + "pink3Dark": "hsl(319, 41.0%, 16.0%)", + "pink4Dark": "hsl(320, 45.4%, 18.7%)", + "pink5Dark": "hsl(320, 49.0%, 21.1%)", + "pink6Dark": "hsl(321, 53.6%, 24.4%)", + "pink7Dark": "hsl(321, 61.1%, 29.7%)", + "pink8Dark": "hsl(322, 74.9%, 37.5%)", + "pink9Dark": "hsl(322, 65.0%, 54.5%)", + "pink10Dark": "hsl(323, 72.8%, 59.2%)", + "pink11Dark": "hsl(325, 90.0%, 66.4%)", + "pink12Dark": "hsl(322, 90.0%, 95.8%)", + "purple1Dark": "hsl(284, 20.0%, 9.6%)", + "purple2Dark": "hsl(283, 30.0%, 11.8%)", + "purple3Dark": "hsl(281, 37.5%, 16.5%)", + "purple4Dark": "hsl(280, 41.2%, 20.0%)", + "purple5Dark": "hsl(279, 43.8%, 23.3%)", + "purple6Dark": "hsl(277, 46.4%, 27.5%)", + "purple7Dark": "hsl(275, 49.3%, 34.6%)", + "purple8Dark": "hsl(272, 52.1%, 45.9%)", + "purple9Dark": "hsl(272, 51.0%, 54.0%)", + "purple10Dark": "hsl(273, 57.3%, 59.1%)", + "purple11Dark": "hsl(275, 80.0%, 71.0%)", + "purple12Dark": "hsl(279, 75.0%, 95.7%)", + "red1Dark": "hsl(353, 23.0%, 9.8%)", + "red2Dark": "hsl(357, 34.4%, 12.0%)", + "red3Dark": "hsl(356, 43.4%, 16.4%)", + "red4Dark": "hsl(356, 47.6%, 19.2%)", + "red5Dark": "hsl(356, 51.1%, 21.9%)", + "red6Dark": "hsl(356, 55.2%, 25.9%)", + "red7Dark": "hsl(357, 60.2%, 31.8%)", + "red8Dark": "hsl(358, 65.0%, 40.4%)", + "red9Dark": "hsl(358, 75.0%, 59.0%)", + "red10Dark": "hsl(358, 85.3%, 64.0%)", + "red11Dark": "hsl(358, 100%, 69.5%)", + "red12Dark": "hsl(351, 89.0%, 96.0%)", + "yellow1Dark": "hsl(45, 100%, 5.5%)", + "yellow2Dark": "hsl(46, 100%, 6.7%)", + "yellow3Dark": "hsl(45, 100%, 8.7%)", + "yellow4Dark": "hsl(45, 100%, 10.4%)", + "yellow5Dark": "hsl(47, 100%, 12.1%)", + "yellow6Dark": "hsl(49, 100%, 14.3%)", + "yellow7Dark": "hsl(49, 90.3%, 18.4%)", + "yellow8Dark": "hsl(50, 100%, 22.0%)", + "yellow9Dark": "hsl(53, 92.0%, 50.0%)", + "yellow10Dark": "hsl(54, 100%, 68.0%)", + "yellow11Dark": "hsl(48, 100%, 47.0%)", + "yellow12Dark": "hsl(53, 100%, 91.0%)", + "primary": "#FF5A5F", + "accent": "#F43F5E", + "accentSoft": "rgba(255, 90, 95, 0.18)", + "success": "#10B981", + "warning": "#F59E0B", + "danger": "#EF4444", + "surface": "#16223A", + "muted": "#1C2844", + "border": "#E2E8F0", + "text": "#0F172A", + "color1": "#050505", + "color2": "#151515", + "color3": "#191919", + "color4": "#232323", + "color5": "#282828", + "color6": "#323232", + "color7": "#424242", + "color8": "#494949", + "color9": "#545454", + "color10": "#626262", + "color11": "#a5a5a5", + "color12": "#fff", + "background": "#0F172A", + "backgroundHover": "#101A36", + "backgroundPress": "#132142", + "backgroundFocus": "#282828", + "backgroundStrong": "#16223A", + "backgroundTransparent": "rgba(15, 23, 42, 0)", + "color": "#F8FAFF", + "colorHover": "#FFFFFF", + "colorPress": "#E8EEFF", + "colorFocus": "#FFFFFF", + "colorTransparent": "rgba(255,255,255,0)", + "borderColor": "rgba(148, 163, 184, 0.25)", + "borderColorHover": "rgba(148, 163, 184, 0.35)", + "borderColorFocus": "#232323", + "borderColorPress": "rgba(148, 163, 184, 0.45)", + "placeholderColor": "#545454", + "blue1": "hsl(212, 35.0%, 9.2%)", + "blue2": "hsl(216, 50.0%, 11.8%)", + "blue3": "rgba(255, 90, 95, 0.18)", + "blue4": "hsl(214, 65.8%, 17.9%)", + "blue5": "hsl(213, 71.2%, 20.2%)", + "blue6": "#FF5A5F", + "blue7": "hsl(211, 85.1%, 27.4%)", + "blue8": "hsl(211, 89.7%, 34.1%)", + "blue9": "hsl(206, 100%, 50.0%)", + "blue10": "#FF5A5F", + "blue11": "#FF8A8A", + "blue12": "hsl(206, 98.0%, 95.8%)", + "gray1": "hsl(0, 0%, 8.5%)", + "gray2": "hsl(0, 0%, 11.0%)", + "gray3": "hsl(0, 0%, 13.6%)", + "gray4": "hsl(0, 0%, 15.8%)", + "gray5": "hsl(0, 0%, 17.9%)", + "gray6": "hsl(0, 0%, 20.5%)", + "gray7": "hsl(0, 0%, 24.3%)", + "gray8": "hsl(0, 0%, 31.2%)", + "gray9": "hsl(0, 0%, 43.9%)", + "gray10": "hsl(0, 0%, 49.4%)", + "gray11": "hsl(0, 0%, 62.8%)", + "gray12": "hsl(0, 0%, 93.0%)", + "green1": "hsl(146, 30.0%, 7.4%)", + "green2": "hsl(155, 44.2%, 8.4%)", + "green3": "hsl(155, 46.7%, 10.9%)", + "green4": "hsl(154, 48.4%, 12.9%)", + "green5": "hsl(154, 49.7%, 14.9%)", + "green6": "hsl(154, 50.9%, 17.6%)", + "green7": "hsl(153, 51.8%, 21.8%)", + "green8": "hsl(151, 51.7%, 28.4%)", + "green9": "hsl(151, 55.0%, 41.5%)", + "green10": "hsl(151, 49.3%, 46.5%)", + "green11": "hsl(151, 50.0%, 53.2%)", + "green12": "hsl(137, 72.0%, 94.0%)", + "orange1": "hsl(30, 70.0%, 7.2%)", + "orange2": "hsl(28, 100%, 8.4%)", + "orange3": "hsl(26, 91.1%, 11.6%)", + "orange4": "hsl(25, 88.3%, 14.1%)", + "orange5": "hsl(24, 87.6%, 16.6%)", + "orange6": "hsl(24, 88.6%, 19.8%)", + "orange7": "hsl(24, 92.4%, 24.0%)", + "orange8": "hsl(25, 100%, 29.0%)", + "orange9": "hsl(24, 94.0%, 50.0%)", + "orange10": "hsl(24, 100%, 58.5%)", + "orange11": "hsl(24, 100%, 62.2%)", + "orange12": "hsl(24, 97.0%, 93.2%)", + "pink1": "hsl(318, 25.0%, 9.6%)", + "pink2": "hsl(319, 32.2%, 11.6%)", + "pink3": "hsl(319, 41.0%, 16.0%)", + "pink4": "hsl(320, 45.4%, 18.7%)", + "pink5": "hsl(320, 49.0%, 21.1%)", + "pink6": "hsl(321, 53.6%, 24.4%)", + "pink7": "hsl(321, 61.1%, 29.7%)", + "pink8": "hsl(322, 74.9%, 37.5%)", + "pink9": "hsl(322, 65.0%, 54.5%)", + "pink10": "hsl(323, 72.8%, 59.2%)", + "pink11": "hsl(325, 90.0%, 66.4%)", + "pink12": "hsl(322, 90.0%, 95.8%)", + "purple1": "hsl(284, 20.0%, 9.6%)", + "purple2": "hsl(283, 30.0%, 11.8%)", + "purple3": "hsl(281, 37.5%, 16.5%)", + "purple4": "hsl(280, 41.2%, 20.0%)", + "purple5": "hsl(279, 43.8%, 23.3%)", + "purple6": "hsl(277, 46.4%, 27.5%)", + "purple7": "hsl(275, 49.3%, 34.6%)", + "purple8": "hsl(272, 52.1%, 45.9%)", + "purple9": "hsl(272, 51.0%, 54.0%)", + "purple10": "hsl(273, 57.3%, 59.1%)", + "purple11": "hsl(275, 80.0%, 71.0%)", + "purple12": "hsl(279, 75.0%, 95.7%)", + "red1": "hsl(353, 23.0%, 9.8%)", + "red2": "hsl(357, 34.4%, 12.0%)", + "red3": "hsl(356, 43.4%, 16.4%)", + "red4": "hsl(356, 47.6%, 19.2%)", + "red5": "hsl(356, 51.1%, 21.9%)", + "red6": "hsl(356, 55.2%, 25.9%)", + "red7": "hsl(357, 60.2%, 31.8%)", + "red8": "hsl(358, 65.0%, 40.4%)", + "red9": "hsl(358, 75.0%, 59.0%)", + "red10": "hsl(358, 85.3%, 64.0%)", + "red11": "hsl(358, 100%, 69.5%)", + "red12": "hsl(351, 89.0%, 96.0%)", + "yellow1": "hsl(45, 100%, 5.5%)", + "yellow2": "hsl(46, 100%, 6.7%)", + "yellow3": "hsl(45, 100%, 8.7%)", + "yellow4": "hsl(45, 100%, 10.4%)", + "yellow5": "hsl(47, 100%, 12.1%)", + "yellow6": "hsl(49, 100%, 14.3%)", + "yellow7": "hsl(49, 90.3%, 18.4%)", + "yellow8": "hsl(50, 100%, 22.0%)", + "yellow9": "hsl(53, 92.0%, 50.0%)", + "yellow10": "hsl(54, 100%, 68.0%)", + "yellow11": "hsl(48, 100%, 47.0%)", + "yellow12": "hsl(53, 100%, 91.0%)", + "shadowColor": "rgba(2, 6, 23, 0.7)", + "shadowColorHover": "rgba(0,0,0,0.3)", + "shadowColorPress": "rgba(2, 6, 23, 0.8)", + "shadowColorFocus": "rgba(2, 6, 23, 0.8)", + "colorMuted": "rgba(248, 250, 255, 0.68)", + "colorSubtle": "rgba(248, 250, 255, 0.5)", + "id": "adminDark" + }, + "adminLight": { + "blue1Light": "hsl(206, 100%, 99.2%)", + "blue2Light": "hsl(210, 100%, 98.0%)", + "blue3Light": "hsl(209, 100%, 96.5%)", + "blue4Light": "hsl(210, 98.8%, 94.0%)", + "blue5Light": "hsl(209, 95.0%, 90.1%)", + "blue6Light": "hsl(209, 81.2%, 84.5%)", + "blue7Light": "hsl(208, 77.5%, 76.9%)", + "blue8Light": "hsl(206, 81.9%, 65.3%)", + "blue9Light": "hsl(206, 100%, 50.0%)", + "blue10Light": "hsl(208, 100%, 47.3%)", + "blue11Light": "hsl(211, 100%, 43.2%)", + "blue12Light": "hsl(211, 100%, 15.0%)", + "gray1Light": "hsl(0, 0%, 99.0%)", + "gray2Light": "hsl(0, 0%, 97.3%)", + "gray3Light": "hsl(0, 0%, 95.1%)", + "gray4Light": "hsl(0, 0%, 93.0%)", + "gray5Light": "hsl(0, 0%, 90.9%)", + "gray6Light": "hsl(0, 0%, 88.7%)", + "gray7Light": "hsl(0, 0%, 85.8%)", + "gray8Light": "hsl(0, 0%, 78.0%)", + "gray9Light": "hsl(0, 0%, 56.1%)", + "gray10Light": "hsl(0, 0%, 52.3%)", + "gray11Light": "hsl(0, 0%, 43.5%)", + "gray12Light": "hsl(0, 0%, 9.0%)", + "green1Light": "hsl(136, 50.0%, 98.9%)", + "green2Light": "hsl(138, 62.5%, 96.9%)", + "green3Light": "hsl(139, 55.2%, 94.5%)", + "green4Light": "hsl(140, 48.7%, 91.0%)", + "green5Light": "hsl(141, 43.7%, 86.0%)", + "green6Light": "hsl(143, 40.3%, 79.0%)", + "green7Light": "hsl(146, 38.5%, 69.0%)", + "green8Light": "hsl(151, 40.2%, 54.1%)", + "green9Light": "hsl(151, 55.0%, 41.5%)", + "green10Light": "hsl(152, 57.5%, 37.6%)", + "green11Light": "hsl(153, 67.0%, 28.5%)", + "green12Light": "hsl(155, 40.0%, 14.0%)", + "orange1Light": "hsl(24, 70.0%, 99.0%)", + "orange2Light": "hsl(24, 83.3%, 97.6%)", + "orange3Light": "hsl(24, 100%, 95.3%)", + "orange4Light": "hsl(25, 100%, 92.2%)", + "orange5Light": "hsl(25, 100%, 88.2%)", + "orange6Light": "hsl(25, 100%, 82.8%)", + "orange7Light": "hsl(24, 100%, 75.3%)", + "orange8Light": "hsl(24, 94.5%, 64.3%)", + "orange9Light": "hsl(24, 94.0%, 50.0%)", + "orange10Light": "hsl(24, 100%, 46.5%)", + "orange11Light": "hsl(24, 100%, 37.0%)", + "orange12Light": "hsl(15, 60.0%, 17.0%)", + "pink1Light": "hsl(322, 100%, 99.4%)", + "pink2Light": "hsl(323, 100%, 98.4%)", + "pink3Light": "hsl(323, 86.3%, 96.5%)", + "pink4Light": "hsl(323, 78.7%, 94.2%)", + "pink5Light": "hsl(323, 72.2%, 91.1%)", + "pink6Light": "hsl(323, 66.3%, 86.6%)", + "pink7Light": "hsl(323, 62.0%, 80.1%)", + "pink8Light": "hsl(323, 60.3%, 72.4%)", + "pink9Light": "hsl(322, 65.0%, 54.5%)", + "pink10Light": "hsl(322, 63.9%, 50.7%)", + "pink11Light": "hsl(322, 75.0%, 46.0%)", + "pink12Light": "hsl(320, 70.0%, 13.5%)", + "purple1Light": "hsl(280, 65.0%, 99.4%)", + "purple2Light": "hsl(276, 100%, 99.0%)", + "purple3Light": "hsl(276, 83.1%, 97.0%)", + "purple4Light": "hsl(275, 76.4%, 94.7%)", + "purple5Light": "hsl(275, 70.8%, 91.8%)", + "purple6Light": "hsl(274, 65.4%, 87.8%)", + "purple7Light": "hsl(273, 61.0%, 81.7%)", + "purple8Light": "hsl(272, 60.0%, 73.5%)", + "purple9Light": "hsl(272, 51.0%, 54.0%)", + "purple10Light": "hsl(272, 46.8%, 50.3%)", + "purple11Light": "hsl(272, 50.0%, 45.8%)", + "purple12Light": "hsl(272, 66.0%, 16.0%)", + "red1Light": "hsl(359, 100%, 99.4%)", + "red2Light": "hsl(359, 100%, 98.6%)", + "red3Light": "hsl(360, 100%, 96.8%)", + "red4Light": "hsl(360, 97.9%, 94.8%)", + "red5Light": "hsl(360, 90.2%, 91.9%)", + "red6Light": "hsl(360, 81.7%, 87.8%)", + "red7Light": "hsl(359, 74.2%, 81.7%)", + "red8Light": "hsl(359, 69.5%, 74.3%)", + "red9Light": "hsl(358, 75.0%, 59.0%)", + "red10Light": "hsl(358, 69.4%, 55.2%)", + "red11Light": "hsl(358, 65.0%, 48.7%)", + "red12Light": "hsl(354, 50.0%, 14.6%)", + "yellow1Light": "hsl(60, 54.0%, 98.5%)", + "yellow2Light": "hsl(52, 100%, 95.5%)", + "yellow3Light": "hsl(55, 100%, 90.9%)", + "yellow4Light": "hsl(54, 100%, 86.6%)", + "yellow5Light": "hsl(52, 97.9%, 82.0%)", + "yellow6Light": "hsl(50, 89.4%, 76.1%)", + "yellow7Light": "hsl(47, 80.4%, 68.0%)", + "yellow8Light": "hsl(48, 100%, 46.1%)", + "yellow9Light": "hsl(53, 92.0%, 50.0%)", + "yellow10Light": "hsl(50, 100%, 48.5%)", + "yellow11Light": "hsl(42, 100%, 29.0%)", + "yellow12Light": "hsl(40, 55.0%, 13.5%)", + "blue1Dark": "hsl(212, 35.0%, 9.2%)", + "blue2Dark": "hsl(216, 50.0%, 11.8%)", + "blue3Dark": "hsl(214, 59.4%, 15.3%)", + "blue4Dark": "hsl(214, 65.8%, 17.9%)", + "blue5Dark": "hsl(213, 71.2%, 20.2%)", + "blue6Dark": "hsl(212, 77.4%, 23.1%)", + "blue7Dark": "hsl(211, 85.1%, 27.4%)", + "blue8Dark": "hsl(211, 89.7%, 34.1%)", + "blue9Dark": "hsl(206, 100%, 50.0%)", + "blue10Dark": "hsl(209, 100%, 60.6%)", + "blue11Dark": "hsl(210, 100%, 66.1%)", + "blue12Dark": "hsl(206, 98.0%, 95.8%)", + "gray1Dark": "hsl(0, 0%, 8.5%)", + "gray2Dark": "hsl(0, 0%, 11.0%)", + "gray3Dark": "hsl(0, 0%, 13.6%)", + "gray4Dark": "hsl(0, 0%, 15.8%)", + "gray5Dark": "hsl(0, 0%, 17.9%)", + "gray6Dark": "hsl(0, 0%, 20.5%)", + "gray7Dark": "hsl(0, 0%, 24.3%)", + "gray8Dark": "hsl(0, 0%, 31.2%)", + "gray9Dark": "hsl(0, 0%, 43.9%)", + "gray10Dark": "hsl(0, 0%, 49.4%)", + "gray11Dark": "hsl(0, 0%, 62.8%)", + "gray12Dark": "hsl(0, 0%, 93.0%)", + "green1Dark": "hsl(146, 30.0%, 7.4%)", + "green2Dark": "hsl(155, 44.2%, 8.4%)", + "green3Dark": "hsl(155, 46.7%, 10.9%)", + "green4Dark": "hsl(154, 48.4%, 12.9%)", + "green5Dark": "hsl(154, 49.7%, 14.9%)", + "green6Dark": "hsl(154, 50.9%, 17.6%)", + "green7Dark": "hsl(153, 51.8%, 21.8%)", + "green8Dark": "hsl(151, 51.7%, 28.4%)", + "green9Dark": "hsl(151, 55.0%, 41.5%)", + "green10Dark": "hsl(151, 49.3%, 46.5%)", + "green11Dark": "hsl(151, 50.0%, 53.2%)", + "green12Dark": "hsl(137, 72.0%, 94.0%)", + "orange1Dark": "hsl(30, 70.0%, 7.2%)", + "orange2Dark": "hsl(28, 100%, 8.4%)", + "orange3Dark": "hsl(26, 91.1%, 11.6%)", + "orange4Dark": "hsl(25, 88.3%, 14.1%)", + "orange5Dark": "hsl(24, 87.6%, 16.6%)", + "orange6Dark": "hsl(24, 88.6%, 19.8%)", + "orange7Dark": "hsl(24, 92.4%, 24.0%)", + "orange8Dark": "hsl(25, 100%, 29.0%)", + "orange9Dark": "hsl(24, 94.0%, 50.0%)", + "orange10Dark": "hsl(24, 100%, 58.5%)", + "orange11Dark": "hsl(24, 100%, 62.2%)", + "orange12Dark": "hsl(24, 97.0%, 93.2%)", + "pink1Dark": "hsl(318, 25.0%, 9.6%)", + "pink2Dark": "hsl(319, 32.2%, 11.6%)", + "pink3Dark": "hsl(319, 41.0%, 16.0%)", + "pink4Dark": "hsl(320, 45.4%, 18.7%)", + "pink5Dark": "hsl(320, 49.0%, 21.1%)", + "pink6Dark": "hsl(321, 53.6%, 24.4%)", + "pink7Dark": "hsl(321, 61.1%, 29.7%)", + "pink8Dark": "hsl(322, 74.9%, 37.5%)", + "pink9Dark": "hsl(322, 65.0%, 54.5%)", + "pink10Dark": "hsl(323, 72.8%, 59.2%)", + "pink11Dark": "hsl(325, 90.0%, 66.4%)", + "pink12Dark": "hsl(322, 90.0%, 95.8%)", + "purple1Dark": "hsl(284, 20.0%, 9.6%)", + "purple2Dark": "hsl(283, 30.0%, 11.8%)", + "purple3Dark": "hsl(281, 37.5%, 16.5%)", + "purple4Dark": "hsl(280, 41.2%, 20.0%)", + "purple5Dark": "hsl(279, 43.8%, 23.3%)", + "purple6Dark": "hsl(277, 46.4%, 27.5%)", + "purple7Dark": "hsl(275, 49.3%, 34.6%)", + "purple8Dark": "hsl(272, 52.1%, 45.9%)", + "purple9Dark": "hsl(272, 51.0%, 54.0%)", + "purple10Dark": "hsl(273, 57.3%, 59.1%)", + "purple11Dark": "hsl(275, 80.0%, 71.0%)", + "purple12Dark": "hsl(279, 75.0%, 95.7%)", + "red1Dark": "hsl(353, 23.0%, 9.8%)", + "red2Dark": "hsl(357, 34.4%, 12.0%)", + "red3Dark": "hsl(356, 43.4%, 16.4%)", + "red4Dark": "hsl(356, 47.6%, 19.2%)", + "red5Dark": "hsl(356, 51.1%, 21.9%)", + "red6Dark": "hsl(356, 55.2%, 25.9%)", + "red7Dark": "hsl(357, 60.2%, 31.8%)", + "red8Dark": "hsl(358, 65.0%, 40.4%)", + "red9Dark": "hsl(358, 75.0%, 59.0%)", + "red10Dark": "hsl(358, 85.3%, 64.0%)", + "red11Dark": "hsl(358, 100%, 69.5%)", + "red12Dark": "hsl(351, 89.0%, 96.0%)", + "yellow1Dark": "hsl(45, 100%, 5.5%)", + "yellow2Dark": "hsl(46, 100%, 6.7%)", + "yellow3Dark": "hsl(45, 100%, 8.7%)", + "yellow4Dark": "hsl(45, 100%, 10.4%)", + "yellow5Dark": "hsl(47, 100%, 12.1%)", + "yellow6Dark": "hsl(49, 100%, 14.3%)", + "yellow7Dark": "hsl(49, 90.3%, 18.4%)", + "yellow8Dark": "hsl(50, 100%, 22.0%)", + "yellow9Dark": "hsl(53, 92.0%, 50.0%)", + "yellow10Dark": "hsl(54, 100%, 68.0%)", + "yellow11Dark": "hsl(48, 100%, 47.0%)", + "yellow12Dark": "hsl(53, 100%, 91.0%)", + "primary": "#FF5A5F", + "accent": "#F43F5E", + "accentSoft": "#E0E7FF", + "success": "#10B981", + "warning": "#F59E0B", + "danger": "#EF4444", + "surface": "#ffffff", + "muted": "#F8FAFC", + "border": "#E2E8F0", + "text": "#0F172A", + "color1": "#fff", + "color2": "#f8f8f8", + "color3": "hsl(0, 0%, 96.3%)", + "color4": "hsl(0, 0%, 94.1%)", + "color5": "hsl(0, 0%, 92.0%)", + "color6": "hsl(0, 0%, 90.0%)", + "color7": "hsl(0, 0%, 88.5%)", + "color8": "hsl(0, 0%, 81.0%)", + "color9": "hsl(0, 0%, 56.1%)", + "color10": "hsl(0, 0%, 50.3%)", + "color11": "hsl(0, 0%, 42.5%)", + "color12": "hsl(0, 0%, 9.0%)", + "background": "#FFF8F5", + "backgroundHover": "#E2E8F0", + "backgroundPress": "#CBD5E1", + "backgroundFocus": "hsl(0, 0%, 92.0%)", + "backgroundStrong": "#ffffff", + "backgroundTransparent": "rgba(241, 245, 249, 0)", + "color": "#0F172A", + "colorHover": "#1E293B", + "colorPress": "#1E293B", + "colorFocus": "#1E293B", + "colorTransparent": "rgba(10,10,10,0)", + "borderColor": "#E2E8F0", + "borderColorHover": "#CBD5E1", + "borderColorFocus": "hsl(0, 0%, 94.1%)", + "borderColorPress": "#94A3B8", + "placeholderColor": "hsl(0, 0%, 56.1%)", + "blue1": "hsl(206, 100%, 99.2%)", + "blue2": "hsl(210, 100%, 98.0%)", + "blue3": "#E0E7FF", + "blue4": "hsl(210, 98.8%, 94.0%)", + "blue5": "hsl(209, 95.0%, 90.1%)", + "blue6": "#6366F1", + "blue7": "hsl(208, 77.5%, 76.9%)", + "blue8": "hsl(206, 81.9%, 65.3%)", + "blue9": "hsl(206, 100%, 50.0%)", + "blue10": "#FF5A5F", + "blue11": "#4338CA", + "blue12": "hsl(211, 100%, 15.0%)", + "gray1": "hsl(0, 0%, 99.0%)", + "gray2": "hsl(0, 0%, 97.3%)", + "gray3": "hsl(0, 0%, 95.1%)", + "gray4": "hsl(0, 0%, 93.0%)", + "gray5": "hsl(0, 0%, 90.9%)", + "gray6": "hsl(0, 0%, 88.7%)", + "gray7": "hsl(0, 0%, 85.8%)", + "gray8": "hsl(0, 0%, 78.0%)", + "gray9": "hsl(0, 0%, 56.1%)", + "gray10": "hsl(0, 0%, 52.3%)", + "gray11": "hsl(0, 0%, 43.5%)", + "gray12": "hsl(0, 0%, 9.0%)", + "green1": "hsl(136, 50.0%, 98.9%)", + "green2": "hsl(138, 62.5%, 96.9%)", + "green3": "hsl(139, 55.2%, 94.5%)", + "green4": "hsl(140, 48.7%, 91.0%)", + "green5": "hsl(141, 43.7%, 86.0%)", + "green6": "hsl(143, 40.3%, 79.0%)", + "green7": "hsl(146, 38.5%, 69.0%)", + "green8": "hsl(151, 40.2%, 54.1%)", + "green9": "hsl(151, 55.0%, 41.5%)", + "green10": "hsl(152, 57.5%, 37.6%)", + "green11": "hsl(153, 67.0%, 28.5%)", + "green12": "hsl(155, 40.0%, 14.0%)", + "orange1": "hsl(24, 70.0%, 99.0%)", + "orange2": "hsl(24, 83.3%, 97.6%)", + "orange3": "hsl(24, 100%, 95.3%)", + "orange4": "hsl(25, 100%, 92.2%)", + "orange5": "hsl(25, 100%, 88.2%)", + "orange6": "hsl(25, 100%, 82.8%)", + "orange7": "hsl(24, 100%, 75.3%)", + "orange8": "hsl(24, 94.5%, 64.3%)", + "orange9": "hsl(24, 94.0%, 50.0%)", + "orange10": "hsl(24, 100%, 46.5%)", + "orange11": "hsl(24, 100%, 37.0%)", + "orange12": "hsl(15, 60.0%, 17.0%)", + "pink1": "hsl(322, 100%, 99.4%)", + "pink2": "hsl(323, 100%, 98.4%)", + "pink3": "hsl(323, 86.3%, 96.5%)", + "pink4": "hsl(323, 78.7%, 94.2%)", + "pink5": "hsl(323, 72.2%, 91.1%)", + "pink6": "hsl(323, 66.3%, 86.6%)", + "pink7": "hsl(323, 62.0%, 80.1%)", + "pink8": "hsl(323, 60.3%, 72.4%)", + "pink9": "hsl(322, 65.0%, 54.5%)", + "pink10": "hsl(322, 63.9%, 50.7%)", + "pink11": "hsl(322, 75.0%, 46.0%)", + "pink12": "hsl(320, 70.0%, 13.5%)", + "purple1": "hsl(280, 65.0%, 99.4%)", + "purple2": "hsl(276, 100%, 99.0%)", + "purple3": "hsl(276, 83.1%, 97.0%)", + "purple4": "hsl(275, 76.4%, 94.7%)", + "purple5": "hsl(275, 70.8%, 91.8%)", + "purple6": "hsl(274, 65.4%, 87.8%)", + "purple7": "hsl(273, 61.0%, 81.7%)", + "purple8": "hsl(272, 60.0%, 73.5%)", + "purple9": "hsl(272, 51.0%, 54.0%)", + "purple10": "hsl(272, 46.8%, 50.3%)", + "purple11": "hsl(272, 50.0%, 45.8%)", + "purple12": "hsl(272, 66.0%, 16.0%)", + "red1": "hsl(359, 100%, 99.4%)", + "red2": "hsl(359, 100%, 98.6%)", + "red3": "hsl(360, 100%, 96.8%)", + "red4": "hsl(360, 97.9%, 94.8%)", + "red5": "hsl(360, 90.2%, 91.9%)", + "red6": "hsl(360, 81.7%, 87.8%)", + "red7": "hsl(359, 74.2%, 81.7%)", + "red8": "hsl(359, 69.5%, 74.3%)", + "red9": "hsl(358, 75.0%, 59.0%)", + "red10": "hsl(358, 69.4%, 55.2%)", + "red11": "hsl(358, 65.0%, 48.7%)", + "red12": "hsl(354, 50.0%, 14.6%)", + "yellow1": "hsl(60, 54.0%, 98.5%)", + "yellow2": "hsl(52, 100%, 95.5%)", + "yellow3": "hsl(55, 100%, 90.9%)", + "yellow4": "hsl(54, 100%, 86.6%)", + "yellow5": "hsl(52, 97.9%, 82.0%)", + "yellow6": "hsl(50, 89.4%, 76.1%)", + "yellow7": "hsl(47, 80.4%, 68.0%)", + "yellow8": "hsl(48, 100%, 46.1%)", + "yellow9": "hsl(53, 92.0%, 50.0%)", + "yellow10": "hsl(50, 100%, 48.5%)", + "yellow11": "hsl(42, 100%, 29.0%)", + "yellow12": "hsl(40, 55.0%, 13.5%)", + "shadowColor": "rgba(15, 23, 42, 0.08)", + "shadowColorHover": "rgba(0,0,0,0.085)", + "shadowColorPress": "rgba(15, 23, 42, 0.12)", + "shadowColorFocus": "rgba(15, 23, 42, 0.12)", + "colorMuted": "#64748B", + "colorSubtle": "#94A3B8", + "id": "adminLight" + }, "dark": { "blue1Light": "hsl(206, 100%, 99.2%)", "blue2Light": "hsl(210, 100%, 98.0%)", diff --git a/resources/css/app.css b/resources/css/app.css index 1fc2c716..438a6ffa 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -665,6 +665,30 @@ h4, --tenant-layer-strong: rgba(30, 41, 59, 0.94); } +.tenant-admin-theme input[type="text"], +.tenant-admin-theme input[type="search"], +.tenant-admin-theme input[type="email"], +.tenant-admin-theme input[type="password"], +.tenant-admin-theme input[type="date"], +.tenant-admin-theme input[type="datetime-local"], +.tenant-admin-theme input[type="tel"], +.tenant-admin-theme input[type="url"], +.tenant-admin-theme input[type="number"], +.tenant-admin-theme select, +.tenant-admin-theme textarea { + background-color: var(--input); + color: var(--foreground); + border-color: var(--border); + -webkit-appearance: none; + appearance: none; + color-scheme: inherit; +} + +.tenant-admin-theme input::placeholder, +.tenant-admin-theme textarea::placeholder { + color: var(--muted-foreground); +} + .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); diff --git a/resources/js/admin/DevTenantSwitcher.tsx b/resources/js/admin/DevTenantSwitcher.tsx index 584e98db..12354d79 100644 --- a/resources/js/admin/DevTenantSwitcher.tsx +++ b/resources/js/admin/DevTenantSwitcher.tsx @@ -3,7 +3,8 @@ import { Loader2, PanelLeftClose, PanelRightOpen } from 'lucide-react'; import { XStack, YStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Button } from '@tamagui/button'; -import { useTheme } from '@tamagui/core'; +import { useThemeName } from '@tamagui/core'; +import { BOTTOM_NAV_HEIGHT, BOTTOM_NAV_PADDING } from './mobile/components/BottomNav'; const DEV_TENANT_KEYS = [ { key: 'cust-standard-empty', label: 'Endkunde – Starter (kein Event)' }, @@ -28,7 +29,9 @@ type DevTenantSwitcherProps = { export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: DevTenantSwitcherProps) { const helper = window.fotospielDemoAuth; - const theme = useTheme(); + const themeName = useThemeName(); + const themeLabel = String(themeName ?? '').toLowerCase(); + const isDark = themeLabel.includes('dark') || themeLabel.includes('night'); const [loggingIn, setLoggingIn] = React.useState(null); const [collapsed, setCollapsed] = React.useState(() => { if (typeof window === 'undefined') { @@ -94,12 +97,12 @@ export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: D return ( - + Demo tenants - + Dev mode @@ -158,7 +161,7 @@ export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: D zIndex={1000} onPress={() => setCollapsed(false)} aria-label="Demo tenants anzeigen" - style={{ bottom: bottomOffset + 70 }} + style={{ bottom: bottomOffset + BOTTOM_NAV_HEIGHT + BOTTOM_NAV_PADDING }} > ); @@ -172,23 +175,23 @@ export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: D maxWidth={320} gap="$2" borderWidth={1} - borderColor="rgba(234,179,8,0.5)" - backgroundColor="rgba(255,255,255,0.95)" + borderColor={isDark ? 'rgba(248,250,255,0.2)' : 'rgba(234,179,8,0.5)'} + backgroundColor={isDark ? 'rgba(15,23,42,0.95)' : 'rgba(255,255,255,0.95)'} padding="$3" borderRadius="$4" - shadowColor="#f59e0b" + shadowColor={isDark ? 'rgba(2,6,23,0.7)' : '#f59e0b'} shadowOpacity={0.25} shadowRadius={14} shadowOffset={{ width: 0, height: 8 }} pointerEvents="auto" - style={{ bottom: bottomOffset + 70 }} + style={{ bottom: bottomOffset + BOTTOM_NAV_HEIGHT + BOTTOM_NAV_PADDING }} > - + Demo tenants - + Dev mode @@ -201,7 +204,7 @@ export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: D aria-label="Switcher minimieren" /> - + Select a seeded tenant to mint Sanctum PATs and jump straight into their admin space. Available only in development builds. @@ -219,7 +222,7 @@ export function DevTenantSwitcher({ bottomOffset = 16, variant = 'floating' }: D ))} - + Console: fotospielDemoAuth.loginAs('lumen') diff --git a/resources/js/admin/main.tsx b/resources/js/admin/main.tsx index 5ee2154c..9c4a1ef4 100644 --- a/resources/js/admin/main.tsx +++ b/resources/js/admin/main.tsx @@ -66,14 +66,15 @@ createRoot(rootEl).render( function AdminApp() { const { resolved } = useAppearance(); const themeName = resolved ?? 'light'; + const adminThemeName = themeName === 'dark' ? 'adminDark' : 'adminLight'; React.useEffect(() => { prefetchMobileRoutes(); }, []); return ( - - + + @@ -87,8 +88,12 @@ function AdminApp() { )} >
diff --git a/resources/js/admin/mobile/EventControlRoomPage.tsx b/resources/js/admin/mobile/EventControlRoomPage.tsx index 00a4da60..67e2a115 100644 --- a/resources/js/admin/mobile/EventControlRoomPage.tsx +++ b/resources/js/admin/mobile/EventControlRoomPage.tsx @@ -251,9 +251,19 @@ function PhotoActionButton({ } function PhotoStatusTag({ label }: { label: string }) { + const { textStrong } = useAdminTheme(); + const badgeBg = withAlpha(textStrong, 0.14); + const badgeBorder = withAlpha(textStrong, 0.25); return ( - - + + {label} @@ -280,7 +290,9 @@ export default function MobileEventControlRoomPage() { const isMember = user?.role === 'member'; const slug = slugParam ?? activeEvent?.slug ?? null; const online = useOnlineStatus(); - const { textStrong, text, muted, border, primary, danger, accent, surfaceMuted, surface } = useAdminTheme(); + const { textStrong, text, muted, border, primary, danger, accent, accentSoft, surfaceMuted, surface } = useAdminTheme(); + const activePillBg = accentSoft ?? withAlpha(primary, 0.18); + const activePillBorder = withAlpha(primary, 0.45); const [activeTab, setActiveTab] = React.useState<'moderation' | 'live'>('moderation'); const [moderationPhotos, setModerationPhotos] = React.useState([]); @@ -1394,7 +1406,8 @@ export default function MobileEventControlRoomPage() { value={option.value} borderRadius="$4" borderWidth={1} - borderColor={border} + borderColor={active ? activePillBorder : border} + backgroundColor={active ? activePillBg : 'transparent'} paddingVertical="$2" paddingHorizontal="$3" width="auto" @@ -1402,7 +1415,7 @@ export default function MobileEventControlRoomPage() { flexShrink={0} hoverStyle={{ backgroundColor: '$backgroundHover' }} pressStyle={{ backgroundColor: '$backgroundPress' }} - activeStyle={{ backgroundColor: '$backgroundPress', borderColor: '$borderColorPress' }} + activeStyle={{ backgroundColor: activePillBg, borderColor: activePillBorder }} > @@ -1564,21 +1577,22 @@ export default function MobileEventControlRoomPage() { const count = liveCounts[option.value] ?? 0; const active = option.value === liveStatusFilter; return ( - + {t(option.labelKey, option.fallback)} diff --git a/resources/js/admin/mobile/EventMembersPage.tsx b/resources/js/admin/mobile/EventMembersPage.tsx index 8e759287..176edad8 100644 --- a/resources/js/admin/mobile/EventMembersPage.tsx +++ b/resources/js/admin/mobile/EventMembersPage.tsx @@ -17,14 +17,16 @@ import toast from 'react-hot-toast'; import { MobileSheet } from './components/Sheet'; import { adminPath } from '../constants'; import { useBackNavigation } from './hooks/useBackNavigation'; -import { useAdminTheme } from './theme'; +import { useAdminTheme, withAlpha } from './theme'; export default function MobileEventMembersPage() { const { slug: slugParam } = useParams<{ slug?: string }>(); const slug = slugParam ?? null; const navigate = useNavigate(); const { t } = useTranslation('management'); - const { textStrong, text, muted, border, primary, danger } = useAdminTheme(); + const { textStrong, text, muted, border, primary, danger, accentSoft } = useAdminTheme(); + const activePillBg = accentSoft ?? withAlpha(primary, 0.18); + const activePillBorder = withAlpha(primary, 0.45); const [members, setMembers] = React.useState([]); const [loading, setLoading] = React.useState(true); @@ -243,22 +245,28 @@ export default function MobileEventMembersPage() { borderColor={border} backgroundColor="$background" > - {statusOptions.map((option) => ( + {statusOptions.map((option) => { + const isActive = statusFilter === option.key; + return ( - + {option.label} - ))} + ); + })} {t('events.members.filters.roleLabel', 'Role')} @@ -278,22 +286,28 @@ export default function MobileEventMembersPage() { borderColor={border} backgroundColor="$background" > - {roleOptions.map((option) => ( + {roleOptions.map((option) => { + const isActive = roleFilter === option.key; + return ( - + {option.label} - ))} + ); + })} ) : null} diff --git a/resources/js/admin/mobile/EventsPage.tsx b/resources/js/admin/mobile/EventsPage.tsx index cc7ea4be..ea3a8932 100644 --- a/resources/js/admin/mobile/EventsPage.tsx +++ b/resources/js/admin/mobile/EventsPage.tsx @@ -20,7 +20,7 @@ import { getApiErrorMessage } from '../lib/apiError'; import { useBackNavigation } from './hooks/useBackNavigation'; import { buildEventStatusCounts, filterEventsByStatus, resolveEventStatusKey, type EventStatusKey } from './lib/eventFilters'; import { buildEventListStats } from './lib/eventListStats'; -import { useAdminTheme } from './theme'; +import { useAdminTheme, withAlpha } from './theme'; import { useAuth } from '../auth/context'; export default function MobileEventsPage() { @@ -235,7 +235,9 @@ function EventsList({ onEdit?: (slug: string) => void; }) { const { t } = useTranslation('management'); - const { text, muted, subtle, border, primary, surface, surfaceMuted, shadow } = useAdminTheme(); + const { text, muted, subtle, border, primary, surface, surfaceMuted, shadow, accentSoft } = useAdminTheme(); + const activePillBg = accentSoft ?? withAlpha(primary, 0.18); + const activePillBorder = withAlpha(primary, 0.45); const statusCounts = React.useMemo(() => buildEventStatusCounts(events), [events]); const filteredByStatus = React.useMemo( @@ -329,7 +331,8 @@ function EventsList({ value={filter.key} borderRadius="$4" borderWidth={1} - borderColor={border} + borderColor={active ? activePillBorder : border} + backgroundColor={active ? activePillBg : 'transparent'} paddingVertical="$2" paddingHorizontal="$3" width="auto" @@ -337,7 +340,7 @@ function EventsList({ flexShrink={0} hoverStyle={{ backgroundColor: '$backgroundHover' }} pressStyle={{ backgroundColor: '$backgroundPress' }} - activeStyle={{ backgroundColor: '$backgroundPress', borderColor: '$borderColorPress' }} + activeStyle={{ backgroundColor: activePillBg, borderColor: activePillBorder }} > diff --git a/resources/js/admin/mobile/NotificationsPage.tsx b/resources/js/admin/mobile/NotificationsPage.tsx index bba14be4..4c54744e 100644 --- a/resources/js/admin/mobile/NotificationsPage.tsx +++ b/resources/js/admin/mobile/NotificationsPage.tsx @@ -22,7 +22,7 @@ import { useBackNavigation } from './hooks/useBackNavigation'; import { groupNotificationsByScope, type NotificationScope, type NotificationGroup } from './lib/notificationGrouping'; import { collectUnreadIds } from './lib/notificationUnread'; import { formatRelativeTime } from './lib/relativeTime'; -import { useAdminTheme } from './theme'; +import { useAdminTheme, withAlpha } from './theme'; type NotificationItem = { id: string; @@ -337,7 +337,9 @@ export default function MobileNotificationsPage() { const [events, setEvents] = React.useState([]); const [showEventPicker, setShowEventPicker] = React.useState(false); const back = useBackNavigation(adminPath('/mobile/dashboard')); - const { text, muted, border, warningBg, warningText, infoBg, primary, danger, subtle } = useAdminTheme(); + const { text, muted, border, warningBg, warningText, infoBg, primary, danger, subtle, accentSoft } = useAdminTheme(); + const activePillBg = accentSoft ?? withAlpha(primary, 0.18); + const activePillBorder = withAlpha(primary, 0.45); const warningIcon = warningText; const infoIcon = primary; const errorText = danger; @@ -587,11 +589,16 @@ export default function MobileNotificationsPage() { { key: 'events', label: t('notificationLogs.scope.events', 'Events') }, { key: 'package', label: t('notificationLogs.scope.package', 'Package') }, { key: 'general', label: t('notificationLogs.scope.general', 'General') }, - ] as Array<{ key: NotificationScope | 'all'; label: string }>).map((filter) => ( + ] as Array<{ key: NotificationScope | 'all'; label: string }>).map((filter) => { + const isActive = (scopeParam ?? 'all') === filter.key; + return ( - + {filter.label} - ))} + ); + })} {loading ? ( diff --git a/resources/js/admin/mobile/__tests__/AdminTheme.test.tsx b/resources/js/admin/mobile/__tests__/AdminTheme.test.tsx index 2d2c18c5..3f63310a 100644 --- a/resources/js/admin/mobile/__tests__/AdminTheme.test.tsx +++ b/resources/js/admin/mobile/__tests__/AdminTheme.test.tsx @@ -21,18 +21,17 @@ const ThemeProbe = () => { ); }; -const renderWithTheme = (name: 'light' | 'dark') => - render( - - - - - - ); +const renderTree = (name: 'adminLight' | 'adminDark') => ( + + + + + +); describe('useAdminTheme', () => { it('tracks Tamagui theme values across light and dark modes', () => { - const { rerender } = renderWithTheme('light'); + const { rerender } = render(renderTree('adminLight')); const probe = screen.getByTestId('probe'); const lightAdminBg = probe.getAttribute('data-admin-bg'); const lightThemeBg = probe.getAttribute('data-theme-bg'); @@ -42,13 +41,7 @@ describe('useAdminTheme', () => { expect(lightAdminBg).toBe(lightThemeBg); expect(lightAdminText).toBe(lightThemeText); - rerender( - - - - - - ); + rerender(renderTree('adminDark')); const darkProbe = screen.getByTestId('probe'); const darkAdminBg = darkProbe.getAttribute('data-admin-bg'); diff --git a/resources/js/admin/mobile/__tests__/EventsPage.test.tsx b/resources/js/admin/mobile/__tests__/EventsPage.test.tsx index ece46fc6..1e75da23 100644 --- a/resources/js/admin/mobile/__tests__/EventsPage.test.tsx +++ b/resources/js/admin/mobile/__tests__/EventsPage.test.tsx @@ -215,6 +215,7 @@ vi.mock('../theme', () => ({ accent: '#6366f1', shadow: 'rgba(15,23,42,0.12)', }), + withAlpha: (value: string) => value, })); import MobileEventsPage from '../EventsPage'; diff --git a/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx b/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx index 0d3597dd..06b5faf6 100644 --- a/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx +++ b/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx @@ -128,7 +128,9 @@ vi.mock('../theme', () => ({ successText: '#166534', infoBg: '#e0e7ff', infoText: '#3730a3', + accentSoft: '#eef2ff', }), + withAlpha: (value: string) => value, })); import MobileNotificationsPage from '../NotificationsPage'; diff --git a/resources/js/admin/mobile/components/BottomNav.tsx b/resources/js/admin/mobile/components/BottomNav.tsx index 11a0958d..f944013b 100644 --- a/resources/js/admin/mobile/components/BottomNav.tsx +++ b/resources/js/admin/mobile/components/BottomNav.tsx @@ -10,6 +10,7 @@ import { adminPath } from '../../constants'; const ICON_SIZE = 24; export const BOTTOM_NAV_HEIGHT = 70; +export const BOTTOM_NAV_PADDING = 8; export type NavKey = 'home' | 'tasks' | 'uploads' | 'profile'; @@ -51,7 +52,7 @@ export function BottomNav({ active, onNavigate }: { active: NavKey; onNavigate: shadowRadius={20} shadowOffset={{ width: 0, height: -8 }} style={{ - paddingBottom: 'max(env(safe-area-inset-bottom, 0px), 8px)', + paddingBottom: `calc(env(safe-area-inset-bottom, 0px) + ${BOTTOM_NAV_PADDING}px)`, backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)', }} diff --git a/resources/js/admin/mobile/components/FormControls.tsx b/resources/js/admin/mobile/components/FormControls.tsx index 05d7e2d9..1c75884b 100644 --- a/resources/js/admin/mobile/components/FormControls.tsx +++ b/resources/js/admin/mobile/components/FormControls.tsx @@ -95,7 +95,7 @@ export const MobileDateTimeInput = React.forwardRef< HTMLInputElement, React.ComponentPropsWithoutRef<'input'> & ControlProps >(function MobileDateTimeInput({ hasError = false, style, ...props }, ref) { - const { border, surface, text, primary, danger } = useAdminTheme(); + const { border, surface, text, primary, danger, isDark } = useAdminTheme(); const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); const borderColor = hasError ? danger : border; @@ -114,6 +114,9 @@ export const MobileDateTimeInput = React.forwardRef< borderColor, backgroundColor: surface, color: text, + WebkitAppearance: 'none', + appearance: 'none', + colorScheme: isDark ? 'dark' : 'light', fontSize: 14, outline: 'none', boxShadow: `0 0 0 0 ${ringColor}`, @@ -135,7 +138,7 @@ export const MobileDateInput = React.forwardRef< HTMLInputElement, React.ComponentPropsWithoutRef<'input'> & ControlProps >(function MobileDateInput({ hasError = false, style, ...props }, ref) { - const { border, surface, text, primary, danger } = useAdminTheme(); + const { border, surface, text, primary, danger, isDark } = useAdminTheme(); const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); const borderColor = hasError ? danger : border; @@ -154,6 +157,9 @@ export const MobileDateInput = React.forwardRef< borderColor, backgroundColor: surface, color: text, + WebkitAppearance: 'none', + appearance: 'none', + colorScheme: isDark ? 'dark' : 'light', fontSize: 14, outline: 'none', boxShadow: `0 0 0 0 ${ringColor}`, @@ -173,7 +179,7 @@ export const MobileDateInput = React.forwardRef< export const MobileInput = React.forwardRef & ControlProps>( function MobileInput({ hasError = false, compact = false, style, onChange, type, ...props }, ref) { - const { border, surface, text, primary, danger } = useAdminTheme(); + const { border, surface, text, primary, danger, isDark } = useAdminTheme(); const borderColor = hasError ? danger : border; const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); const isPassword = type === 'password'; @@ -196,6 +202,12 @@ export const MobileInput = React.forwardRef ); }, @@ -213,7 +224,7 @@ export const MobileTextArea = React.forwardRef< HTMLTextAreaElement, React.ComponentPropsWithoutRef<'textarea'> & ControlProps >(function MobileTextArea({ hasError = false, compact = false, style, onChange, ...props }, ref) { - const { border, surface, text, primary, danger } = useAdminTheme(); + const { border, surface, text, primary, danger, isDark } = useAdminTheme(); const borderColor = hasError ? danger : border; const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); @@ -233,6 +244,13 @@ export const MobileTextArea = React.forwardRef< backgroundColor={surface} color={text} borderColor={borderColor} + style={{ + resize: 'vertical', + WebkitAppearance: 'none', + appearance: 'none', + colorScheme: isDark ? 'dark' : 'light', + ...style, + } as any} focusStyle={{ borderColor: hasError ? danger : primary, boxShadow: `0 0 0 3px ${ringColor}`, @@ -240,7 +258,6 @@ export const MobileTextArea = React.forwardRef< hoverStyle={{ borderColor, } as any} - style={{ resize: 'vertical', ...style } as any} /> ); }); @@ -253,7 +270,8 @@ export function MobileSelect({ style, ...props }: MobileSelectProps) { - const { border, surface, text, primary, danger, subtle, glassSurfaceStrong, surfaceMuted, glassBorder } = useAdminTheme(); + const { border, surface, text, primary, danger, subtle, glassSurfaceStrong, surfaceMuted, glassBorder, isDark } = + useAdminTheme(); const borderColor = hasError ? danger : (glassBorder ?? border); const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); const triggerSurface = surfaceMuted ?? glassSurfaceStrong ?? surface; @@ -316,7 +334,12 @@ export function MobileSelect({ hoverStyle={{ borderColor: borderColor as any, }} - style={style as any} + style={{ + WebkitAppearance: 'none', + appearance: 'none', + colorScheme: isDark ? 'dark' : 'light', + ...style, + } as any} > diff --git a/resources/js/admin/mobile/components/MobileShell.tsx b/resources/js/admin/mobile/components/MobileShell.tsx index fde14492..7d7aab18 100644 --- a/resources/js/admin/mobile/components/MobileShell.tsx +++ b/resources/js/admin/mobile/components/MobileShell.tsx @@ -5,7 +5,7 @@ import { YStack, XStack, SizableText as Text, Image } from 'tamagui'; import { Pressable } from '@tamagui/react-native-web-lite'; import { useTranslation } from 'react-i18next'; import { useEventContext } from '../../context/EventContext'; -import { BottomNav, BOTTOM_NAV_HEIGHT, NavKey } from './BottomNav'; +import { BottomNav, BOTTOM_NAV_HEIGHT, BOTTOM_NAV_PADDING, NavKey } from './BottomNav'; import { useMobileNav } from '../hooks/useMobileNav'; import { ADMIN_EVENTS_PATH, adminPath } from '../../constants'; import { MobileCard, CTAButton } from './Primitives'; @@ -336,7 +336,9 @@ export function MobileShell({ title, subtitle, children, activeTab, onBack, head gap="$3" width="100%" maxWidth={800} - style={{ paddingBottom: `calc(env(safe-area-inset-bottom, 0px) + ${BOTTOM_NAV_HEIGHT}px)` }} + style={{ + paddingBottom: `calc(env(safe-area-inset-bottom, 0px) + ${BOTTOM_NAV_HEIGHT + BOTTOM_NAV_PADDING}px)`, + }} > {!online ? ( diff --git a/resources/js/admin/mobile/components/Primitives.tsx b/resources/js/admin/mobile/components/Primitives.tsx index 9fa03c32..5040c451 100644 --- a/resources/js/admin/mobile/components/Primitives.tsx +++ b/resources/js/admin/mobile/components/Primitives.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Card, YStack, XStack, SizableText as Text, Tabs, Separator } from 'tamagui'; import { Pressable } from '@tamagui/react-native-web-lite'; import { useAdminTheme } from '../theme'; +import { BOTTOM_NAV_HEIGHT, BOTTOM_NAV_PADDING } from './BottomNav'; import { withAlpha } from './colors'; export function MobileCard({ @@ -393,7 +394,7 @@ export function FloatingActionButton({ style={{ position: 'fixed', right: 18, - bottom: 'calc(env(safe-area-inset-bottom, 0px) + 96px)', + bottom: `calc(env(safe-area-inset-bottom, 0px) + ${BOTTOM_NAV_HEIGHT + BOTTOM_NAV_PADDING + 12}px)`, zIndex: 60, transform: pressed ? 'scale(0.96)' : 'scale(1)', opacity: pressed ? 0.92 : 1, @@ -434,7 +435,10 @@ export function ContentTabs({ tabs: { value: string; label: string; content: React.ReactNode }[]; header?: React.ReactNode; }) { - const { muted, text } = useAdminTheme(); + const { muted, text, border, glassBorder, accentSoft, primary } = useAdminTheme(); + const tabBorder = glassBorder ?? border; + const activeBg = accentSoft ?? withAlpha(primary, 0.18); + const activeBorder = withAlpha(primary, 0.45); return ( } disablePassBorderRadius="bottom"> - {tabs.map((tab) => ( + {tabs.map((tab) => { + const isActive = value === tab.value; + return ( {tab.label} - ))} + ); + })} {header} diff --git a/resources/js/admin/mobile/components/Sheet.tsx b/resources/js/admin/mobile/components/Sheet.tsx index cdb84aec..07cab8a6 100644 --- a/resources/js/admin/mobile/components/Sheet.tsx +++ b/resources/js/admin/mobile/components/Sheet.tsx @@ -5,6 +5,7 @@ import { Pressable } from '@tamagui/react-native-web-lite'; import { Sheet } from '@tamagui/sheet'; import { useTranslation } from 'react-i18next'; import { useAdminTheme } from '../theme'; +import { BOTTOM_NAV_HEIGHT, BOTTOM_NAV_PADDING } from './BottomNav'; type SheetProps = { open: boolean; @@ -30,7 +31,7 @@ export function MobileSheet({ contentSpacing = '$3', padding = '$4', paddingBottom = '$7', - bottomOffsetPx = 88, + bottomOffsetPx = BOTTOM_NAV_HEIGHT + BOTTOM_NAV_PADDING, }: SheetProps) { const { t } = useTranslation('mobile'); const { surface, textStrong, muted, overlay, shadow, border } = useAdminTheme(); diff --git a/resources/js/admin/mobile/components/UserMenuSheet.tsx b/resources/js/admin/mobile/components/UserMenuSheet.tsx index dd9761bb..8bff92ff 100644 --- a/resources/js/admin/mobile/components/UserMenuSheet.tsx +++ b/resources/js/admin/mobile/components/UserMenuSheet.tsx @@ -1,12 +1,13 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { ChevronRight, CreditCard, FileText, HelpCircle, User, X } from 'lucide-react'; -import { XStack, YStack, SizableText as Text, ListItem, YGroup, Switch, Separator } from 'tamagui'; +import { ChevronRight, CreditCard, FileText, HelpCircle, Moon, Sun, User, X } from 'lucide-react'; +import { XStack, YStack, SizableText as Text, ListItem, YGroup, Separator } from 'tamagui'; import { Pressable } from '@tamagui/react-native-web-lite'; +import { ToggleGroup } from '@tamagui/toggle-group'; import { useAppearance } from '@/hooks/use-appearance'; import { ADMIN_BILLING_PATH, ADMIN_DATA_EXPORTS_PATH, ADMIN_FAQ_PATH, ADMIN_PROFILE_ACCOUNT_PATH, adminPath } from '../../constants'; -import { useAdminTheme } from '../theme'; +import { useAdminTheme, withAlpha } from '../theme'; import { MobileSelect } from './FormControls'; type UserMenuSheetProps = { @@ -30,7 +31,9 @@ export function UserMenuSheet({ open, onClose, user, isMember, navigate }: UserM setLanguage(i18n.language?.startsWith('en') ? 'en' : 'de'); }, [i18n.language]); - const isDark = resolved === 'dark'; + const themeValue: 'light' | 'dark' = (appearance === 'system' ? resolved : appearance) ?? 'light'; + const activeToggleBg = theme.accentSoft ?? withAlpha(theme.primary, 0.18); + const activeToggleBorder = withAlpha(theme.primary, 0.45); const handleNavigate = (path: string) => { onClose(); @@ -239,14 +242,46 @@ export function UserMenuSheet({ open, onClose, user, isMember, navigate }: UserM } iconAfter={ - updateAppearance(next ? 'dark' : 'light')} - aria-label={t('mobileProfile.theme', 'Dark Mode')} + { + if (next === 'light' || next === 'dark') { + updateAppearance(next); + } + }} + disableDeactivation + orientation="horizontal" + flexDirection="row" + gap="$1.5" > - - + {([ + { key: 'light', label: t('mobileProfile.themeLight', 'Light'), icon: Sun }, + { key: 'dark', label: t('mobileProfile.themeDark', 'Dark'), icon: Moon }, + ] as const).map((option) => { + const active = option.key === themeValue; + const Icon = option.icon; + return ( + + + + + {option.label} + + + + ); + })} + } /> diff --git a/resources/js/admin/mobile/components/__tests__/MobileShell.test.tsx b/resources/js/admin/mobile/components/__tests__/MobileShell.test.tsx index 9f800929..408fafba 100644 --- a/resources/js/admin/mobile/components/__tests__/MobileShell.test.tsx +++ b/resources/js/admin/mobile/components/__tests__/MobileShell.test.tsx @@ -55,6 +55,7 @@ vi.mock('tamagui', () => ({ vi.mock('../BottomNav', () => ({ BottomNav: () =>
, BOTTOM_NAV_HEIGHT: 70, + BOTTOM_NAV_PADDING: 8, NavKey: {}, })); diff --git a/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx b/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx index c1fa6114..272d2afe 100644 --- a/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx +++ b/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx @@ -17,8 +17,6 @@ vi.mock('@tamagui/react-native-web-lite', () => ({ vi.mock('tamagui', () => { const Stack = ({ children, ...props }: { children: React.ReactNode }) =>
{children}
; const Text = ({ children, ...props }: { children: React.ReactNode }) => {children}; - const Switch = ({ children }: { children?: React.ReactNode }) =>
{children}
; - Switch.Thumb = () =>
; const ListItem = ({ title, iconAfter, ...props }: { title?: React.ReactNode; iconAfter?: React.ReactNode }) => (
@@ -36,11 +34,16 @@ vi.mock('tamagui', () => { SizableText: Text, ListItem, YGroup, - Switch, Separator: ({ children }: { children?: React.ReactNode }) =>
{children}
, }; }); +vi.mock('@tamagui/toggle-group', () => ({ + ToggleGroup: Object.assign(({ children }: { children: React.ReactNode }) =>
{children}
, { + Item: ({ children }: { children: React.ReactNode }) =>
{children}
, + }), +})); + vi.mock('../FormControls', () => ({ MobileSelect: ({ children }: { children: React.ReactNode }) => , })); @@ -66,6 +69,7 @@ vi.mock('../../theme', () => ({ glassShadow: 'rgba(15,23,42,0.14)', shadow: 'rgba(0,0,0,0.12)', }), + withAlpha: (value: string) => value, })); import { UserMenuSheet } from '../UserMenuSheet'; diff --git a/resources/js/admin/mobile/theme.ts b/resources/js/admin/mobile/theme.ts index d5244d45..0516162c 100644 --- a/resources/js/admin/mobile/theme.ts +++ b/resources/js/admin/mobile/theme.ts @@ -110,8 +110,8 @@ export function useAdminTheme() { // Muted/Subtle should NOT use theme.muted (which is a background color in Tamagui standard) // Instead, we derive them from Text with opacity or use specific palette values if available // But safer is Alpha since it works in both Light (Dark Text) and Dark (Light Text) modes. - const muted = withAlpha(text, 0.65); - const subtle = withAlpha(text, 0.45); + const muted = resolveThemeValue((theme as any).colorMuted?.val, withAlpha(text, 0.65)); + const subtle = resolveThemeValue((theme as any).colorSubtle?.val, withAlpha(text, 0.45)); const surfaceMuted = resolveThemeValue(theme.muted?.val, isDark ? '#121F3D' : ADMIN_COLORS.surfaceMuted); const glassSurface = withAlpha(surface, isDark ? 0.90 : 0.85); @@ -122,6 +122,7 @@ export function useAdminTheme() { return { theme, + isDark, background, surface, surfaceMuted, @@ -134,7 +135,7 @@ export function useAdminTheme() { subtle, // Now properly derived from text color primary, accent: resolveThemeValue(theme.accent?.val, ADMIN_COLORS.accent), - accentSoft: resolveThemeValue(theme.blue3?.val, ADMIN_COLORS.accentSoft), + accentSoft: resolveThemeValue((theme as any).accentSoft?.val ?? theme.blue3?.val, ADMIN_COLORS.accentSoft), accentStrong: resolveThemeValue(theme.blue11?.val, ADMIN_COLORS.primaryStrong), successBg: resolveThemeValue(theme.backgroundStrong?.val, '#DCFCE7'), successText: resolveThemeValue(theme.green10?.val, ADMIN_COLORS.success), diff --git a/tamagui.config.ts b/tamagui.config.ts index d4ae76f3..e4749c46 100644 --- a/tamagui.config.ts +++ b/tamagui.config.ts @@ -57,6 +57,13 @@ const lightTheme = { blue11: '#4338CA', // Indigo 700 }; +const adminLightTheme = { + ...lightTheme, + accentSoft: tokens.color.accentSoft, + colorMuted: '#64748B', // Slate 500 + colorSubtle: '#94A3B8', // Slate 400 +}; + const guestLightTheme = { ...baseThemes.light, primary: 'var(--guest-primary, #FF5A5F)', @@ -111,6 +118,34 @@ const darkTheme = { blue11: '#FF8A8A', }; +const adminDarkTheme = { + ...darkTheme, + background: '#0F172A', + backgroundHover: '#101A36', + backgroundPress: '#132142', + backgroundStrong: '#16223A', + backgroundTransparent: 'rgba(15, 23, 42, 0)', + color: '#F8FAFF', + colorHover: '#FFFFFF', + colorPress: '#E8EEFF', + colorFocus: '#FFFFFF', + borderColor: 'rgba(148, 163, 184, 0.25)', + borderColorHover: 'rgba(148, 163, 184, 0.35)', + borderColorPress: 'rgba(148, 163, 184, 0.45)', + shadowColor: 'rgba(2, 6, 23, 0.7)', + shadowColorPress: 'rgba(2, 6, 23, 0.8)', + shadowColorFocus: 'rgba(2, 6, 23, 0.8)', + surface: '#16223A', + muted: '#1C2844', + blue3: 'rgba(255, 90, 95, 0.18)', + blue6: '#FF5A5F', + blue10: '#FF5A5F', + blue11: '#FF8A8A', + accentSoft: 'rgba(255, 90, 95, 0.18)', + colorMuted: 'rgba(248, 250, 255, 0.68)', + colorSubtle: 'rgba(248, 250, 255, 0.5)', +}; + const guestNightTheme = { ...baseThemes.dark, primary: 'var(--guest-primary, #FF4FD8)', @@ -143,6 +178,8 @@ const themes = { ...baseThemes, light: lightTheme, dark: darkTheme, + adminLight: adminLightTheme, + adminDark: adminDarkTheme, guestLight: { ...guestLightTheme }, guestDark: { ...darkTheme }, guestNight: { ...guestNightTheme },