+
+
-
+
diff --git a/components/CustomBranding.tsx b/components/CustomBranding.tsx
index 74b5bd0c..75acc79c 100644
--- a/components/CustomBranding.tsx
+++ b/components/CustomBranding.tsx
@@ -1,8 +1,38 @@
import { useEffect } from "react";
+function computeContrastRatio(a: number[], b: number[]) {
+ const lum1 = computeLuminance(a[0], a[1], a[2]);
+ const lum2 = computeLuminance(b[0], b[1], b[2]);
+ const brightest = Math.max(lum1, lum2);
+ const darkest = Math.min(lum1, lum2);
+ return (brightest + 0.05) / (darkest + 0.05);
+}
+
+function computeLuminance(r: number, g: number, b: number) {
+ const a = [r, g, b].map((v) => {
+ v /= 255;
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
+ });
+ return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
+}
+
+function hexToRGB(hex: string) {
+ const color = hex.replace("#", "");
+ return [parseInt(color.slice(0, 2), 16), parseInt(color.slice(2, 4), 16), parseInt(color.slice(4, 6), 16)];
+}
+
+function getContrastingTextColor(bgColor: string | null): string {
+ bgColor = bgColor == "" || bgColor == null ? "#292929" : bgColor;
+ const rgb = hexToRGB(bgColor);
+ const whiteContrastRatio = computeContrastRatio(rgb, [255, 255, 255]);
+ const blackContrastRatio = computeContrastRatio(rgb, [41, 41, 41]); //#292929
+ return whiteContrastRatio > blackContrastRatio ? "#ffffff" : "#292929";
+}
+
const BrandColor = ({ val = "#292929" }: { val: string | undefined | null }) => {
useEffect(() => {
document.documentElement.style.setProperty("--brand-color", val);
+ document.documentElement.style.setProperty("--brand-text-color", getContrastingTextColor(val));
}, [val]);
return null;
};
diff --git a/components/Tooltip.tsx b/components/Tooltip.tsx
index b27f3c25..b932152d 100644
--- a/components/Tooltip.tsx
+++ b/components/Tooltip.tsx
@@ -23,7 +23,7 @@ export function Tooltip({
onOpenChange={onOpenChange}>
{children}
diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx
index 92e64c31..eaa8ab33 100644
--- a/components/booking/AvailableTimes.tsx
+++ b/components/booking/AvailableTimes.tsx
@@ -84,7 +84,7 @@ const AvailableTimes: FC = ({
{slot.time.format(timeFormat)}
diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx
index bc207579..5fd9832b 100644
--- a/components/booking/DatePicker.tsx
+++ b/components/booking/DatePicker.tsx
@@ -200,13 +200,11 @@ function DatePicker({
className={classNames(
"absolute w-full top-0 left-0 right-0 bottom-0 rounded-sm text-center mx-auto",
"hover:border hover:border-brand dark:hover:border-white",
- day.disabled
- ? "text-gray-400 font-light hover:border-0 cursor-default"
- : "dark:text-white text-primary-500 font-medium",
+ day.disabled ? "text-gray-400 font-light hover:border-0 cursor-default" : "font-medium",
date && date.isSame(inviteeDate().date(day.date), "day")
- ? "bg-brand text-white-important"
+ ? "bg-brand text-brandcontrast"
: !day.disabled
- ? " bg-gray-100 dark:bg-gray-600"
+ ? " bg-gray-100 dark:bg-gray-600 dark:text-white"
: ""
)}
data-testid="day"
diff --git a/components/booking/TimeOptions.tsx b/components/booking/TimeOptions.tsx
index b707e638..8b6c79af 100644
--- a/components/booking/TimeOptions.tsx
+++ b/components/booking/TimeOptions.tsx
@@ -35,19 +35,19 @@ const TimeOptions: FC
= (props) => {
};
return selectedTimeZone !== "" ? (
-
+
-
{t("time_options")}
+
{t("time_options")}
- {t("am_pm")}
+ {t("am_pm")}
{t("use_setting")}
@@ -60,7 +60,7 @@ const TimeOptions: FC = (props) => {
/>
- {t("24_h")}
+ {t("24_h")}
@@ -69,7 +69,7 @@ const TimeOptions: FC
= (props) => {
id="timeZone"
value={selectedTimeZone}
onChange={(tz: ITimezoneOption) => setSelectedTimeZone(tz.value)}
- className="mb-2 shadow-sm focus:ring-black focus:border-brand mt-1 block w-full sm:text-sm border-gray-300 rounded-md"
+ className="block w-full mt-1 mb-2 border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
/>
) : null;
diff --git a/components/security/TwoFactorModalHeader.tsx b/components/security/TwoFactorModalHeader.tsx
index bcf5f21f..b2c763fe 100644
--- a/components/security/TwoFactorModalHeader.tsx
+++ b/components/security/TwoFactorModalHeader.tsx
@@ -4,11 +4,11 @@ import React from "react";
const TwoFactorModalHeader = ({ title, description }: { title: string; description: string }) => {
return (
-
+
-
+
{title}
{description}
diff --git a/components/team/MemberInvitationModal.tsx b/components/team/MemberInvitationModal.tsx
index 5f873c58..370462a9 100644
--- a/components/team/MemberInvitationModal.tsx
+++ b/components/team/MemberInvitationModal.tsx
@@ -62,8 +62,8 @@ export default function MemberInvitationModal(props: { team: TeamWithMembers | n
-
-
+
+
diff --git a/components/ui/Avatar.tsx b/components/ui/Avatar.tsx
index 97cf5204..f1a3734c 100644
--- a/components/ui/Avatar.tsx
+++ b/components/ui/Avatar.tsx
@@ -36,7 +36,7 @@ export default function Avatar(props: AvatarProps) {
return title ? (
{avatar}
-
+
{title}
diff --git a/components/ui/Button.tsx b/components/ui/Button.tsx
index a72f851e..6a746346 100644
--- a/components/ui/Button.tsx
+++ b/components/ui/Button.tsx
@@ -64,7 +64,7 @@ export const Button = forwardRef {
}}
className={`
w-10 h-10
- bg-brand text-white focus:outline-none px-3 py-1 rounded
+ bg-brand text-brandcontrast focus:outline-none px-3 py-1 rounded
${activeDays[idx + 1] ? "rounded-r-none" : ""}
${activeDays[idx - 1] ? "rounded-l-none" : ""}
${idx === 0 ? "rounded-l" : ""}
diff --git a/components/ui/form/PhoneInput.tsx b/components/ui/form/PhoneInput.tsx
index 7b1bb474..c7e102b7 100644
--- a/components/ui/form/PhoneInput.tsx
+++ b/components/ui/form/PhoneInput.tsx
@@ -8,7 +8,7 @@ export const PhoneInput = (props: PhoneInputProps) => (
{
diff --git a/ee/components/stripe/Payment.tsx b/ee/components/stripe/Payment.tsx
index 66b484bc..683f5d8c 100644
--- a/ee/components/stripe/Payment.tsx
+++ b/ee/components/stripe/Payment.tsx
@@ -15,7 +15,7 @@ import Button from "@components/ui/Button";
const CARD_OPTIONS = {
iconStyle: "solid" as const,
classes: {
- base: "block p-2 w-full border-solid border-2 border-gray-300 rounded-md shadow-sm dark:bg-brand dark:text-white dark:border-gray-900 focus-within:ring-black focus-within:border-brand sm:text-sm",
+ base: "block p-2 w-full border-solid border-2 border-gray-300 rounded-md shadow-sm dark:bg-brand dark:text-brandcontrast dark:border-gray-900 focus-within:ring-black focus-within:border-brand sm:text-sm",
},
style: {
base: {
diff --git a/ee/components/team/availability/TeamAvailabilityTimes.tsx b/ee/components/team/availability/TeamAvailabilityTimes.tsx
index 04838312..691afe01 100644
--- a/ee/components/team/availability/TeamAvailabilityTimes.tsx
+++ b/ee/components/team/availability/TeamAvailabilityTimes.tsx
@@ -59,7 +59,7 @@ export default function TeamAvailabilityTimes(props: Props) {
{times.map((time) => (
{time.format("HH:mm")}
diff --git a/pages/auth/forgot-password/index.tsx b/pages/auth/forgot-password/index.tsx
index 101c143f..4f7066b5 100644
--- a/pages/auth/forgot-password/index.tsx
+++ b/pages/auth/forgot-password/index.tsx
@@ -69,7 +69,7 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
const Success = () => {
return (
-
{t("done")}
+
{t("done")}
{t("check_email_reset_password")}
{error &&
{error.message}
}
@@ -77,15 +77,15 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
};
return (
-
+
-
+
{success &&
}
{!success && (
<>
-
+
{t("forgot_password")}
{t("reset_instructions")}
@@ -107,7 +107,7 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
autoComplete="email"
placeholder="john.doe@example.com"
required
- className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-black focus:border-brand sm:text-sm"
+ className="block w-full px-3 py-2 placeholder-gray-400 border border-gray-300 rounded-md shadow-sm appearance-none focus:outline-none focus:ring-black focus:border-brand sm:text-sm"
/>
@@ -116,12 +116,12 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {