Skip to content
Open
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ React Native app for WMBR radio streaming (live + archives), schedules, and play
- `5–8` one specific week in a 4‑week cycle (Week 1–4)
- Weekday shows use `day=7` and are expanded across Monday–Friday.

## Best Practices

- Don't use any "bare" colors, either hex or `rgb()`. Instead, use values from
the `COLORS` object in `src/utils/Colors.ts`, or `CORE_COLORS` if there
doesn't seem to be a matching semantic color.

## Data Flow (High Level)

```
Expand Down
60 changes: 45 additions & 15 deletions src/app/About/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import LinearGradient from 'react-native-linear-gradient';
import { ABOUT_PAGE_GRADIENT } from '@utils/GradientColors';
import Icon from 'react-native-vector-icons/Ionicons';
import { getWMBRLogoSVG } from '@utils/WMBRLogo';
import { COLORS } from '@utils/Colors';
Expand All @@ -26,11 +25,18 @@ const openProgramGuide = () =>

export default function AboutPage() {
return (
<LinearGradient colors={ABOUT_PAGE_GRADIENT} style={styles.gradient}>
<LinearGradient
colors={[COLORS.BACKGROUND.SECONDARY, COLORS.BACKGROUND.PRIMARY]}
style={styles.gradient}
>
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
<View style={styles.logoRow}>
<SvgXml xml={getWMBRLogoSVG('#FFFFFF')} width={60} height={16} />
<SvgXml
xml={getWMBRLogoSVG(COLORS.TEXT.PRIMARY)}
width={60}
height={16}
/>
</View>

<Text style={styles.body}>
Expand All @@ -51,7 +57,7 @@ export default function AboutPage() {
onPress={() => openLink('tel:+16172538810')}
activeOpacity={0.8}
>
<Icon name="call-outline" size={20} color="#FFFFFF" />
<Icon name="call-outline" size={20} color={COLORS.TEXT.PRIMARY} />
<View style={styles.textBlock}>
<Text style={styles.linkText}>(617) 253-8810</Text>
<Text style={styles.smallText}>Requests Line</Text>
Expand All @@ -64,7 +70,7 @@ export default function AboutPage() {
onPress={() => openLink('mailto:[email protected]')}
activeOpacity={0.8}
>
<Icon name="mail-outline" size={20} color="#FFFFFF" />
<Icon name="mail-outline" size={20} color={COLORS.TEXT.PRIMARY} />
<View style={styles.textBlock}>
<Text style={styles.linkText}>[email protected]</Text>
<Text style={styles.smallText}>Music Department</Text>
Expand All @@ -76,7 +82,7 @@ export default function AboutPage() {
onPress={() => openLink('mailto:[email protected]')}
activeOpacity={0.8}
>
<Icon name="mail-outline" size={20} color="#FFFFFF" />
<Icon name="mail-outline" size={20} color={COLORS.TEXT.PRIMARY} />
<View style={styles.textBlock}>
<Text style={styles.linkText}>[email protected]</Text>
<Text style={styles.smallText}>News Department</Text>
Expand All @@ -99,7 +105,11 @@ export default function AboutPage() {
onPress={openProgramGuide}
activeOpacity={0.8}
>
<Icon name="musical-notes-outline" size={18} color="#000" />
<Icon
name="musical-notes-outline"
size={18}
color={COLORS.BUTTON.ACCENT.TEXT}
/>
<Text style={styles.buttonText}>Program Guide</Text>
</TouchableOpacity>

Expand All @@ -108,7 +118,11 @@ export default function AboutPage() {
onPress={openWebsite}
activeOpacity={0.8}
>
<Icon name="globe-outline" size={18} color="#FFFFFF" />
<Icon
name="globe-outline"
size={18}
color={COLORS.TEXT.PRIMARY}
/>
<Text style={styles.buttonOutlineText}>Visit Our Website</Text>
</TouchableOpacity>
</View>
Expand All @@ -119,28 +133,40 @@ export default function AboutPage() {
activeOpacity={0.8}
style={styles.socialButton}
>
<Icon name="logo-instagram" size={20} color="#FFFFFF" />
<Icon
name="logo-instagram"
size={20}
color={COLORS.TEXT.PRIMARY}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={openTwitter}
activeOpacity={0.8}
style={styles.socialButton}
>
<Icon name="logo-twitter" size={20} color="#FFFFFF" />
<Icon name="logo-twitter" size={20} color={COLORS.TEXT.PRIMARY} />
</TouchableOpacity>
<TouchableOpacity
onPress={openFacebook}
activeOpacity={0.8}
style={styles.socialButton}
>
<Icon name="logo-facebook" size={20} color="#FFFFFF" />
<Icon
name="logo-facebook"
size={20}
color={COLORS.TEXT.PRIMARY}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={openMastodon}
activeOpacity={0.8}
style={styles.socialButton}
>
<Icon name="logo-mastodon" size={20} color="#FFFFFF" />
<Icon
name="logo-mastodon"
size={20}
color={COLORS.TEXT.PRIMARY}
/>
</TouchableOpacity>
</View>
</View>
Expand Down Expand Up @@ -169,13 +195,17 @@ const styles = StyleSheet.create({
button: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#00D17A',
backgroundColor: COLORS.BUTTON.ACCENT.BACKGROUND,
paddingHorizontal: 12,
paddingVertical: 10,
borderRadius: 8,
marginRight: 8,
},
buttonText: { marginLeft: 8, color: '#000', fontWeight: '700' },
buttonText: {
marginLeft: 8,
color: COLORS.BUTTON.ACCENT.TEXT,
fontWeight: '700',
},
buttonOutline: {
flexDirection: 'row',
alignItems: 'center',
Expand All @@ -190,7 +220,7 @@ const styles = StyleSheet.create({
socialRow: { flexDirection: 'row', marginTop: 18 },
socialButton: { marginRight: 12 },
linkText: { color: COLORS.TEXT.LINK, textDecorationLine: 'underline' },
smallText: { color: '#AAAAAA', fontSize: 12, marginTop: 2 },
smallText: { color: COLORS.TEXT.TERTIARY, fontSize: 12, marginTop: 2 },
section: { marginTop: 12, marginBottom: 8 },
sectionTitle: {
color: COLORS.TEXT.PRIMARY,
Expand Down
6 changes: 3 additions & 3 deletions src/app/Home/HomeNowPlaying.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,20 @@ export default function HomeNowPlaying({ showInfo }: { showInfo?: ShowInfo }) {
const styles = StyleSheet.create({
liveText: {
fontSize: 14,
color: '#FF4444',
color: COLORS.TEXT.ALERT,
fontWeight: '500',
marginBottom: 8,
},
nowPlayingContainer: { alignItems: 'center', marginTop: 4 },
nowPlayingLabel: {
fontSize: 10,
color: COLORS.TEXT.META,
color: COLORS.TEXT.TERTIARY,
fontWeight: '500',
marginBottom: 2,
textTransform: 'uppercase',
letterSpacing: 0.5,
},
nowPlayingLabelActive: { color: '#BBBBBB' },
nowPlayingLabelActive: { color: COLORS.TEXT.SECONDARY },
currentSongText: {
fontSize: 12,
color: COLORS.TEXT.SECONDARY,
Expand Down
6 changes: 3 additions & 3 deletions src/app/Home/PlayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function PlayButton({
return <Icon name="stop" size={64} color={CORE_COLORS.WMBR_GREEN} />;
}
} else {
return <Icon name="play" size={64} color="#FFFFFF" />;
return <Icon name="play" size={64} color={CORE_COLORS.WHITE} />;
}
}, [isPlaying, isPlayingArchive]);

Expand Down Expand Up @@ -165,8 +165,8 @@ const styles = StyleSheet.create({
elevation: 12,
},
playButtonActive: {
backgroundColor: '#FFFFFF',
shadowColor: '#FFFFFF',
backgroundColor: CORE_COLORS.WHITE,
shadowColor: CORE_COLORS.WHITE,
},
buttonContent: {
width: '100%',
Expand Down
4 changes: 2 additions & 2 deletions src/app/Home/SplashScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Animated, {
import LinearGradient from 'react-native-linear-gradient';
import { SvgXml } from 'react-native-svg';
import { getWMBRLogoSVG } from '@utils/WMBRLogo';
import { CORE_COLORS } from '@utils/Colors';
import { COLORS, CORE_COLORS } from '@utils/Colors';

interface SplashScreenProps {
onAnimationEnd: () => void;
Expand Down Expand Up @@ -102,7 +102,7 @@ export default function SplashScreen({ onAnimationEnd }: SplashScreenProps) {
/>

<LinearGradient
colors={['#000000', '#1a1a1a', '#000000']}
colors={[COLORS.BACKGROUND.SECONDARY, COLORS.BACKGROUND.PRIMARY]}
style={styles.gradient}
>
<View style={styles.content}>
Expand Down
24 changes: 12 additions & 12 deletions src/app/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export default function HomeScreen() {
colors={
isPlaying
? [CORE_COLORS.WMBR_GREEN, '#006B31', CORE_COLORS.WMBR_GREEN]
: ['#000000', '#1a1a1a', '#000000']
: [COLORS.BACKGROUND.SECONDARY, COLORS.BACKGROUND.PRIMARY]
}
style={styles.fullScreenGradient}
>
Expand Down Expand Up @@ -380,15 +380,15 @@ export default function HomeScreen() {
<TouchableOpacity
style={[
styles.liveButton,
isPlaying && styles.liveButtonActive,
isPlaying && styles.liveButtonPlaying,
]}
onPress={handleSwitchToLive}
activeOpacity={0.7}
>
<Text
style={[
styles.liveButtonText,
isPlaying && styles.liveButtonTextActive,
isPlaying && styles.liveButtonTextPlaying,
]}
>
← Switch to LIVE
Expand Down Expand Up @@ -448,27 +448,27 @@ const styles = StyleSheet.create({
marginBottom: 12,
lineHeight: 16,
},
showDescriptionActive: { color: '#D0D0D0' },
showDescriptionActive: { color: COLORS.TEXT.ACTIVE },
liveButton: {
marginTop: 16,
paddingHorizontal: 20,
paddingVertical: 12,
backgroundColor: 'rgba(255, 68, 68, 0.2)',
backgroundColor: COLORS.BUTTON.SWITCH.BACKGROUND,
borderRadius: 20,
borderWidth: 1,
borderColor: '#FF4444',
},
liveButtonActive: {
backgroundColor: 'rgba(255, 255, 255, 0.2)',
borderColor: '#FFFFFF',
borderColor: COLORS.BUTTON.SWITCH.BORDER,
},
liveButtonText: {
color: '#FF4444',
color: COLORS.BUTTON.SWITCH.TEXT,
fontSize: 14,
fontWeight: '600',
textAlign: 'center',
},
liveButtonTextActive: { color: '#FFFFFF' },
liveButtonPlaying: {
backgroundColor: COLORS.BUTTON.SWITCH_ACTIVE.BACKGROUND,
borderColor: COLORS.BUTTON.SWITCH_ACTIVE.BORDER,
},
liveButtonTextPlaying: { color: COLORS.BUTTON.SWITCH_ACTIVE.TEXT },
playbackControls: {
flexDirection: 'row',
alignItems: 'center',
Expand Down
Loading