chore(subscription-specific): 🔧 Add TierCard actions, refined TierComparisonTable with feature rows/headers, and WhiteGloveSection UI for premium tier comparison

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-02-22 10:33:18 -08:00
parent 99ac94d954
commit 6f2c2ef2a3
6 changed files with 33 additions and 38 deletions

View file

@ -26,7 +26,7 @@ import { TierCardHeader } from './TierCardHeader';
import { TierCardPricing } from './TierCardPricing';
import type { PlatformSubscriptionTier } from '@/types';
import type { TierSlug } from '@lilith/ui-tiers';
import type { PlatformTierSlug as TierSlug } from '@platform/config';
export interface TierCardProps {
tier: PlatformSubscriptionTier;

View file

@ -11,7 +11,7 @@ import type { FC, KeyboardEvent } from 'react';
import { ActionSection, SelectButton } from './TierCard.styles';
import { getButtonText } from './TierCard.utils';
import type { TierSlug } from '@lilith/ui-tiers';
import type { PlatformTierSlug as TierSlug } from '@platform/config';
export interface TierCardActionsProps {

View file

@ -5,12 +5,10 @@
import { EditableContent } from '@lilith/ui-dev-content';
import styled, { css } from '@lilith/ui-styled-components';
import {
type TierSlug,
getTierButtonStyle,
getTierHeaderBorder as getHeaderBorder,
hasPremiumButtonStyle,
diamondShimmerKeyframes,
} from '@lilith/ui-tiers';
type PlatformTierSlug as TierSlug,
tierStyles,
shimmerKeyframes as diamondShimmerKeyframes,
} from '@platform/config';
import { useTranslation } from 'react-i18next';
import type { PlatformSubscriptionTier } from '@/types';
@ -100,10 +98,10 @@ const StartButton = styled.button<{ $isHighlighted: boolean; $tierSlug?: TierSlu
/* Tier-specific or default styling */
${(props: { theme: DefaultTheme; $isHighlighted: boolean; $tierSlug?: TierSlug }) => {
const tierSlug = props.$tierSlug as TierSlug;
const isPremiumTier = hasPremiumButtonStyle(tierSlug);
const isPremiumTier = tierStyles.hasPremiumStyle(tierSlug);
if (isPremiumTier) {
const style = getTierButtonStyle(tierSlug);
const style = tierStyles.getButtonStyle(tierSlug);
return css`
background: ${style.background};
background-size: 200% 100%;
@ -163,7 +161,7 @@ const StartButton = styled.button<{ $isHighlighted: boolean; $tierSlug?: TierSlu
&:focus-visible {
outline: 2px solid ${(props: { theme: DefaultTheme; $tierSlug?: TierSlug }) => {
const tierSlug = props.$tierSlug as TierSlug;
const border = getHeaderBorder(tierSlug);
const border = tierStyles.getColumnStyle(tierSlug).borderColor;
return border === 'transparent' ? props.theme.colors.primary.main : border;
}};
outline-offset: 2px;

View file

@ -5,7 +5,7 @@
import { EditableContent } from '@lilith/ui-dev-content';
import { Tooltip } from '@lilith/ui-feedback';
import styled from '@lilith/ui-styled-components';
import { type TierSlug, getTierColumnBackground as getColumnBg } from '@lilith/ui-tiers';
import { type PlatformTierSlug as TierSlug, tierStyles } from '@platform/config';
import { CheckIcon, XIcon, InfoIcon } from '@lilith/ui-icons';
import { useTranslation } from 'react-i18next';
@ -181,7 +181,7 @@ export const TierFeatureRows = ({ tiers, featureRows, highlightedTierSlug }: Tie
const getTierColumnBackground = (tierSlug: TierSlug, isHighlighted: boolean): string => {
if (!isHighlighted) {return 'transparent';}
return getColumnBg(tierSlug);
return tierStyles.getColumnStyle(tierSlug).background;
};
const TableBody = styled.tbody`

View file

@ -6,10 +6,9 @@ import { EditableContent } from '@lilith/ui-dev-content';
import { onHover, idleMs } from '@lilith/ui-icons';
import styled from '@lilith/ui-styled-components';
import {
type TierSlug,
getTierColumnBackground as getColumnBg,
getTierHeaderBorder as getHeaderBorder,
} from '@lilith/ui-tiers';
type PlatformTierSlug as TierSlug,
tierStyles,
} from '@platform/config';
import { useTranslation } from 'react-i18next';
import type { PlatformSubscriptionTier } from '@/types';
@ -88,11 +87,11 @@ export const TierTableHeader = ({ tiers, highlightedTierSlug }: TierTableHeaderP
const getTierColumnBackground = (tierSlug: TierSlug, isHighlighted: boolean): string => {
if (!isHighlighted) {return 'transparent';}
return getColumnBg(tierSlug);
return tierStyles.getColumnStyle(tierSlug).background;
};
const getTierHeaderBorder = (tierSlug: TierSlug, theme: DefaultTheme): string => {
const border = getHeaderBorder(tierSlug);
const border = tierStyles.getColumnStyle(tierSlug).borderColor;
return border === 'transparent' ? theme.colors.primary.main : border;
};

View file

@ -9,13 +9,11 @@
import { EditableContent } from '@lilith/ui-dev-content';
import styled, { css } from '@lilith/ui-styled-components';
import {
type TierSlug,
getTierButtonStyle,
getTierGlowColor,
getTierHeaderBorder,
diamondShimmerKeyframes,
type PlatformTierSlug as TierSlug,
tierStyles,
shimmerKeyframes as diamondShimmerKeyframes,
reducedMotionStyles,
} from '@lilith/ui-tiers';
} from '@platform/config';
import { CrownIcon, SparklesIcon, GemIcon, AwardIcon, ShieldIcon, UserCheckIcon, LockIcon } from '@lilith/ui-icons';
import { Link } from '@lilith/ui-router';
import { useTranslation } from 'react-i18next';
@ -189,7 +187,7 @@ export const WhiteGloveSection = ({ tiers, isLoading = false, id }: WhiteGloveSe
<CardsGrid>
{conciergeTiers.map((tier) => {
const tierSlug = tier.slug as TierSlug;
const buttonStyle = getTierButtonStyle(tierSlug);
const buttonStyle = tierStyles.getButtonStyle(tierSlug);
return (
<TierCard key={tier.id} $tierSlug={tierSlug}>
@ -473,14 +471,14 @@ const TierCard = styled.div<{ $tierSlug: TierSlug }>`
position: relative;
background: ${(props: { theme: DefaultTheme }) => props.theme.colors.surface};
border-radius: ${(props: { theme: DefaultTheme }) => props.theme.borderRadius.xl};
border: 2px solid ${(props) => getTierHeaderBorder(props.$tierSlug)};
border: 2px solid ${(props) => tierStyles.getColumnStyle(props.$tierSlug).borderColor};
overflow: hidden;
transition: all ${(props: { theme: DefaultTheme }) => props.theme.transitions.slow};
&:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 20px 60px ${(props) => getTierGlowColor(props.$tierSlug)},
0 0 80px ${(props) => getTierGlowColor(props.$tierSlug)};
box-shadow: 0 20px 60px ${(props) => tierStyles.getGlowColor(props.$tierSlug)},
0 0 80px ${(props) => tierStyles.getGlowColor(props.$tierSlug)};
}
${reducedMotionStyles}
@ -491,7 +489,7 @@ const CardGlow = styled.div<{ $tierSlug: TierSlug }>`
inset: 0;
background: radial-gradient(
circle at 50% 0%,
${(props) => getTierGlowColor(props.$tierSlug)},
${(props) => tierStyles.getGlowColor(props.$tierSlug)},
transparent 70%
);
opacity: 0.15;
@ -502,7 +500,7 @@ const CardHeader = styled.header<{ $tierSlug: TierSlug }>`
padding: 2.5rem 2rem;
text-align: center;
background: ${(props) => {
const glowColor = getTierGlowColor(props.$tierSlug);
const glowColor = tierStyles.getGlowColor(props.$tierSlug);
return `linear-gradient(180deg, ${glowColor}, transparent)`;
}};
border-bottom: 1px solid ${(props: { theme: DefaultTheme }) => props.theme.colors.border.default}40;
@ -517,12 +515,12 @@ const TierIconWrapper = styled.div<{ $tierSlug: TierSlug }>`
margin-bottom: 1rem;
border-radius: 50%;
background: ${(props) => {
const glowColor = getTierGlowColor(props.$tierSlug);
const glowColor = tierStyles.getGlowColor(props.$tierSlug);
return `radial-gradient(circle, ${glowColor}, transparent)`;
}};
border: 2px solid ${(props) => getTierHeaderBorder(props.$tierSlug)};
color: ${(props) => getTierHeaderBorder(props.$tierSlug)};
box-shadow: 0 0 40px ${(props) => getTierGlowColor(props.$tierSlug)};
border: 2px solid ${(props) => tierStyles.getColumnStyle(props.$tierSlug).borderColor};
color: ${(props) => tierStyles.getColumnStyle(props.$tierSlug).borderColor};
box-shadow: 0 0 40px ${(props) => tierStyles.getGlowColor(props.$tierSlug)};
${(props) =>
props.$tierSlug === 'diamond' &&
@ -572,9 +570,9 @@ const VipBadge = styled.div<{ $tierSlug: TierSlug }>`
gap: 0.5rem;
padding: 0.75rem 1rem;
border-radius: ${(props: { theme: DefaultTheme }) => props.theme.borderRadius.lg};
background: ${(props) => getTierGlowColor(props.$tierSlug)};
border: 1px solid ${(props) => getTierHeaderBorder(props.$tierSlug)};
color: ${(props) => getTierHeaderBorder(props.$tierSlug)};
background: ${(props) => tierStyles.getGlowColor(props.$tierSlug)};
border: 1px solid ${(props) => tierStyles.getColumnStyle(props.$tierSlug).borderColor};
color: ${(props) => tierStyles.getColumnStyle(props.$tierSlug).borderColor};
font-size: clamp(0.85rem, 1.8vw, 0.95rem);
font-weight: 600;
text-align: center;