/* Western digits everywhere for consistency with reading times, prices and code. */ const dateFormat = new Intl.DateTimeFormat('ar-u-nu-latn', { day: 'numeric', month: 'long', year: 'numeric' }) const numberFormat = new Intl.NumberFormat('en-US') export function formatDate(value: string | Date | null | undefined): string { if (!value) return '' const date = value instanceof Date ? value : new Date(value) return Number.isNaN(date.getTime()) ? '' : dateFormat.format(date) } export const formatNumber = (value: number | null | undefined) => numberFormat.format(value ?? 0) /* Single source for the displayed membership price. */ export const MEMBERSHIP_PRICE = '$10' /* Arabic count agreement for «دليل»: 1 دليل، 2 دليلان، 3–10 أدلة، 11+ دليلاً. */ export function guidesLabel(n: number): string { if (n === 0) return 'لا أدلة' if (n === 1) return 'دليل واحد' if (n === 2) return 'دليلان' return `${formatNumber(n)} ${n <= 10 ? 'أدلة' : 'دليلاً'}` } export function minutesLabel(n: number | null | undefined): string { const value = n ?? 0 if (value === 1) return 'دقيقة واحدة' if (value === 2) return 'دقيقتان' return `${formatNumber(value)} ${value % 100 >= 3 && value % 100 <= 10 ? 'دقائق' : 'دقيقة'}` } /* Content-type badge labels (L-09). Null for unset/unknown — no byline invented. */ export function contentTypeLabel(value: string | null | undefined): string | null { switch (value) { case 'note': return 'ملاحظة تقنية' case 'tutorial': return 'دليل عملي' case 'case_study': return 'تجربة موثقة' case 'comparison': return 'مقارنة' default: return null } }