From a16f63a7ef4e0f7cc678d551133a75b7d0e248a6 Mon Sep 17 00:00:00 2001 From: Sam Holmes Date: Sun, 23 Aug 2026 19:00:24 -0700 Subject: [PATCH 01/31] feat: add system-aware light mode --- app/admin/talks/page.tsx | 35 +++++++-------- app/admin/thumbnails/page.tsx | 24 +++++----- app/components/Button.tsx | 42 +++++++++--------- app/components/Card.tsx | 16 +++---- app/components/CheckboxInput.tsx | 4 +- app/components/ErrorBoundary.tsx | 2 +- app/components/Footer.tsx | 4 +- app/components/Header.tsx | 40 ++++++++--------- app/components/HelpInfoButton.tsx | 8 ++-- app/components/LinkCloudSection.tsx | 4 +- app/components/LinkInput.tsx | 34 +++++++-------- app/components/Modal.tsx | 6 +-- app/components/PageContainer.tsx | 2 +- app/components/PotionBackground.tsx | 15 ++++--- app/components/RadioInput.tsx | 6 +-- app/components/TagCloudSection.tsx | 4 +- app/components/TagInput.tsx | 51 +++++++++++----------- app/components/TextInput.tsx | 10 ++--- app/components/TextareaInput.tsx | 11 ++--- app/components/icons/index.tsx | 6 ++- app/doorbell/layout.tsx | 4 +- app/doorbell/page.tsx | 16 ++++--- app/event-terms/page.tsx | 18 ++++---- app/events/[eventId]/EventDetailClient.tsx | 36 ++++++++------- app/events/page.tsx | 16 ++++--- app/globals.css | 38 ++++++++++++++-- app/login/page.tsx | 16 +++---- app/nametags/page.tsx | 10 +++-- app/page.tsx | 22 +++++++--- app/reset-password/page.tsx | 6 +-- app/setup/page.tsx | 10 ++--- app/slides/SlidesListClient.tsx | 10 ++--- app/slides/[slug]/SlideDetailClient.tsx | 10 ++--- app/submit-talk/page.tsx | 42 +++++++++--------- app/talk/page.tsx | 20 ++++----- app/talk/submitted/page.tsx | 8 ++-- app/watch/page.tsx | 16 ++++--- app/whois/ProfileDisplay.tsx | 2 +- app/whois/ProfileList.tsx | 10 ++--- app/whois/ProfileNotFound.tsx | 6 +-- app/whois/page.tsx | 4 +- 41 files changed, 355 insertions(+), 289 deletions(-) diff --git a/app/admin/talks/page.tsx b/app/admin/talks/page.tsx index 4307095..4559ea4 100644 --- a/app/admin/talks/page.tsx +++ b/app/admin/talks/page.tsx @@ -403,7 +403,7 @@ export default function AdminTalks() { // Styled Components // const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -434,12 +434,12 @@ const PageHeader = styled.div` const Title = styled.h1` font-size: 2rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; ` const Subtitle = styled.p` - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); margin: 0.5rem 0 0 0; ` @@ -450,7 +450,7 @@ const FilterBar = styled.div` ` const FilterLabel = styled.span` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 0.875rem; font-weight: 600; ` @@ -470,10 +470,11 @@ const FilterButton = styled.button<{ $active: boolean; $color?: string }>` transition: all 0.2s ease; text-transform: capitalize; border: 1px solid - ${(props) => (props.$active ? props.$color || "white" : "rgba(255, 255, 255, 0.2)")}; + ${(props) => (props.$active ? props.$color || "white" : "rgba(var(--foreground-rgb), 0.2)")}; background-color: ${(props) => props.$active ? (props.$color || "white") + "22" : "transparent"}; - color: ${(props) => (props.$active ? props.$color || "white" : "rgba(255, 255, 255, 0.6)")}; + color: ${(props) => + props.$active ? props.$color || "white" : "rgba(var(--foreground-rgb), 0.6)"}; &:hover { border-color: ${(props) => props.$color || "white"}; @@ -488,10 +489,10 @@ const TalkList = styled.div` ` const TalkCard = styled.div` - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.1); + border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.5rem; display: flex; @@ -509,7 +510,7 @@ const CardHeader = styled.div` const TalkTitle = styled.h2` font-size: 1.125rem; font-weight: 600; - color: white; + color: var(--foreground); margin: 0; flex: 1; ` @@ -612,7 +613,7 @@ const StatusPillSelect = styled.select<{ $color: string; $widthCh: number }>` option { background-color: #1a1a2e; - color: white; + color: var(--foreground); } ` @@ -632,7 +633,7 @@ const MetaRow = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 0.75rem; - background-color: rgba(255, 255, 255, 0.03); + background-color: rgba(var(--foreground-rgb), 0.03); border-radius: 0.75rem; padding: 0.75rem; @@ -654,14 +655,14 @@ const MetaItem = styled.div` const MetaLabel = styled.span` font-size: 0.6875rem; font-weight: 600; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); text-transform: uppercase; letter-spacing: 0.05em; ` const MetaValue = styled.span` font-size: 0.875rem; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); display: flex; align-items: center; gap: 0.5rem; @@ -678,7 +679,7 @@ const HandleLink = styled.a` ` const Synopsis = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 0.875rem; line-height: 1.6; margin: 0; @@ -687,7 +688,7 @@ const Synopsis = styled.p` const SlidesInfo = styled.div` font-size: 0.8125rem; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); ` const SlidesLink = styled.a` @@ -732,13 +733,13 @@ const ErrorMessage = styled.div` const EmptyState = styled.div` text-align: center; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); padding: 3rem; font-size: 1rem; ` const LoadingText = styled.div` - color: white; + color: var(--foreground); font-size: 1.25rem; text-align: center; margin-top: 4rem; diff --git a/app/admin/thumbnails/page.tsx b/app/admin/thumbnails/page.tsx index 2e05d9d..00e9aa2 100644 --- a/app/admin/thumbnails/page.tsx +++ b/app/admin/thumbnails/page.tsx @@ -358,7 +358,7 @@ function AdminTalkThumbnailGen() { // const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -382,13 +382,13 @@ const Container = styled.main` const Title = styled.h1` font-size: 2rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; text-align: center; ` const Subtitle = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); margin: -1rem 0 0 0; text-align: center; ` @@ -441,15 +441,15 @@ const Field = styled.div` const Label = styled.label` font-size: 0.875rem; font-weight: 700; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); ` const FileInput = styled.input` padding: 0.5rem; - background-color: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); + background-color: rgba(var(--foreground-rgb), 0.1); + border: 1px solid rgba(var(--foreground-rgb), 0.2); border-radius: 0.5rem; - color: white; + color: var(--foreground); font-size: 0.875rem; cursor: pointer; @@ -459,7 +459,7 @@ const FileInput = styled.input` background-color: rgba(156, 163, 255, 0.2); border: 1px solid rgba(156, 163, 255, 0.4); border-radius: 0.375rem; - color: white; + color: var(--foreground); cursor: pointer; font-size: 0.8125rem; transition: all 0.2s ease; @@ -481,7 +481,7 @@ const HandleRow = styled.div` ` const HandlePrefix = styled.span` - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); font-size: 1rem; font-weight: 600; flex-shrink: 0; @@ -501,7 +501,7 @@ const PhotoStatus = styled.p` const OrDivider = styled.div` text-align: center; - color: rgba(255, 255, 255, 0.4); + color: rgba(var(--foreground-rgb), 0.4); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; @@ -522,12 +522,12 @@ const DownloadRow = styled.div` const SpecNote = styled.p` margin: -1rem 0 0 0; text-align: center; - color: rgba(255, 255, 255, 0.4); + color: rgba(var(--foreground-rgb), 0.4); font-size: 0.75rem; ` const LoadingText = styled.div` - color: white; + color: var(--foreground); font-size: 1.25rem; text-align: center; margin-top: 4rem; diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 970b355..232d1ab 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -89,12 +89,12 @@ const StyledButton = styled.button<{ line-height: 1.5; background-color: ${(props) => props.$variant === "primary" - ? "white" + ? "var(--foreground)" : props.$variant === "tertiary" ? "transparent" : "transparent"}; - color: ${(props) => (props.$variant === "primary" ? "black" : "white")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid white" : "none")}; + color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; + border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -111,7 +111,7 @@ const StyledButton = styled.button<{ background: linear-gradient( 90deg, transparent, - rgba(255, 255, 255, 0.1), + rgba(var(--foreground-rgb), 0.1), transparent ); transition: left 0.5s ease; @@ -120,9 +120,9 @@ const StyledButton = styled.button<{ &:hover:not(:disabled) { background-color: ${(props) => { - if (props.$variant === "primary") return "#ddd" - if (props.$variant === "tertiary") return "rgba(255, 255, 255, 0.05)" - return "rgba(255, 255, 255, 0.1)" + if (props.$variant === "primary") return "rgba(var(--foreground-rgb), 0.82)" + if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" + return "rgba(var(--foreground-rgb), 0.1)" }}; border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; @@ -160,12 +160,12 @@ const StyledLink = styled(Link)<{ line-height: 1.5; background-color: ${(props) => props.$variant === "primary" - ? "white" + ? "var(--foreground)" : props.$variant === "tertiary" ? "transparent" : "transparent"}; - color: ${(props) => (props.$variant === "primary" ? "black" : "white")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid white" : "none")}; + color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; + border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -182,7 +182,7 @@ const StyledLink = styled(Link)<{ background: linear-gradient( 90deg, transparent, - rgba(255, 255, 255, 0.1), + rgba(var(--foreground-rgb), 0.1), transparent ); transition: left 0.5s ease; @@ -191,9 +191,9 @@ const StyledLink = styled(Link)<{ &:hover { background-color: ${(props) => { - if (props.$variant === "primary") return "#ddd" - if (props.$variant === "tertiary") return "rgba(255, 255, 255, 0.05)" - return "rgba(255, 255, 255, 0.1)" + if (props.$variant === "primary") return "rgba(var(--foreground-rgb), 0.82)" + if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" + return "rgba(var(--foreground-rgb), 0.1)" }}; border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; @@ -226,12 +226,12 @@ const StyledExternalLink = styled.a<{ line-height: 1.5; background-color: ${(props) => props.$variant === "primary" - ? "white" + ? "var(--foreground)" : props.$variant === "tertiary" ? "transparent" : "transparent"}; - color: ${(props) => (props.$variant === "primary" ? "black" : "white")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid white" : "none")}; + color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; + border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -248,7 +248,7 @@ const StyledExternalLink = styled.a<{ background: linear-gradient( 90deg, transparent, - rgba(255, 255, 255, 0.1), + rgba(var(--foreground-rgb), 0.1), transparent ); transition: left 0.5s ease; @@ -257,9 +257,9 @@ const StyledExternalLink = styled.a<{ &:hover { background-color: ${(props) => { - if (props.$variant === "primary") return "#ddd" - if (props.$variant === "tertiary") return "rgba(255, 255, 255, 0.05)" - return "rgba(255, 255, 255, 0.1)" + if (props.$variant === "primary") return "rgba(var(--foreground-rgb), 0.82)" + if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" + return "rgba(var(--foreground-rgb), 0.1)" }}; border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; diff --git a/app/components/Card.tsx b/app/components/Card.tsx index 7b09795..e7828f2 100644 --- a/app/components/Card.tsx +++ b/app/components/Card.tsx @@ -78,13 +78,13 @@ export const CardContent = styled.div<{ $padding?: string }>` export const CardTitle = styled.h3<{ $size?: string }>` font-size: ${(props) => props.$size || "1.25rem"}; font-weight: bold; - color: white; + color: var(--foreground); margin-bottom: 0.5rem; ` export const CardText = styled.p<{ $color?: string; $size?: string; $weight?: string }>` font-size: ${(props) => props.$size || "0.875rem"}; - color: ${(props) => props.$color || "#9ca3af"}; + color: ${(props) => props.$color || "var(--subtle-foreground)"}; margin-bottom: 0.5rem; font-weight: ${(props) => props.$weight || "normal"}; ` @@ -94,7 +94,7 @@ export const CardText = styled.p<{ $color?: string; $size?: string; $weight?: st const StyledLink = styled(Link)` display: flex; flex-direction: column; - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); backdrop-filter: blur(10px); border-radius: 0.5rem; overflow: hidden; @@ -111,7 +111,7 @@ const StyledLink = styled(Link)` const StyledExternalLink = styled.a` display: flex; flex-direction: column; - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); backdrop-filter: blur(10px); border-radius: 0.5rem; overflow: hidden; @@ -128,7 +128,7 @@ const StyledExternalLink = styled.a` const StyledDiv = styled.div` display: flex; flex-direction: column; - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); backdrop-filter: blur(10px); border-radius: 0.5rem; overflow: hidden; @@ -169,8 +169,8 @@ const PlayButton = styled.div` top: 50%; left: 50%; transform: translate(-50%, -50%); - background-color: rgba(255, 255, 255, 0.5); - color: black; + background-color: rgba(var(--foreground-rgb), 0.5); + color: var(--background); border-radius: 50%; width: 60px; height: 60px; @@ -185,7 +185,7 @@ const PlayButton = styled.div` ${StyledLink}:hover &, ${StyledDiv}:hover &, ${StyledExternalLink}:hover & { - background-color: rgba(255, 255, 255, 0.8); + background-color: rgba(var(--foreground-rgb), 0.8); transform: translate(-50%, -50%) scale(1.1); } ` diff --git a/app/components/CheckboxInput.tsx b/app/components/CheckboxInput.tsx index e374157..2e520b3 100644 --- a/app/components/CheckboxInput.tsx +++ b/app/components/CheckboxInput.tsx @@ -34,7 +34,7 @@ const StyledCheckbox = styled.input.attrs({ type: "checkbox" })<{ height: ${(props) => (props.$size === "small" ? "1rem" : "1.25rem")}; border: 2px solid ${(props) => - props.$variant === "secondary" ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)"}; + props.$variant === "secondary" ? "rgba(var(--foreground-rgb), 0.3)" : "rgba(0, 0, 0, 0.3)"}; border-radius: 0.25rem; background-color: transparent; cursor: pointer; @@ -45,7 +45,7 @@ const StyledCheckbox = styled.input.attrs({ type: "checkbox" })<{ &:hover { border-color: ${(props) => - props.$variant === "secondary" ? "rgba(255, 255, 255, 0.5)" : "rgba(0, 0, 0, 0.5)"}; + props.$variant === "secondary" ? "rgba(var(--foreground-rgb), 0.5)" : "rgba(0, 0, 0, 0.5)"}; } &:checked { diff --git a/app/components/ErrorBoundary.tsx b/app/components/ErrorBoundary.tsx index 39f50d9..89e1102 100644 --- a/app/components/ErrorBoundary.tsx +++ b/app/components/ErrorBoundary.tsx @@ -33,7 +33,7 @@ export class ErrorBoundary extends Component +
) ) } diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx index d4da903..d2f31ac 100644 --- a/app/components/Footer.tsx +++ b/app/components/Footer.tsx @@ -90,7 +90,7 @@ const FooterContainer = styled.footer` align-items: center; justify-content: center; width: 100%; - background-color: rgba(0, 0, 0, 0.1); + background-color: var(--footer-background); backdrop-filter: blur(64px); margin-top: auto; ` @@ -101,7 +101,7 @@ const FooterContent = styled.div` align-items: center; justify-content: space-between; padding: 1.5rem 1rem; - color: #a3a3a3; + color: var(--subtle-foreground); max-width: 1200px; width: 100%; gap: 1rem; diff --git a/app/components/Header.tsx b/app/components/Header.tsx index 067a76b..e260a56 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -304,7 +304,7 @@ const Container = styled.header` width: 100%; position: sticky; top: 0; - background-color: rgba(0, 0, 0, 0.05); + background-color: var(--header-background); backdrop-filter: blur(38px); border-bottom: 1px solid rgba(0, 0, 0, 0.1); z-index: 100; @@ -339,7 +339,7 @@ const MenuButton = styled.button` border: none; cursor: pointer; padding: 0.5rem; - color: white; + color: var(--foreground); &:hover { opacity: 0.8; @@ -395,7 +395,7 @@ const ProfileImage = styled.img` height: 100%; object-fit: cover; border-radius: 50%; - border: 2px solid rgba(255, 255, 255, 0.2); + border: 2px solid rgba(var(--foreground-rgb), 0.2); ` const ProfilePlaceholder = styled.div` @@ -404,10 +404,10 @@ const ProfilePlaceholder = styled.div` display: flex; align-items: center; justify-content: center; - background-color: rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.1); border-radius: 50%; - border: 2px solid rgba(255, 255, 255, 0.2); - color: white; + border: 2px solid rgba(var(--foreground-rgb), 0.2); + color: var(--foreground); font-size: 1rem; font-weight: 600; ` @@ -425,21 +425,21 @@ const AccountMenuItem = styled.li` const AccountMenuLink = styled.a` display: block; padding: 0.75rem 1rem; - color: white; + color: var(--foreground); text-decoration: none; font-size: 1.1rem; border-radius: 0.375rem; transition: background-color 0.2s ease; &:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.1); } ` const AccountMenuButton = styled.button` display: block; padding: 0.75rem 1rem; - color: white; + color: var(--foreground); text-decoration: none; font-size: 1.1rem; border-radius: 0.375rem; @@ -451,13 +451,13 @@ const AccountMenuButton = styled.button` cursor: pointer; &:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.1); } ` const AccountMenuDivider = styled.hr` border: none; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--border); margin: 0.5rem 0; ` @@ -478,9 +478,9 @@ const LeftSidebar = styled.div<{ $isOpen: boolean }>` left: 0; width: 280px; height: 100%; - background-color: rgba(0, 0, 0, 0.05); + background-color: var(--sidebar-background); backdrop-filter: blur(38px); - border-right: 1px solid rgba(255, 255, 255, 0.1); + border-right: 1px solid var(--border); z-index: 201; transform: translateX(${(props) => (props.$isOpen ? "0" : "-100%")}); transition: transform 0.3s ease-in-out; @@ -497,9 +497,9 @@ const RightSidebar = styled.div<{ $isOpen: boolean }>` right: 0; width: 280px; height: 100%; - background-color: rgba(0, 0, 0, 0.05); + background-color: var(--sidebar-background); backdrop-filter: blur(38px); - border-left: 1px solid rgba(255, 255, 255, 0.1); + border-left: 1px solid var(--border); z-index: 201; transform: translateX(${(props) => (props.$isOpen ? "0" : "100%")}); transition: transform 0.3s ease-in-out; @@ -530,13 +530,13 @@ const SidebarProfileImage = styled.img` height: 2.5rem; object-fit: cover; border-radius: 50%; - border: 2px solid rgba(255, 255, 255, 0.2); + border: 2px solid rgba(var(--foreground-rgb), 0.2); display: block; flex-shrink: 0; ` const ProfileHandle = styled.span` - color: white; + color: var(--foreground); font-size: 1rem; font-weight: 500; ` @@ -549,7 +549,7 @@ const CloseButton = styled.button` border: none; cursor: pointer; padding: 0.5rem; - color: white; + color: var(--foreground); &:hover { opacity: 0.8; @@ -591,14 +591,14 @@ const MenuItem = styled.li` const MenuLink = styled.a` display: block; padding: 0.75rem 1rem; - color: white; + color: var(--foreground); text-decoration: none; font-size: 1.1rem; border-radius: 0.375rem; transition: background-color 0.2s ease; &:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.1); } @media (min-width: 768px) { diff --git a/app/components/HelpInfoButton.tsx b/app/components/HelpInfoButton.tsx index 22d6b7a..7678026 100644 --- a/app/components/HelpInfoButton.tsx +++ b/app/components/HelpInfoButton.tsx @@ -50,12 +50,12 @@ const HelpIconWrapper = styled.div` display: inline-flex; align-items: center; justify-content: center; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); transition: color 0.2s ease; flex-shrink: 0; &:hover { - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); } ` @@ -64,7 +64,7 @@ const Tooltip = styled.div<{ $minWidth?: string; $maxWidth?: string }>` bottom: calc(100% + 8px); right: 0; background: rgba(0, 0, 0, 0.95); - color: rgba(255, 255, 255, 0.95); + color: rgba(var(--foreground-rgb), 0.95); padding: 0.75rem 1rem; border-radius: 8px; font-size: 0.875rem; @@ -76,7 +76,7 @@ const Tooltip = styled.div<{ $minWidth?: string; $maxWidth?: string }>` z-index: 1000; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), - 0 0 0 1px rgba(255, 255, 255, 0.1); + 0 0 0 1px rgba(var(--foreground-rgb), 0.1); pointer-events: auto; &::after { diff --git a/app/components/LinkCloudSection.tsx b/app/components/LinkCloudSection.tsx index f47e7df..d6ab046 100644 --- a/app/components/LinkCloudSection.tsx +++ b/app/components/LinkCloudSection.tsx @@ -88,12 +88,12 @@ const SectionHeader = styled.div` const SectionTitle = styled.h3` font-size: 1.25rem; font-weight: 600; - color: white; + color: var(--foreground); margin: 0; ` const SavingIndicator = styled.span` font-size: 0.875rem; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); font-style: italic; ` diff --git a/app/components/LinkInput.tsx b/app/components/LinkInput.tsx index 505542d..3aeacd0 100644 --- a/app/components/LinkInput.tsx +++ b/app/components/LinkInput.tsx @@ -265,18 +265,18 @@ const LinkPill = styled.div<{ $isDragging?: boolean; $dragOver?: boolean }>` align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; - background-color: rgba(255, 255, 255, 0.2); - border: 1px solid rgba(255, 255, 255, 0.3); + background-color: rgba(var(--foreground-rgb), 0.2); + border: 1px solid rgba(var(--foreground-rgb), 0.3); border-radius: 9999px; font-size: 0.875rem; - color: white; + color: var(--foreground); font-weight: 500; transition: all 0.2s ease; cursor: ${(props) => (props.draggable ? "grab" : "pointer")}; opacity: ${(props) => (props.$isDragging ? 0.5 : 1)}; transform: ${(props) => (props.$isDragging ? "scale(0.95)" : "scale(1)")}; border-color: ${(props) => - props.$dragOver ? "rgba(255, 255, 255, 0.6)" : "rgba(255, 255, 255, 0.3)"}; + props.$dragOver ? "rgba(var(--foreground-rgb), 0.6)" : "rgba(var(--foreground-rgb), 0.3)"}; &:hover { background-color: rgba(255, 255, 255, 0.25); @@ -290,7 +290,7 @@ const LinkPill = styled.div<{ $isDragging?: boolean; $dragOver?: boolean }>` const RemoveButton = styled.button` background: none; border: none; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); cursor: pointer; font-size: 1.2rem; line-height: 1; @@ -305,8 +305,8 @@ const RemoveButton = styled.button` transition: all 0.2s ease; &:hover { - color: white; - background-color: rgba(255, 255, 255, 0.2); + color: var(--foreground); + background-color: rgba(var(--foreground-rgb), 0.2); } ` @@ -315,19 +315,19 @@ const AddPill = styled.button` align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; - background-color: rgba(255, 255, 255, 0.1); - border: 1px dashed rgba(255, 255, 255, 0.3); + background-color: rgba(var(--foreground-rgb), 0.1); + border: 1px dashed rgba(var(--foreground-rgb), 0.3); border-radius: 9999px; font-size: 0.875rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-weight: 500; cursor: pointer; transition: all 0.2s ease; &:hover { - background-color: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.5); - color: white; + background-color: rgba(var(--foreground-rgb), 0.15); + border-color: rgba(var(--foreground-rgb), 0.5); + color: var(--foreground); } ` @@ -342,8 +342,8 @@ const InputPill = styled.div` align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; - background-color: rgba(255, 255, 255, 0.15); - border: 1px solid rgba(255, 255, 255, 0.3); + background-color: rgba(var(--foreground-rgb), 0.15); + border: 1px solid rgba(var(--foreground-rgb), 0.3); border-radius: 9999px; min-width: 120px; position: relative; @@ -353,7 +353,7 @@ const Input = styled.input` background: transparent; border: none; outline: none; - color: white; + color: var(--foreground); font-size: 0.875rem; font-weight: 500; font-family: inherit; @@ -362,7 +362,7 @@ const Input = styled.input` padding: 0; &::placeholder { - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); } &:disabled { diff --git a/app/components/Modal.tsx b/app/components/Modal.tsx index e9ee1c8..baf1c45 100644 --- a/app/components/Modal.tsx +++ b/app/components/Modal.tsx @@ -66,8 +66,8 @@ const Backdrop = styled.div` ` const ModalContent = styled.div` - background-color: rgba(20, 20, 20, 0.95); - border: 1px solid rgba(255, 255, 255, 0.2); + background-color: var(--surface-solid); + border: 1px solid var(--border); border-radius: 0.5rem; padding: 2rem; max-width: 500px; @@ -82,7 +82,7 @@ const CloseButton = styled.button` right: 1rem; background: transparent; border: none; - color: white; + color: var(--foreground); font-size: 1.5rem; cursor: pointer; padding: 0.25rem; diff --git a/app/components/PageContainer.tsx b/app/components/PageContainer.tsx index 46b309b..4a33503 100644 --- a/app/components/PageContainer.tsx +++ b/app/components/PageContainer.tsx @@ -28,7 +28,7 @@ export const PageContainer = ({ const StyledContainer = styled.div<{ $alignItems: "center" | "stretch" | "flex-start" | "flex-end" }>` - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); backdrop-filter: blur(10px); padding: 3rem; border-radius: 1rem; diff --git a/app/components/PotionBackground.tsx b/app/components/PotionBackground.tsx index 4f22a45..42c1e09 100644 --- a/app/components/PotionBackground.tsx +++ b/app/components/PotionBackground.tsx @@ -287,7 +287,7 @@ export const PotionBackground = () => { } const BackgroundContainer = styled.div` - background-color: black; + background-color: var(--background); width: 100%; height: 100%; overflow: hidden; @@ -305,8 +305,13 @@ const Canvas = styled.canvas<{ }>` display: block; position: absolute; - width: ${(props) => props.$width}px - height: ${(props) => props.$height}px - top: ${(props) => props.$top}px - left: ${(props) => props.$left}px + width: ${(props) => props.$width}px; + height: ${(props) => props.$height}px; + top: ${(props) => props.$top}px; + left: ${(props) => props.$left}px; + filter: invert(1); + + @media (prefers-color-scheme: dark) { + filter: none; + } ` diff --git a/app/components/RadioInput.tsx b/app/components/RadioInput.tsx index 10c9283..505e71d 100644 --- a/app/components/RadioInput.tsx +++ b/app/components/RadioInput.tsx @@ -34,7 +34,7 @@ const StyledRadio = styled.input.attrs({ type: "radio" })<{ height: ${(props) => (props.$size === "small" ? "1rem" : "1.25rem")}; border: 2px solid ${(props) => - props.$variant === "secondary" ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)"}; + props.$variant === "secondary" ? "rgba(var(--foreground-rgb), 0.3)" : "rgba(0, 0, 0, 0.3)"}; border-radius: 50%; background-color: transparent; cursor: pointer; @@ -45,7 +45,7 @@ const StyledRadio = styled.input.attrs({ type: "radio" })<{ &:hover { border-color: ${(props) => - props.$variant === "secondary" ? "rgba(255, 255, 255, 0.5)" : "rgba(0, 0, 0, 0.5)"}; + props.$variant === "secondary" ? "rgba(var(--foreground-rgb), 0.5)" : "rgba(0, 0, 0, 0.5)"}; } &:checked { @@ -64,7 +64,7 @@ const StyledRadio = styled.input.attrs({ type: "radio" })<{ width: ${(props) => (props.$size === "small" ? "0.375rem" : "0.5rem")}; height: ${(props) => (props.$size === "small" ? "0.375rem" : "0.5rem")}; border-radius: 50%; - background-color: white; + background-color: var(--foreground); } &:focus { diff --git a/app/components/TagCloudSection.tsx b/app/components/TagCloudSection.tsx index 564c96b..5292aba 100644 --- a/app/components/TagCloudSection.tsx +++ b/app/components/TagCloudSection.tsx @@ -97,12 +97,12 @@ const SectionHeader = styled.div` const SectionTitle = styled.h3` font-size: 1.25rem; font-weight: 600; - color: white; + color: var(--foreground); margin: 0; ` const SavingIndicator = styled.span` font-size: 0.875rem; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); font-style: italic; ` diff --git a/app/components/TagInput.tsx b/app/components/TagInput.tsx index bf96de7..1f99fb6 100644 --- a/app/components/TagInput.tsx +++ b/app/components/TagInput.tsx @@ -385,12 +385,12 @@ const TagPill = styled.div<{ $approved: boolean; $isDragging?: boolean; $dragOve gap: 0.375rem; padding: 0.375rem 0.75rem; background-color: ${(props) => - props.$approved ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 243, 205, 0.3)"}; + props.$approved ? "rgba(var(--foreground-rgb), 0.2)" : "rgba(255, 243, 205, 0.3)"}; border: 1px solid - ${(props) => (props.$approved ? "rgba(255, 255, 255, 0.3)" : "rgba(255, 193, 7, 0.5)")}; + ${(props) => (props.$approved ? "rgba(var(--foreground-rgb), 0.3)" : "rgba(255, 193, 7, 0.5)")}; border-radius: 9999px; font-size: 0.875rem; - color: white; + color: var(--foreground); font-weight: 500; transition: all 0.2s ease; cursor: ${(props) => (props.draggable ? "grab" : "default")}; @@ -399,10 +399,10 @@ const TagPill = styled.div<{ $approved: boolean; $isDragging?: boolean; $dragOve border-color: ${(props) => props.$dragOver ? props.$approved - ? "rgba(255, 255, 255, 0.6)" + ? "rgba(var(--foreground-rgb), 0.6)" : "rgba(255, 193, 7, 0.8)" : props.$approved - ? "rgba(255, 255, 255, 0.3)" + ? "rgba(var(--foreground-rgb), 0.3)" : "rgba(255, 193, 7, 0.5)"}; &:hover { @@ -418,7 +418,7 @@ const TagPill = styled.div<{ $approved: boolean; $isDragging?: boolean; $dragOve const RemoveButton = styled.button` background: none; border: none; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); cursor: pointer; font-size: 1.2rem; line-height: 1; @@ -433,8 +433,8 @@ const RemoveButton = styled.button` transition: all 0.2s ease; &:hover { - color: white; - background-color: rgba(255, 255, 255, 0.2); + color: var(--foreground); + background-color: rgba(var(--foreground-rgb), 0.2); } ` @@ -443,19 +443,19 @@ const AddPill = styled.button` align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; - background-color: rgba(255, 255, 255, 0.1); - border: 1px dashed rgba(255, 255, 255, 0.3); + background-color: rgba(var(--foreground-rgb), 0.1); + border: 1px dashed rgba(var(--foreground-rgb), 0.3); border-radius: 9999px; font-size: 0.875rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-weight: 500; cursor: pointer; transition: all 0.2s ease; &:hover { - background-color: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.5); - color: white; + background-color: rgba(var(--foreground-rgb), 0.15); + border-color: rgba(var(--foreground-rgb), 0.5); + color: var(--foreground); } ` @@ -470,8 +470,8 @@ const InputPill = styled.div` align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; - background-color: rgba(255, 255, 255, 0.15); - border: 1px solid rgba(255, 255, 255, 0.3); + background-color: rgba(var(--foreground-rgb), 0.15); + border: 1px solid rgba(var(--foreground-rgb), 0.3); border-radius: 9999px; min-width: 120px; position: relative; @@ -481,7 +481,7 @@ const Input = styled.input` background: transparent; border: none; outline: none; - color: white; + color: var(--foreground); font-size: 0.875rem; font-weight: 500; font-family: inherit; @@ -490,7 +490,7 @@ const Input = styled.input` padding: 0; &::placeholder { - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); } &:disabled { @@ -502,7 +502,7 @@ const Input = styled.input` const SearchIndicator = styled.div` position: absolute; right: 0.75rem; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); font-size: 0.875rem; ` @@ -513,7 +513,7 @@ const SuggestionsList = styled.div` right: 0; background-color: rgba(0, 0, 0, 0.9); backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); + border: 1px solid rgba(var(--foreground-rgb), 0.2); border-radius: 0.5rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); max-height: 200px; @@ -525,12 +525,13 @@ const SuggestionItem = styled.div<{ $highlighted: boolean }>` padding: 0.625rem 1rem; cursor: pointer; font-size: 0.875rem; - color: white; - background-color: ${(props) => (props.$highlighted ? "rgba(255, 255, 255, 0.1)" : "transparent")}; + color: var(--foreground); + background-color: ${(props) => + props.$highlighted ? "rgba(var(--foreground-rgb), 0.1)" : "transparent"}; transition: background-color 0.15s ease; &:hover { - background-color: rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.1); } &:first-child { @@ -545,7 +546,7 @@ const SuggestionItem = styled.div<{ $highlighted: boolean }>` ` const CreateItem = styled(SuggestionItem)` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-style: italic; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--border); ` diff --git a/app/components/TextInput.tsx b/app/components/TextInput.tsx index 0af4b1e..5055917 100644 --- a/app/components/TextInput.tsx +++ b/app/components/TextInput.tsx @@ -39,14 +39,14 @@ const StyledInput = styled.input<{ width: 100%; box-sizing: border-box; background-color: ${(props) => (props.$variant === "primary" ? "white" : "transparent")}; - color: ${(props) => (props.$variant === "primary" ? "black" : "white")}; + color: ${(props) => (props.$variant === "primary" ? "black" : "var(--foreground)")}; border: ${(props) => { if (props.$error) { return "1px solid var(--error-color)" } if (props.$variant === "secondary") { - return "1px solid rgba(255, 255, 255, 0.3)" + return "1px solid rgba(var(--foreground-rgb), 0.3)" } return "1px solid rgba(0, 0, 0, 0.2)" @@ -60,18 +60,18 @@ const StyledInput = styled.input<{ } if (props.$variant === "secondary") { - return "white" + return "var(--foreground)" } return "rgba(0, 0, 0, 0.4)" }}; background-color: ${(props) => - props.$variant === "primary" ? "white" : "rgba(255, 255, 255, 0.05)"}; + props.$variant === "primary" ? "white" : "rgba(var(--foreground-rgb), 0.05)"}; } &::placeholder { color: ${(props) => - props.$variant === "primary" ? "rgba(0, 0, 0, 0.5)" : "rgba(255, 255, 255, 0.5)"}; + props.$variant === "primary" ? "rgba(0, 0, 0, 0.5)" : "rgba(var(--foreground-rgb), 0.5)"}; } &:disabled { diff --git a/app/components/TextareaInput.tsx b/app/components/TextareaInput.tsx index 319b3f6..8e1f8b9 100644 --- a/app/components/TextareaInput.tsx +++ b/app/components/TextareaInput.tsx @@ -38,22 +38,23 @@ const StyledTextarea = styled.textarea<{ box-sizing: border-box; resize: vertical; background-color: ${(props) => (props.$variant === "primary" ? "white" : "transparent")}; - color: ${(props) => (props.$variant === "primary" ? "black" : "white")}; + color: ${(props) => (props.$variant === "primary" ? "black" : "var(--foreground)")}; border: ${(props) => props.$variant === "secondary" - ? "1px solid rgba(255, 255, 255, 0.3)" + ? "1px solid rgba(var(--foreground-rgb), 0.3)" : "1px solid rgba(0, 0, 0, 0.2)"}; &:focus { outline: none; - border-color: ${(props) => (props.$variant === "secondary" ? "white" : "rgba(0, 0, 0, 0.4)")}; + border-color: ${(props) => + props.$variant === "secondary" ? "var(--foreground)" : "rgba(0, 0, 0, 0.4)"}; background-color: ${(props) => - props.$variant === "primary" ? "white" : "rgba(255, 255, 255, 0.05)"}; + props.$variant === "primary" ? "white" : "rgba(var(--foreground-rgb), 0.05)"}; } &::placeholder { color: ${(props) => - props.$variant === "primary" ? "rgba(0, 0, 0, 0.5)" : "rgba(255, 255, 255, 0.5)"}; + props.$variant === "primary" ? "rgba(0, 0, 0, 0.5)" : "rgba(var(--foreground-rgb), 0.5)"}; } &:disabled { diff --git a/app/components/icons/index.tsx b/app/components/icons/index.tsx index 688200f..95962fc 100644 --- a/app/components/icons/index.tsx +++ b/app/components/icons/index.tsx @@ -35,7 +35,11 @@ export const CameraIcon = ({ color = "#888" }: { color?: string }) => ( ) -export const QuestionIcon = ({ color = "rgba(255, 255, 255, 0.6)" }: { color?: string }) => ( +export const QuestionIcon = ({ + color = "rgba(var(--foreground-rgb), 0.6)" +}: { + color?: string +}) => ( } + fallback={ +
+ } > @@ -182,7 +184,7 @@ export default function Doorbell() { // Styled Components // const Main = styled.main` - color: white; + color: var(--foreground); display: flex; flex-direction: column; align-items: center; @@ -190,7 +192,7 @@ const Main = styled.main` ` const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -249,7 +251,7 @@ const TermsMessage = styled.p` text-align: center; max-width: 420px; margin: 0; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); ` const ButtonSection = styled.section` @@ -275,7 +277,7 @@ const DoorbellMessage = styled.p` text-align: center; max-width: 420px; margin: 0; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); ` const AnimatedButtonContent = styled(motion.span)` @@ -297,11 +299,11 @@ const CallMessage = styled.p` font-size: 1.25rem; text-align: center; margin: 0; - color: white; + color: var(--foreground); ` const TermsLink = styled(Link)` - color: white; + color: var(--foreground); text-decoration: underline; transition: opacity 0.2s ease; diff --git a/app/event-terms/page.tsx b/app/event-terms/page.tsx index 896d087..3ec94d7 100644 --- a/app/event-terms/page.tsx +++ b/app/event-terms/page.tsx @@ -8,7 +8,9 @@ export default function EventTerms() { <> } + fallback={ +
+ } > @@ -153,7 +155,7 @@ export default function EventTerms() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -168,7 +170,7 @@ const BackgroundContainer = styled.section` const Main = styled.main` position: relative; z-index: 1; - color: white; + color: var(--foreground); ` const TermsSection = styled.section` @@ -190,7 +192,7 @@ const Title = styled.h1` font-weight: 700; margin-bottom: 1.5rem; text-align: center; - color: white; + color: var(--foreground); ` const IntroText = styled.p` @@ -198,7 +200,7 @@ const IntroText = styled.p` line-height: 1.7; text-align: center; margin-bottom: 3rem; - color: rgba(255, 255, 255, 0.85); + color: rgba(var(--foreground-rgb), 0.85); @media (max-width: 768px) { font-size: 1rem; @@ -214,7 +216,7 @@ const SectionTitle = styled.h2` font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; - color: white; + color: var(--foreground); @media (max-width: 768px) { font-size: 1.375rem; @@ -225,7 +227,7 @@ const Paragraph = styled.p` font-size: 1.0625rem; line-height: 1.8; margin-bottom: 1rem; - color: rgba(255, 255, 255, 0.8); + color: rgba(var(--foreground-rgb), 0.8); &:last-child { margin-bottom: 0; @@ -239,7 +241,7 @@ const Paragraph = styled.p` const List = styled.ul` margin: 1rem 0 0 1.5rem; - color: rgba(255, 255, 255, 0.8); + color: rgba(var(--foreground-rgb), 0.8); ` const ListItem = styled.li` diff --git a/app/events/[eventId]/EventDetailClient.tsx b/app/events/[eventId]/EventDetailClient.tsx index 1bd7752..d9c286f 100644 --- a/app/events/[eventId]/EventDetailClient.tsx +++ b/app/events/[eventId]/EventDetailClient.tsx @@ -134,7 +134,11 @@ export default function EventDetailClient() { <> } + fallback={ +
+ } > @@ -159,7 +163,9 @@ export default function EventDetailClient() { <> } + fallback={ +
+ } > @@ -350,7 +356,7 @@ function formatEventDateTime(startAt: string, endAt: string): string { // Styled Components // const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -377,7 +383,7 @@ const Container = styled.div` @media (min-width: 1132px) { margin-inline: auto; } - background-color: rgba(21, 21, 28, 0.75); + background-color: var(--surface); backdrop-filter: blur(10px); border-radius: 0.5rem; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); @@ -444,22 +450,22 @@ const Header = styled.header` const Title = styled.h1` font-size: 2.25rem; font-weight: bold; - color: white; + color: var(--foreground); margin-bottom: 0.5rem; ` const DateTime = styled.p` font-size: 1.125rem; - color: #9ca3af; + color: var(--subtle-foreground); margin-bottom: 1rem; ` const SectionTitle = styled.h2` font-size: 1.5rem; font-weight: bold; - color: white; + color: var(--foreground); margin-bottom: 1rem; - border-bottom: 1px solid #374151; + border-bottom: 1px solid var(--border); padding-bottom: 0.75rem; ` @@ -469,7 +475,7 @@ const LocationSection = styled.section` const LocationText = styled.p` font-size: 1rem; - color: #d1d5db; + color: var(--muted-foreground); margin-bottom: 1rem; ` @@ -496,7 +502,7 @@ const DescriptionSection = styled.section` const Description = styled.div` font-size: 1rem; - color: #d1d5db; + color: var(--muted-foreground); line-height: 1.5; word-break: break-word; @@ -601,7 +607,7 @@ const AttendeeLink = styled.a` ` const RegistrationSection = styled.section` - background-color: rgba(255, 255, 255, 0.01); + background-color: rgba(var(--foreground-rgb), 0.01); backdrop-filter: blur(32px); box-shadow: 4px 8px 8px 0 rgba(0, 0, 0, 0.05); padding: 1.5rem; @@ -633,18 +639,18 @@ const OneClickRSVPContainer = styled.div` const StoredInfoDisplay = styled.div` font-size: 0.875rem; - color: #d1d5db; + color: var(--muted-foreground); text-align: center; line-height: 1.6; ` const NameValue = styled.span` - color: white; + color: var(--foreground); font-weight: 900; ` const EmailValue = styled.span` - color: #aaa; + color: var(--subtle-foreground); ` const ClearUserInfoLink = styled.a` @@ -662,7 +668,7 @@ const ClearUserInfoLink = styled.a` const LoadingMessage = styled.p` text-align: center; - color: #9ca3af; + color: var(--subtle-foreground); font-size: 1.125rem; padding: 4rem 2rem; ` diff --git a/app/events/page.tsx b/app/events/page.tsx index 1c3c796..436b8ba 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -51,7 +51,9 @@ export default function Events() { <> } + fallback={ +
+ } > @@ -97,7 +99,7 @@ export default function Events() { {event.name} {formatEventDate(event.start_at)} {event.location && ( - + {event.location.type === "physical" ? `${event.location.city}, ${event.location.state}` : "Online Event"} @@ -140,7 +142,7 @@ function formatEventDate(dateString: string): string { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -176,7 +178,7 @@ const Title = styled.h2` font-weight: bold; margin-bottom: 1rem; text-align: center; - color: white; + color: var(--foreground); ` const EventDescription = styled.p` @@ -187,7 +189,7 @@ const EventDescription = styled.p` margin-left: auto; margin-right: auto; margin-bottom: 2rem; - color: #d1d5db; + color: var(--muted-foreground); ` const FilterToggle = styled.div` @@ -214,14 +216,14 @@ const EventsGrid = styled.div` const LoadingMessage = styled.p` text-align: center; - color: #9ca3af; + color: var(--subtle-foreground); font-size: 1.125rem; padding: 2rem; ` const NoEventsMessage = styled.p` text-align: center; - color: #9ca3af; + color: var(--subtle-foreground); font-size: 1.125rem; padding: 2rem; ` diff --git a/app/globals.css b/app/globals.css index 1ed1702..9c8d981 100644 --- a/app/globals.css +++ b/app/globals.css @@ -3,14 +3,42 @@ @tailwind utilities; :root { - --error-color: #f87171; - --b1: #000000; - --n: 21% 0.003 296.813; + color-scheme: light; + --background: #f7f7fa; + --background-rgb: 247, 247, 250; + --foreground: #17171c; + --foreground-rgb: 23, 23, 28; + --muted-foreground: #555b66; + --subtle-foreground: #6b7280; + --surface: rgba(255, 255, 255, 0.78); + --surface-solid: #ffffff; + --header-background: rgba(247, 247, 250, 0.82); + --sidebar-background: rgba(247, 247, 250, 0.94); + --footer-background: rgba(247, 247, 250, 0.88); + --border: rgba(23, 23, 28, 0.12); + --error-color: #dc2626; + --b1: #ffffff; + --n: 35% 0.003 296.813; } @media (prefers-color-scheme: dark) { - html { + :root { color-scheme: dark; + --background: #0a0a0a; + --background-rgb: 10, 10, 10; + --foreground: #ffffff; + --foreground-rgb: 255, 255, 255; + --muted-foreground: #d1d5db; + --subtle-foreground: #9ca3af; + --surface: rgba(21, 21, 28, 0.75); + --surface-solid: #15151c; + --header-background: rgba(0, 0, 0, 0.05); + --sidebar-background: rgba(0, 0, 0, 0.05); + --footer-background: rgba(0, 0, 0, 0.1); + --border: rgba(255, 255, 255, 0.1); + --error-color: #f87171; + --b1: #000000; + --n: 21% 0.003 296.813; } } @@ -25,6 +53,8 @@ body { flex-direction: column; margin: 0; padding: 0; + background-color: var(--background); + color: var(--foreground); } #__next { diff --git a/app/login/page.tsx b/app/login/page.tsx index f8bc4a1..22fbd43 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -388,7 +388,7 @@ export default function Login() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -408,12 +408,12 @@ const Container = styled.main` const Title = styled.h1` font-size: 2rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; ` const Subtitle = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); margin: -1rem 0 0 0; text-align: center; ` @@ -469,7 +469,7 @@ const InputGroup = styled.div` ` const PasswordHelpText = styled.p` - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); font-size: 0.75rem; margin: 0; line-height: 1.4; @@ -482,7 +482,7 @@ const SuccessContainer = styled.div` const BackButton = styled.button` background: none; border: none; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); font-size: 0.875rem; cursor: pointer; padding: 0.5rem; @@ -491,14 +491,14 @@ const BackButton = styled.button` font-family: inherit; &:hover { - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); } ` const ForgotPasswordButton = styled.button` background: none; border: none; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); cursor: pointer; padding: 0; margin-top: -0.5rem; @@ -508,7 +508,7 @@ const ForgotPasswordButton = styled.button` text-align: right; &:hover:not(:disabled) { - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); } &:disabled { diff --git a/app/nametags/page.tsx b/app/nametags/page.tsx index 2a0fde9..fedf107 100644 --- a/app/nametags/page.tsx +++ b/app/nametags/page.tsx @@ -45,7 +45,9 @@ export default function NametagPage() { } + fallback={ +
+ } > @@ -92,7 +94,7 @@ export default function NametagPage() { // Styled Components // const Main = styled.main` - color: white; + color: var(--foreground); display: flex; flex-direction: column; align-items: center; @@ -100,7 +102,7 @@ const Main = styled.main` ` const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -196,7 +198,7 @@ const Heading = styled.h1` const Description = styled.p` font-size: clamp(1.25rem, 2vw, 1.75rem); margin: 0; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); line-height: 1.4; ` diff --git a/app/page.tsx b/app/page.tsx index 18b2938..3232383 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -86,7 +86,9 @@ export default function Home() { <> } + fallback={ +
+ } > @@ -395,7 +397,7 @@ export default function Home() { } const Main = styled.main` - color: white; + color: var(--foreground); display: flex; flex-direction: column; align-items: center; @@ -403,7 +405,7 @@ const Main = styled.main` ` const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -441,7 +443,7 @@ const HeroSocialLinks = styled.div` const HeroSocialIcon = styled.a` display: flex; align-items: center; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); transition: all 0.3s ease; svg { @@ -465,6 +467,11 @@ const HeroImage = styled.img` width: 100%; max-width: 688px; margin: 0 auto; + filter: invert(1); + + @media (prefers-color-scheme: dark) { + filter: none; + } ` const Tagline = styled.section` @@ -523,7 +530,7 @@ const ScrollFeatureTagline = styled(motion.p)` font-size: clamp(1.5rem, 3vw, 2.5rem); text-align: center; max-width: 820px; - color: rgba(255, 255, 255, 0.8); + color: rgba(var(--foreground-rgb), 0.8); line-height: 1.4; ` @@ -605,6 +612,7 @@ const SliderOverlay = styled.div` const AboutContentOverlay = styled.div` position: relative; z-index: 2; + color: #ffffff; display: flex; flex-direction: column; align-items: center; @@ -740,7 +748,7 @@ const OrganizerCardWrapper = styled.div` ` const OrganizerCardLink = styled.a` - background-color: rgba(255, 255, 255, 0.02); + background-color: rgba(var(--foreground-rgb), 0.02); padding: 3rem; border-radius: 0.5rem; text-align: center; @@ -755,7 +763,7 @@ const OrganizerCardLink = styled.a` transition: background-color 0.3s ease; &:hover { - background-color: rgba(255, 255, 255, 0.05); + background-color: rgba(var(--foreground-rgb), 0.05); } @media (max-width: 768px) { diff --git a/app/reset-password/page.tsx b/app/reset-password/page.tsx index 92164b6..c394c62 100644 --- a/app/reset-password/page.tsx +++ b/app/reset-password/page.tsx @@ -149,7 +149,7 @@ export default function ResetPasswordPage() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -169,12 +169,12 @@ const Container = styled.main` const Title = styled.h1` font-size: 2rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; ` const Subtitle = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); margin: -1rem 0 0 0; text-align: center; ` diff --git a/app/setup/page.tsx b/app/setup/page.tsx index caab40b..42ae133 100644 --- a/app/setup/page.tsx +++ b/app/setup/page.tsx @@ -375,7 +375,7 @@ export default function Setup() { {handle && ( {checkingHandle ? ( - Checking... + Checking... ) : handleAvailable === true ? ( ✓ Available ) : handleAvailable === false ? ( @@ -460,13 +460,13 @@ const HeaderRow = styled.div` const Title = styled.h1` font-size: 2.5rem; font-weight: 700; - color: rgba(255, 255, 255, 0.95); + color: rgba(var(--foreground-rgb), 0.95); text-align: center; width: 100%; ` const LoadingText = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 1.2rem; ` @@ -487,7 +487,7 @@ const Section = styled.div` const SectionTitle = styled.h2` font-size: 1.5rem; font-weight: 600; - color: rgba(255, 255, 255, 0.95); + color: rgba(var(--foreground-rgb), 0.95); margin: 0; ` @@ -518,7 +518,7 @@ const StatusText = styled.span<{ $color: string }>` ` const HelpText = styled.p` - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); font-size: 0.875rem; margin: 0; ` diff --git a/app/slides/SlidesListClient.tsx b/app/slides/SlidesListClient.tsx index dc9ec69..a699024 100644 --- a/app/slides/SlidesListClient.tsx +++ b/app/slides/SlidesListClient.tsx @@ -39,7 +39,7 @@ export default function SlidesListClient({ slides }: SlidesListClientProps) { // Styled Components // const Main = styled.main` - color: white; + color: var(--foreground); display: flex; flex-direction: column; align-items: center; @@ -80,7 +80,7 @@ const SectionTitle = styled.h1` const EmptyState = styled.p` font-size: 1.125rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); ` const SlidesList = styled.div` @@ -94,7 +94,7 @@ const SlideCard = styled(Link)` flex-direction: column; gap: 0.5rem; padding: 1.5rem; - background: rgba(255, 255, 255, 0.03); + background: rgba(var(--foreground-rgb), 0.03); border-radius: 0.5rem; text-decoration: none; color: inherit; @@ -113,13 +113,13 @@ const SlideTitle = styled.h2` const SlideAuthor = styled.p` font-size: 1rem; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); margin: 0; ` const SlideDescription = styled.p` font-size: 1rem; line-height: 1.6; - color: rgba(255, 255, 255, 0.8); + color: rgba(var(--foreground-rgb), 0.8); margin: 0.5rem 0 0; ` diff --git a/app/slides/[slug]/SlideDetailClient.tsx b/app/slides/[slug]/SlideDetailClient.tsx index cb57a69..82544c4 100644 --- a/app/slides/[slug]/SlideDetailClient.tsx +++ b/app/slides/[slug]/SlideDetailClient.tsx @@ -76,7 +76,7 @@ function ShareIcon() { // Styled Components // const Main = styled.main` - color: white; + color: var(--foreground); display: flex; flex-direction: column; align-items: center; @@ -139,7 +139,7 @@ const MetadataSection = styled.section` max-width: 1200px; width: 100%; padding: 2rem; - background: rgba(255, 255, 255, 0.03); + background: rgba(var(--foreground-rgb), 0.03); border-radius: 0.5rem; backdrop-filter: blur(8px); ` @@ -159,20 +159,20 @@ const MetaInfo = styled.div` const Author = styled.p` font-size: 1.125rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); margin: 0; ` const DateText = styled.p` font-size: 1rem; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); margin: 0; ` const Description = styled.p` font-size: 1.125rem; line-height: 1.8; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); font-weight: 300; margin: 0.5rem 0; diff --git a/app/submit-talk/page.tsx b/app/submit-talk/page.tsx index 11ab455..237ab48 100644 --- a/app/submit-talk/page.tsx +++ b/app/submit-talk/page.tsx @@ -557,7 +557,7 @@ export default function SubmitTalk() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -577,13 +577,13 @@ const Container = styled.main` const Title = styled.h1` font-size: 2rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; text-align: center; ` const Subtitle = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); margin: -1rem 0 0 0; text-align: center; ` @@ -599,7 +599,7 @@ const FormSection = styled.div` flex-direction: column; gap: 1rem; padding-top: 1rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--border); &:first-of-type { border-top: none; @@ -610,7 +610,7 @@ const FormSection = styled.div` const SectionTitle = styled.h2` font-size: 1.25rem; font-weight: 600; - color: white; + color: var(--foreground); margin: 0; ` @@ -626,21 +626,21 @@ const Field = styled.div` ` const InfoValue = styled.div` - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); font-size: 0.9375rem; margin: 0; ` const InfoNote = styled.p` margin: 0.5rem 0 0 0; - color: rgba(255, 255, 255, 0.6); + color: rgba(var(--foreground-rgb), 0.6); font-size: 0.875rem; line-height: 1.5; ` const HookNote = styled.p` margin: 0; - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); font-size: 0.8125rem; line-height: 1.4; ` @@ -663,15 +663,15 @@ const ThumbnailPreviewWrap = styled.div` const Label = styled.label` font-size: 0.875rem; font-weight: 700; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); ` const ReadOnlyValue = styled.div` padding: 0.75rem; - background-color: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); + background-color: rgba(var(--foreground-rgb), 0.05); + border: 1px solid var(--border); border-radius: 0.5rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 1rem; ` @@ -689,16 +689,16 @@ const RadioOption = styled.div` const RadioLabel = styled.label` font-size: 0.875rem; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); cursor: pointer; ` const FileInput = styled.input` padding: 0.75rem; - background-color: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); + background-color: rgba(var(--foreground-rgb), 0.1); + border: 1px solid rgba(var(--foreground-rgb), 0.2); border-radius: 0.5rem; - color: white; + color: var(--foreground); font-size: 1rem; cursor: pointer; @@ -708,7 +708,7 @@ const FileInput = styled.input` background-color: rgba(156, 163, 255, 0.2); border: 1px solid rgba(156, 163, 255, 0.4); border-radius: 0.375rem; - color: white; + color: var(--foreground); cursor: pointer; font-size: 0.875rem; transition: all 0.2s ease; @@ -722,7 +722,7 @@ const FileInput = styled.input` const FileInfo = styled.div` margin-top: 0.5rem; font-size: 0.875rem; - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-style: italic; ` @@ -752,7 +752,7 @@ const CancelButton = styled(Button)` ` const LoadingText = styled.div` - color: white; + color: var(--foreground); font-size: 1.25rem; text-align: center; ` @@ -763,12 +763,12 @@ const CheckboxField = styled.div` gap: 0.75rem; margin-top: 1rem; padding-top: 1.5rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--border); ` const CheckboxLabel = styled.label` font-size: 0.875rem; - color: rgba(255, 255, 255, 0.9); + color: rgba(var(--foreground-rgb), 0.9); cursor: pointer; line-height: 1.5; ` diff --git a/app/talk/page.tsx b/app/talk/page.tsx index 71a9f88..799e1c0 100644 --- a/app/talk/page.tsx +++ b/app/talk/page.tsx @@ -82,10 +82,10 @@ const FormContainer = styled.form` max-width: 48rem; margin: 0 auto; padding: 2rem; - background-color: rgba(255, 255, 255, 0.05); + background-color: rgba(var(--foreground-rgb), 0.05); backdrop-filter: blur(10px); border-radius: 0.5rem; - border: 1px solid rgba(255, 255, 255, 0.1); + border: 1px solid var(--border); display: flex; flex-direction: column; gap: 1rem; @@ -99,8 +99,8 @@ const TextArea = styled.textarea` padding: 0.75rem; border-radius: 0.375rem; background-color: rgba(0, 0, 0, 0.8); - color: white; - border: 1px solid rgba(255, 255, 255, 0.2); + color: var(--foreground); + border: 1px solid rgba(var(--foreground-rgb), 0.2); font-size: 1rem; min-height: 8rem; resize: vertical; @@ -114,7 +114,7 @@ const TextArea = styled.textarea` } &::placeholder { - color: rgba(255, 255, 255, 0.5); + color: rgba(var(--foreground-rgb), 0.5); } &:disabled { @@ -150,7 +150,7 @@ const Button = styled.button` const SubmitButton = styled(Button)` background: linear-gradient(135deg, rgba(147, 51, 234, 0.8), rgba(99, 102, 241, 0.8)); - color: white; + color: var(--foreground); &:hover:not(:disabled) { background: linear-gradient(135deg, rgba(147, 51, 234, 1), rgba(99, 102, 241, 1)); @@ -170,12 +170,12 @@ const ResetButton = styled.input` font-weight: 500; transition: all 0.2s; cursor: pointer; - background-color: rgba(255, 255, 255, 0.1); - color: white; - border: 1px solid rgba(255, 255, 255, 0.2); + background-color: rgba(var(--foreground-rgb), 0.1); + color: var(--foreground); + border: 1px solid rgba(var(--foreground-rgb), 0.2); &:hover:not(:disabled) { - background-color: rgba(255, 255, 255, 0.15); + background-color: rgba(var(--foreground-rgb), 0.15); transform: translateY(-1px); } diff --git a/app/talk/submitted/page.tsx b/app/talk/submitted/page.tsx index 6fc8486..301a7ec 100644 --- a/app/talk/submitted/page.tsx +++ b/app/talk/submitted/page.tsx @@ -29,10 +29,10 @@ const SuccessContainer = styled.div` max-width: 30rem; margin: 0 auto; padding: 3rem; - background-color: rgba(255, 255, 255, 0.05); + background-color: rgba(var(--foreground-rgb), 0.05); backdrop-filter: blur(10px); border-radius: 0.5rem; - border: 1px solid rgba(255, 255, 255, 0.1); + border: 1px solid var(--border); text-align: center; ` @@ -44,7 +44,7 @@ const SuccessTitle = styled.h1` ` const SuccessMessage = styled.p` - color: #d1d5db; + color: var(--muted-foreground); font-size: 1.125rem; margin-bottom: 2rem; line-height: 1.6; @@ -54,7 +54,7 @@ const BackLink = styled.a` display: inline-block; padding: 0.75rem 1.5rem; background-color: #8b5cf6; - color: white; + color: var(--foreground); border-radius: 0.375rem; text-decoration: none; font-weight: 500; diff --git a/app/watch/page.tsx b/app/watch/page.tsx index 9144bf1..6422114 100644 --- a/app/watch/page.tsx +++ b/app/watch/page.tsx @@ -57,7 +57,9 @@ export default function Watch() { <> } + fallback={ +
+ } > @@ -119,10 +121,10 @@ Explore our collection of presentations from the community.`} rel="noopener noreferrer" > - + {talk.title} - + {talk.speaker} @@ -150,7 +152,7 @@ Explore our collection of presentations from the community.`} // Styles const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -222,7 +224,7 @@ const HeroSection = styled.section` const HeroBlurb = styled.p` font-size: 1.25rem; line-height: 1.8; - color: #d1d5db; + color: var(--muted-foreground); text-align: center; max-width: 900px; margin: 0; @@ -255,8 +257,8 @@ const YearHeader = styled.h2` font-weight: bold; margin-bottom: 2rem; text-align: center; - color: white; - border-bottom: 2px solid rgba(255, 255, 255, 0.2); + color: var(--foreground); + border-bottom: 2px solid rgba(var(--foreground-rgb), 0.2); padding-bottom: 1rem; ` diff --git a/app/whois/ProfileDisplay.tsx b/app/whois/ProfileDisplay.tsx index 36e4dfc..60c575a 100644 --- a/app/whois/ProfileDisplay.tsx +++ b/app/whois/ProfileDisplay.tsx @@ -408,7 +408,7 @@ export function ProfileDisplay({ } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; diff --git a/app/whois/ProfileList.tsx b/app/whois/ProfileList.tsx index 95d6533..52265bd 100644 --- a/app/whois/ProfileList.tsx +++ b/app/whois/ProfileList.tsx @@ -168,7 +168,7 @@ export function ProfileList() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -195,7 +195,7 @@ const ContentWrapper = styled.div` ` const Title = styled.h1` - color: white; + color: var(--foreground); font-size: 2.5rem; font-weight: 700; margin: 0; @@ -203,7 +203,7 @@ const Title = styled.h1` ` const EmptyState = styled.div` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 1.25rem; text-align: center; padding: 4rem 0; @@ -226,12 +226,12 @@ const ProfileListItem = styled.div` ` const LoadingText = styled.div` - color: white; + color: var(--foreground); font-size: 1.2rem; ` const LoadingMoreText = styled.div` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 1rem; text-align: center; padding: 2rem 0; diff --git a/app/whois/ProfileNotFound.tsx b/app/whois/ProfileNotFound.tsx index fcd660b..02dcd92 100644 --- a/app/whois/ProfileNotFound.tsx +++ b/app/whois/ProfileNotFound.tsx @@ -19,7 +19,7 @@ export function ProfileNotFound() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -49,12 +49,12 @@ const NotFoundContent = styled.div` const NotFoundTitle = styled.h1` font-size: 6rem; font-weight: 700; - color: white; + color: var(--foreground); margin: 0; ` const NotFoundText = styled.p` - color: rgba(255, 255, 255, 0.7); + color: rgba(var(--foreground-rgb), 0.7); font-size: 1.25rem; margin: 0; ` diff --git a/app/whois/page.tsx b/app/whois/page.tsx index 7a562d3..3a61e2f 100644 --- a/app/whois/page.tsx +++ b/app/whois/page.tsx @@ -263,7 +263,7 @@ export default function Who() { } const BackgroundContainer = styled.section` - background-color: #0a0a0a; + background-color: var(--background); position: fixed; height: 100vh; width: 100vw; @@ -282,6 +282,6 @@ const Container = styled.main` ` const LoadingText = styled.div` - color: white; + color: var(--foreground); font-size: 1.2rem; ` From cc2630cc42561bb312b1f34e195060e8976572e3 Mon Sep 17 00:00:00 2001 From: Sam Holmes Date: Sun, 23 Aug 2026 19:10:53 -0700 Subject: [PATCH 02/31] feat: adopt streamlined site layout --- app/components/Button.tsx | 51 +- app/components/Card.tsx | 23 +- app/components/GiveATalkCTA.tsx | 219 +-------- app/components/Header.tsx | 35 +- app/globals.css | 17 +- app/layout.tsx | 2 +- app/page.tsx | 845 ++++++++++++-------------------- 7 files changed, 399 insertions(+), 793 deletions(-) diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 232d1ab..2ec0f82 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -74,19 +74,21 @@ const StyledButton = styled.button<{ $variant: "primary" | "secondary" | "tertiary" $size: "small" | "default" }>` - padding: ${(props) => (props.$size === "small" ? "0.5rem 1rem" : "0.75rem 1.5rem")}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; - font-weight: ${(props) => (props.$size === "small" ? "500" : "600")}; - font-size: ${(props) => (props.$size === "small" ? "inherit" : "1.1rem")}; + padding: ${(props) => (props.$size === "small" ? "0.5rem 1.1rem" : "0.85rem 1.75rem")}; + border-radius: 999px; + font-weight: ${(props) => (props.$size === "small" ? "600" : "700")}; + font-size: ${(props) => (props.$size === "small" ? "0.9rem" : "1.05rem")}; cursor: pointer; - transition: all 0.3s ease; + transition: all 0.2s ease; text-decoration: none; display: inline-flex; align-items: center; + justify-content: center; gap: 0.5rem; border: none; font-family: inherit; line-height: 1.5; + white-space: nowrap; background-color: ${(props) => props.$variant === "primary" ? "var(--foreground)" @@ -94,7 +96,8 @@ const StyledButton = styled.button<{ ? "transparent" : "transparent"}; color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; + border: ${(props) => + props.$variant === "secondary" ? "1.5px solid var(--foreground)" : "1.5px solid transparent"}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -124,7 +127,7 @@ const StyledButton = styled.button<{ if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" return "rgba(var(--foreground-rgb), 0.1)" }}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; + border-radius: 999px; ${(props) => props.$variant === "tertiary" && @@ -145,19 +148,21 @@ const StyledLink = styled(Link)<{ $variant: "primary" | "secondary" | "tertiary" $size: "small" | "default" }>` - padding: ${(props) => (props.$size === "small" ? "0.5rem 1rem" : "0.75rem 1.5rem")}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; - font-weight: ${(props) => (props.$size === "small" ? "500" : "600")}; - font-size: ${(props) => (props.$size === "small" ? "inherit" : "1.1rem")}; + padding: ${(props) => (props.$size === "small" ? "0.5rem 1.1rem" : "0.85rem 1.75rem")}; + border-radius: 999px; + font-weight: ${(props) => (props.$size === "small" ? "600" : "700")}; + font-size: ${(props) => (props.$size === "small" ? "0.9rem" : "1.05rem")}; cursor: pointer; - transition: all 0.3s ease; + transition: all 0.2s ease; text-decoration: none; display: inline-flex; align-items: center; + justify-content: center; gap: 0.5rem; border: none; font-family: inherit; line-height: 1.5; + white-space: nowrap; background-color: ${(props) => props.$variant === "primary" ? "var(--foreground)" @@ -165,7 +170,8 @@ const StyledLink = styled(Link)<{ ? "transparent" : "transparent"}; color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; + border: ${(props) => + props.$variant === "secondary" ? "1.5px solid var(--foreground)" : "1.5px solid transparent"}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -195,7 +201,7 @@ const StyledLink = styled(Link)<{ if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" return "rgba(var(--foreground-rgb), 0.1)" }}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; + border-radius: 999px; ${(props) => props.$variant === "tertiary" && @@ -211,19 +217,21 @@ const StyledExternalLink = styled.a<{ $variant: "primary" | "secondary" | "tertiary" $size: "small" | "default" }>` - padding: ${(props) => (props.$size === "small" ? "0.5rem 1rem" : "0.75rem 1.5rem")}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; - font-weight: ${(props) => (props.$size === "small" ? "500" : "600")}; - font-size: ${(props) => (props.$size === "small" ? "inherit" : "1.1rem")}; + padding: ${(props) => (props.$size === "small" ? "0.5rem 1.1rem" : "0.85rem 1.75rem")}; + border-radius: 999px; + font-weight: ${(props) => (props.$size === "small" ? "600" : "700")}; + font-size: ${(props) => (props.$size === "small" ? "0.9rem" : "1.05rem")}; cursor: pointer; - transition: all 0.3s ease; + transition: all 0.2s ease; text-decoration: none; display: inline-flex; align-items: center; + justify-content: center; gap: 0.5rem; border: none; font-family: inherit; line-height: 1.5; + white-space: nowrap; background-color: ${(props) => props.$variant === "primary" ? "var(--foreground)" @@ -231,7 +239,8 @@ const StyledExternalLink = styled.a<{ ? "transparent" : "transparent"}; color: ${(props) => (props.$variant === "primary" ? "var(--background)" : "var(--foreground)")}; - border: ${(props) => (props.$variant === "secondary" ? "1px solid var(--foreground)" : "none")}; + border: ${(props) => + props.$variant === "secondary" ? "1.5px solid var(--foreground)" : "1.5px solid transparent"}; position: ${(props) => (props.$variant === "tertiary" ? "relative" : "static")}; overflow: ${(props) => (props.$variant === "tertiary" ? "hidden" : "visible")}; @@ -261,7 +270,7 @@ const StyledExternalLink = styled.a<{ if (props.$variant === "tertiary") return "rgba(var(--foreground-rgb), 0.05)" return "rgba(var(--foreground-rgb), 0.1)" }}; - border-radius: ${(props) => (props.$variant === "tertiary" ? "0.375rem" : "0.25rem")}; + border-radius: 999px; ${(props) => props.$variant === "tertiary" && diff --git a/app/components/Card.tsx b/app/components/Card.tsx index e7828f2..2968a46 100644 --- a/app/components/Card.tsx +++ b/app/components/Card.tsx @@ -94,9 +94,9 @@ export const CardText = styled.p<{ $color?: string; $size?: string; $weight?: st const StyledLink = styled(Link)` display: flex; flex-direction: column; - background-color: var(--surface); - backdrop-filter: blur(10px); - border-radius: 0.5rem; + background-color: var(--surface-solid); + border: 1px solid var(--border); + border-radius: 0.75rem; overflow: hidden; transition: transform 0.2s ease; text-decoration: none; @@ -111,9 +111,9 @@ const StyledLink = styled(Link)` const StyledExternalLink = styled.a` display: flex; flex-direction: column; - background-color: var(--surface); - backdrop-filter: blur(10px); - border-radius: 0.5rem; + background-color: var(--surface-solid); + border: 1px solid var(--border); + border-radius: 0.75rem; overflow: hidden; transition: transform 0.2s ease; text-decoration: none; @@ -128,9 +128,9 @@ const StyledExternalLink = styled.a` const StyledDiv = styled.div` display: flex; flex-direction: column; - background-color: var(--surface); - backdrop-filter: blur(10px); - border-radius: 0.5rem; + background-color: var(--surface-solid); + border: 1px solid var(--border); + border-radius: 0.75rem; overflow: hidden; transition: transform 0.2s ease; @@ -146,9 +146,8 @@ const ImageContainer = styled.div<{ $aspectRatio?: "16/9" | "1/1" | "auto" }>` overflow: hidden; ${(props) => props.$aspectRatio === "16/9" && "aspect-ratio: 16/9;"} ${(props) => props.$aspectRatio === "1/1" && "aspect-ratio: 1/1;"} - background-color: ${(props) => - props.$aspectRatio !== "auto" ? "rgba(0, 0, 0, 0.8)" : "transparent"}; - border-radius: ${(props) => (props.$aspectRatio !== "auto" ? "0.5rem" : "0")}; + background-color: ${(props) => (props.$aspectRatio !== "auto" ? "var(--border)" : "transparent")}; + border-radius: 0; ` const CardImage = styled.img<{ $aspectRatio?: "16/9" | "1/1" | "auto" }>` diff --git a/app/components/GiveATalkCTA.tsx b/app/components/GiveATalkCTA.tsx index 012fa15..287b7dc 100644 --- a/app/components/GiveATalkCTA.tsx +++ b/app/components/GiveATalkCTA.tsx @@ -1,13 +1,14 @@ "use client" -import styled from "styled-components" -import Link from "next/link" import { useRouter } from "next/navigation" -import { useState, useEffect } from "react" +import { useEffect, useState } from "react" import { supabaseClient } from "../../lib/supabaseClient" +import { Button } from "./Button" -// Components // +// +// Components +// -export const GiveATalkCTA: React.FC = () => { +export const GiveATalkCTA = () => { const router = useRouter() const [isAuthenticated, setIsAuthenticated] = useState(null) @@ -18,217 +19,21 @@ export const GiveATalkCTA: React.FC = () => { } = await supabaseClient.auth.getUser() setIsAuthenticated(!!user) } + checkAuth() }, []) - const handleClick = (e: React.MouseEvent) => { + const handleClick = (event?: React.MouseEvent) => { if (isAuthenticated === false) { - e.preventDefault() + event?.preventDefault() const redirectUrl = encodeURIComponent("/submit-talk") router.push(`/login?redirect=${redirectUrl}`) } } return ( - - - - - - - Give a Talk! - + ) } - -const StyledLink = styled(Link)` - display: inline-flex; - align-items: center; - padding: 0.5rem 1rem; - gap: 0.5rem; - font-weight: 500; - font-size: 0.875rem; - color: rgba(255, 255, 255, 0.95); - text-decoration: none; - transition: all 0.3s ease-in-out; - border-radius: 15px 0 20px 0px; - box-shadow: - 0 0 20px rgba(156, 163, 255, 0.15), - 0 0 40px rgba(92, 107, 246, 0.1), - 0 0 60px rgba(28, 28, 40, 0.4), - 0 1px 3px rgba(0, 0, 0, 0.9), - 0 10px 20px -5px rgba(28, 28, 40, 0.5), - inset 0 1px 0 rgba(156, 163, 255, 0.1); - background: linear-gradient( - 135deg, - rgba(28, 28, 40, 0.9) 0%, - rgba(15, 15, 22, 0.95) 25%, - rgba(0, 0, 1, 1) 50%, - rgba(15, 15, 22, 0.95) 75%, - rgba(28, 28, 40, 0.9) 100% - ); - border: 1px solid rgba(156, 163, 255, 0.5); - position: relative; - overflow: hidden; - white-space: nowrap; - transform: perspective(1000px) rotateX(5deg) skew(-10deg) scaleY(.9); - animation: pulseGlow 3s ease-in-out infinite; - - &::before { - content: ""; - position: absolute; - top: -200%; - left: -100%; - width: 300%; - height: 400%; - background: linear-gradient( - 115deg, - transparent 40%, - rgba(156, 163, 255, 0.15) 48%, - rgba(255, 255, 255, 0.25) 50%, - rgba(156, 163, 255, 0.15) 52%, - transparent 60% - ); - animation: shimmer 2.5s linear infinite; - } - - &::after { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 1px; - background: linear-gradient( - 90deg, - transparent 0%, - rgba(255, 255, 255, 0.4) 50%, - transparent 100% - ); - pointer-events: none; - } - - &:hover { - transform: perspective(1000px) rotateX(5deg) translateY(-1px) skew(-10deg) scaleY(.9); - box-shadow: - 0 0 30px rgba(156, 163, 255, 0.25), - 0 0 50px rgba(92, 107, 246, 0.15), - 0 0 80px rgba(28, 28, 40, 0.5), - 0 2px 4px rgba(0, 0, 0, 1), - 0 15px 30px -5px rgba(28, 28, 40, 0.7), - inset 0 1px 0 rgba(156, 163, 255, 0.15); - text-decoration: none; - } - - @keyframes shimmer { - 0% { - transform: translateX(-100%) translateY(-100%) rotate(45deg); - } - 100% { - transform: translateX(100%) translateY(100%) rotate(45deg); - } - } - - @keyframes pulseGlow { - 0%, 100% { - box-shadow: - 0 0 20px rgba(156, 163, 255, 0.15), - 0 0 40px rgba(92, 107, 246, 0.1), - 0 0 60px rgba(28, 28, 40, 0.4), - 0 1px 3px rgba(0, 0, 0, 0.9), - 0 10px 20px -5px rgba(28, 28, 40, 0.5), - inset 0 1px 0 rgba(156, 163, 255, 0.1); - } - 50% { - box-shadow: - 0 0 35px rgba(156, 163, 255, 0.25), - 0 0 70px rgba(92, 107, 246, 0.18), - 0 0 100px rgba(28, 28, 40, 0.5), - 0 1px 3px rgba(0, 0, 0, 0.9), - 0 10px 20px -5px rgba(28, 28, 40, 0.5), - inset 0 1px 0 rgba(156, 163, 255, 0.15); - } - } - - &:hover { - transform: scale(1.02) skew(-10deg) scaleY(.9); - box-shadow: - 0 4px 12px rgba(0, 0, 0, 1), - 0 0 20px rgba(92, 107, 246, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.2); - text-decoration: none; - } - - @keyframes shimmer { - 0% { - transform: translateX(-100%) translateY(-100%) rotate(45deg); - } - 100% { - transform: translateX(100%) translateY(100%) rotate(45deg); - } - } - - &::after { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 50%; - background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, transparent 100%); - pointer-events: none; - } - - &:hover { - transform: scale(1.03) skew(-10deg) scaleY(.9); - box-shadow: - 0 6px 16px rgba(0, 0, 0, 0.8), - 0 0 20px rgba(92, 107, 246, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.25), - inset 0 -1px 0 rgba(0, 0, 0, 0.9); - text-decoration: none; - } - - @keyframes shimmer { - 0% { - transform: translateX(-100%) translateY(-100%) rotate(45deg); - } - 100% { - transform: translateX(100%) translateY(100%) rotate(45deg); - } - } - } - - @keyframes pulse { - 0%, - 100% { - opacity: 1; - } - 50% { - opacity: 0.8; - } - } -` - -const IconWrapper = styled.div` - width: 1.25rem; - height: 1.25rem; - display: flex; - align-items: center; - justify-content: center; - - svg { - width: 100%; - height: 100%; - } -` diff --git a/app/components/Header.tsx b/app/components/Header.tsx index e260a56..4c49e3d 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -1,6 +1,7 @@ "use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" +import Link from "next/link" import styled from "styled-components" import { links } from "../siteConfig" import { GiveATalkCTA } from "./GiveATalkCTA" @@ -129,7 +130,7 @@ export const Header = () => {