diff --git a/components/home/Home.tv.tsx b/components/home/Home.tv.tsx index cffff54f..594580f3 100644 --- a/components/home/Home.tv.tsx +++ b/components/home/Home.tv.tsx @@ -46,7 +46,7 @@ import { updateTVDiscovery } from "@/utils/tvDiscovery/sync"; const HORIZONTAL_PADDING = scaleSize(60); const TOP_PADDING = scaleSize(100); // Generous gap between sections for Apple TV+ aesthetic -const SECTION_GAP = scaleSize(10); +const SECTION_GAP = scaleSize(24); type InfiniteScrollingCollectionListSection = { type: "InfiniteScrollingCollectionList"; diff --git a/components/home/TVHeroCarousel.tsx b/components/home/TVHeroCarousel.tsx index 7a71fbfb..4e9e4712 100644 --- a/components/home/TVHeroCarousel.tsx +++ b/components/home/TVHeroCarousel.tsx @@ -207,7 +207,7 @@ export const TVHeroCarousel: React.FC = ({ const typography = useScaledTVTypography(); const sizes = useScaledTVSizes(); const api = useAtomValue(apiAtom); - const _insets = useSafeAreaInsets(); + const insets = useSafeAreaInsets(); const router = useRouter(); // Active item for featured display (debounced) @@ -381,7 +381,13 @@ export const TVHeroCarousel: React.FC = ({ const heroHeight = SCREEN_HEIGHT * sizes.padding.heroHeight; return ( - + {/* Backdrop layers with crossfade */} = ({ position: "relative", width, aspectRatio, - borderRadius: scaleSize(4), + borderRadius: scaleSize(24), overflow: "hidden", backgroundColor: "#1a1a1a", borderWidth: scaleSize(2), diff --git a/constants/TVSizes.ts b/constants/TVSizes.ts index 676609bc..403b8ebd 100644 --- a/constants/TVSizes.ts +++ b/constants/TVSizes.ts @@ -79,7 +79,7 @@ export const TVAnimation = { * Applied to poster sizes and gaps. */ const sizeScaleMultipliers: Record = { - [TVTypographyScale.Small]: 0.9, + [TVTypographyScale.Small]: 0.8, [TVTypographyScale.Default]: 1.0, [TVTypographyScale.Large]: 1.1, [TVTypographyScale.ExtraLarge]: 1.2, diff --git a/constants/TVTypography.ts b/constants/TVTypography.ts index 833f617e..d53726ad 100644 --- a/constants/TVTypography.ts +++ b/constants/TVTypography.ts @@ -1,56 +1,75 @@ import { TVTypographyScale, useSettings } from "@/utils/atoms/settings"; +import { scaleSize } from "@/utils/scaleSize"; /** * TV Typography Scale * * Consistent text sizes for TV interface components. - * Design values are for 1920×1080 and scaled proportionally - * to the actual viewport via scaleSize(). + * Base values are designed for 1920x1080 and scaled to the actual viewport via + * scaleSize(), then further adjusted by the user's tvTypographyScale setting. */ -import { scaleSize } from "@/utils/scaleSize"; +// ============================================================================= +// BASE VALUES (at Default scale) +// ============================================================================= export const TVTypography = { /** Hero titles, movie/show names */ - display: scaleSize(70), + display: 70, /** Episode series name, major headings */ - title: scaleSize(42), + title: 42, /** Section headers (Cast, Technical Details, From this Series) */ - heading: scaleSize(32), + heading: 32, /** Overview, actor names, card titles, metadata */ - body: scaleSize(40), + body: 40, /** Secondary text, labels, subtitles */ - callout: scaleSize(26), + callout: 26, }; export type TVTypographyKey = keyof typeof TVTypography; +// ============================================================================= +// SCALING +// ============================================================================= + const scaleMultipliers: Record = { - [TVTypographyScale.Small]: 0.85, + [TVTypographyScale.Small]: 0.8, [TVTypographyScale.Default]: 1.0, - [TVTypographyScale.Large]: 1.2, - [TVTypographyScale.ExtraLarge]: 1.4, + [TVTypographyScale.Large]: 1.1, + [TVTypographyScale.ExtraLarge]: 1.2, +}; + +// ============================================================================= +// HOOKS +// ============================================================================= + +export type ScaledTVTypography = { + display: number; + title: number; + heading: number; + body: number; + callout: number; }; /** * Hook that returns scaled TV typography values based on user settings. * Use this instead of the static TVTypography constant for dynamic scaling. */ -export const useScaledTVTypography = () => { +export const useScaledTVTypography = (): ScaledTVTypography => { const { settings } = useSettings(); const scale = scaleMultipliers[settings.tvTypographyScale] ?? scaleMultipliers[TVTypographyScale.Default]; return { - display: Math.round(TVTypography.display * scale), - title: Math.round(TVTypography.title * scale), - heading: Math.round(TVTypography.heading * scale), - body: Math.round(TVTypography.body * scale), - callout: Math.round(TVTypography.callout * scale), + display: Math.round(scaleSize(TVTypography.display) * scale), + title: Math.round(scaleSize(TVTypography.title) * scale), + heading: Math.round(scaleSize(TVTypography.heading) * scale), + body: Math.round(scaleSize(TVTypography.body) * scale), + callout: Math.round(scaleSize(TVTypography.callout) * scale), }; };