{ "name": "Ganjoor", "version": 1, "meta": { "source": "github", "repo": "anas-rashid/ganjoorandroid", "ref": "main@50bbe0b", "package": "app", "paths": { "tokens": [ "app/src/main/java/com/ganjoor/android/ui/theme/Theme.kt", "app/src/main/java/com/ganjoor/android/ui/theme/Type.kt", "app/src/main/res/values/colors.xml" ], "fonts": [ "app/src/main/res/font/" ], "assets": [ "app/src/main/res/drawable/", "app/src/main/res/mipmap-xxxhdpi/", "fastlane/metadata/android/fa/images/phoneScreenshots/" ], "docs": [ "README.md" ] }, "synced": "2026-10-07" }, "color": { "themes": [ { "id": "light", "name": "Light" }, { "id": "dark", "name": "Dark" }, { "id": "sepia", "name": "Sepia" }, { "id": "sepia-night", "name": "Sepia night" }, { "id": "dark-oled", "name": "Dark · OLED black" }, { "id": "sepia-night-oled", "name": "Sepia night · OLED black" } ], "tokens": [ { "name": "primary", "value": { "light": "#00696e", "dark": "#80d4da", "sepia": "#7a4e24", "sepia-night": "#d9a96c", "dark-oled": "#80d4da", "sepia-night-oled": "#d9a96c" }, "usage": "Turquoise (sepia: walnut). Tappable crumbs in breadcrumbs, section labels in the settings sheet, the pin mark, a saved bookmark heart, TextButton labels, \"AI-generated\" note. 6.3:1+ on surface in every theme." }, { "name": "on-primary", "value": { "light": "#ffffff", "dark": "#003739", "sepia": "#ffffff", "sepia-night": "#3a2510", "dark-oled": "#003739", "sepia-night-oled": "#3a2510" }, "usage": "Text and icons on a primary fill: Switch thumb when on, filled Button labels." }, { "name": "primary-container", "value": { "light": "#9cf1f6", "dark": "#004f53", "sepia": "#e8d3b5", "sepia-night": "#53391c", "dark-oled": "#004f53", "sepia-night-oled": "#53391c" }, "usage": "Tonal turquoise fill for emphasised containers (Material defaults: filled-tonal surfaces). Rarely used directly." }, { "name": "on-primary-container", "value": { "light": "#002021", "dark": "#9cf1f6", "sepia": "#2b1700", "sepia-night": "#f5debe", "dark-oled": "#9cf1f6", "sepia-night-oled": "#f5debe" }, "usage": "Text on primary-container." }, { "name": "secondary", "value": { "light": "#8b5000", "dark": "#ffb873", "sepia": "#6b5b3e", "sepia-night": "#cfbe98", "dark-oled": "#ffb873", "sepia-night-oled": "#cfbe98" }, "usage": "Saffron accent (sepia: olive-brown). The tilework counterpart to primary; reserve for accents, never body text." }, { "name": "on-secondary", "value": { "light": "#ffffff", "dark": "#4a2800", "sepia": "#ffffff", "sepia-night": "#362c14", "dark-oled": "#4a2800", "sepia-night-oled": "#362c14" }, "usage": "Text on a secondary fill." }, { "name": "secondary-container", "value": { "light": "#ffdcbe", "dark": "#693c00", "sepia": "#eadfc4", "sepia-night": "#4d4228", "dark-oled": "#693c00", "sepia-night-oled": "#4d4228" }, "usage": "Peach fill: a selected FilterChip, and the disc behind a poet portrait (shows the initial when no portrait exists)." }, { "name": "on-secondary-container", "value": { "light": "#2c1600", "dark": "#ffdcbe", "sepia": "#231a05", "sepia-night": "#ebdcb7", "dark-oled": "#ffdcbe", "sepia-night-oled": "#ebdcb7" }, "usage": "Text and check-mark on secondary-container: selected chip label, poet initial. 7.2:1+ in every theme." }, { "name": "background", "value": { "light": "#fafdfc", "dark": "#191c1c", "sepia": "#f6ecd9", "sepia-night": "#1c1710", "dark-oled": "#000000", "sepia-night-oled": "#000000" }, "usage": "Window and splash background (res/values/colors.xml window_background mirrors light and dark)." }, { "name": "on-background", "value": { "light": "#191c1c", "dark": "#e0e3e2", "sepia": "#3a2e1e", "sepia-night": "#e6dac4", "dark-oled": "#e0e3e2", "sepia-night-oled": "#e6dac4" }, "usage": "Text on background." }, { "name": "surface", "value": { "light": "#fafdfc", "dark": "#191c1c", "sepia": "#f1e5ce", "sepia-night": "#241d14", "dark-oled": "#000000", "sepia-night-oled": "#000000" }, "usage": "Page ground behind lists, the reader column, top app bar and sheets." }, { "name": "on-surface", "value": { "light": "#191c1c", "dark": "#e0e3e2", "sepia": "#3a2e1e", "sepia-night": "#e6dac4", "dark-oled": "#e0e3e2", "sepia-night-oled": "#e6dac4" }, "usage": "Primary text on surface: poem verses, list headlines, the current breadcrumb. 10.6:1+ in every theme." }, { "name": "surface-variant", "value": { "light": "#dae4e4", "dark": "#3f4949", "sepia": "#e5d8bc", "sepia-night": "#3b3225", "dark-oled": "#111515", "sepia-night-oled": "#0f0c07" }, "usage": "Muted fill for variant surfaces (Material defaults: slider inactive track, chip disabled)." }, { "name": "on-surface-variant", "value": { "light": "#3f4949", "dark": "#bec8c8", "sepia": "#5a4c35", "sepia-night": "#ccbfa6", "dark-oled": "#bec8c8", "sepia-night-oled": "#ccbfa6" }, "usage": "Secondary text and icons: metre line, couplet summaries, setting notes, \"»\" separators, action icons. 5.6:1+ on surface and surface-container-highest in every theme." }, { "name": "surface-bright", "value": { "light": "#fafdfc", "dark": "#3f4242", "sepia": "#f8f0e0", "sepia-night": "#433a2d", "dark-oled": "#161717", "sepia-night-oled": "#17130d" }, "usage": "Brightest surface tone; OLED keeps it 46% of the way to black." }, { "name": "surface-dim", "value": { "light": "#d9dddc", "dark": "#191c1c", "sepia": "#dbd0b8", "sepia-night": "#1c1710", "dark-oled": "#000000", "sepia-night-oled": "#000000" }, "usage": "Dimmest surface tone." }, { "name": "surface-container-lowest", "value": { "light": "#ffffff", "dark": "#141616", "sepia": "#fffaf0", "sepia-night": "#17120c", "dark-oled": "#000000", "sepia-night-oled": "#000000" }, "usage": "Lowest container tone." }, { "name": "surface-container-low", "value": { "light": "#f3f7f6", "dark": "#212424", "sepia": "#f2e8d4", "sepia-night": "#241d14", "dark-oled": "#000000", "sepia-night-oled": "#000000" }, "usage": "Bottom sheet and elevated card ground (Material default for ModalBottomSheet)." }, { "name": "surface-container", "value": { "light": "#eef1f0", "dark": "#252828", "sepia": "#ece1ca", "sepia-night": "#2a2218", "dark-oled": "#010101", "sepia-night-oled": "#010101" }, "usage": "Default container tone: navigation bar, menus." }, { "name": "surface-container-high", "value": { "light": "#e8eceb", "dark": "#2f3333", "sepia": "#e6dac0", "sepia-night": "#352c21", "dark-oled": "#040505", "sepia-night-oled": "#050402" }, "usage": "Dialogs and dropdown menus." }, { "name": "surface-container-highest", "value": { "light": "#e2e6e5", "dark": "#3a3e3e", "sepia": "#e0d3b6", "sepia-night": "#40372b", "dark-oled": "#0d0f0f", "sepia-night-oled": "#100c08" }, "usage": "Filled Card ground: poet cards in the grid; Switch track when off." }, { "name": "outline", "value": { "light": "#6f7979", "dark": "#899393", "sepia": "#8c7a5c", "sepia-night": "#968a72", "dark-oled": "#899393", "sepia-night-oled": "#968a72" }, "usage": "1px borders: OutlinedTextField, unselected FilterChip outline in focus, Switch border when off. Sepia is 3.3:1 on surface, still above the 3:1 floor for control borders." }, { "name": "outline-variant", "value": { "light": "#cac4d0", "dark": "#49454f", "sepia": "#cac4d0", "sepia-night": "#49454f", "dark-oled": "#49454f", "sepia-night-oled": "#49454f" }, "usage": "Material 3 default, not overridden by any scheme (a faintly purple grey): HorizontalDivider and the unselected FilterChip border. Decorative only; never the sole boundary of a control." }, { "name": "error", "value": { "light": "#b3261e", "dark": "#f2b8b5", "sepia": "#b3261e", "sepia-night": "#f2b8b5", "dark-oled": "#f2b8b5", "sepia-night-oled": "#f2b8b5" }, "usage": "Material 3 default, not overridden. Load-failure and assistant error text on surface." }, { "name": "on-error", "value": { "light": "#ffffff", "dark": "#601410", "sepia": "#ffffff", "sepia-night": "#601410", "dark-oled": "#601410", "sepia-night-oled": "#601410" }, "usage": "Material 3 default. Text on an error fill." }, { "name": "downloaded", "value": { "light": "#2e7d32", "dark": "#81c784", "sepia": "#2e7d32", "sepia-night": "#81c784", "dark-oled": "#81c784", "sepia-night-oled": "#81c784" }, "usage": "ColorScheme.downloaded in Theme.kt: the CheckCircle beside a poet already saved on the device. Picked by surface luminance (<0.5 → light green). Always paired with the tick shape, never colour alone. 4.1:1+ on surface in every theme." }, { "name": "surface-tonal-3", "value": { "light": "#e5f1f0", "dark": "#212b2c", "sepia": "#e7d9c0", "sepia-night": "#33291b", "dark-oled": "#0b1112", "sepia-night-oled": "#120e09" }, "usage": "Derived, not declared: Material 3 tonal elevation 3dp (primary at 8.2% over surface). The bottom search bar's Surface on the poets screen." } ] }, "type": { "fonts": [ { "family": "Noto Naskh Arabic", "file": "fonts/NotoNaskhArabic.ttf", "weight": "400 700", "style": "normal" }, { "family": "Noto Nastaliq Urdu", "file": "fonts/NotoNastaliqUrdu.ttf", "weight": "400 700", "style": "normal" }, { "family": "Libron", "file": "fonts/Libron-Regular.ttf", "weight": "400", "style": "normal" }, { "family": "Libron", "file": "fonts/Libron-Bold.ttf", "weight": "700", "style": "normal" } ], "families": { "naskh": "\"Noto Naskh Arabic\", \"Noto Naskh\", serif", "nastaliq": "\"Noto Nastaliq Urdu\", \"Noto Naskh Arabic\", serif", "libron": "Libron, Georgia, \"Times New Roman\", serif" }, "groups": [ { "name": "Reading", "family": "naskh", "styles": [ { "name": "poem-naskh", "family": "naskh", "fontSize": "22px", "lineHeight": 1.8, "fontWeight": 400, "sample": "الا یا ایها الساقی ادر کأسا و ناولها", "usage": "The poem itself, default font. Size 14–40px in 2px steps (default 22); weight Regular / Medium / Semibold / Bold chosen by the reader; leading always 1.8× the size." }, { "name": "poem-nastaliq", "family": "nastaliq", "fontSize": "22px", "lineHeight": 2.4, "fontWeight": 400, "sample": "الا یا ایها الساقی ادر کأسا و ناولها", "usage": "The poem when the reader picks nastaliq. Leading 2.4× — nastaliq stacks diagonally and has deep descenders, so tighter leading clips the swashes. Same size and weight range as naskh." } ] }, { "name": "Interface — Persian & Urdu (Naskh)", "family": "naskh", "styles": [ { "name": "display-large", "fontSize": "57px", "lineHeight": "64px", "fontWeight": 400, "letterSpacing": "-0.25px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "display-medium", "fontSize": "45px", "lineHeight": "52px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "display-small", "fontSize": "36px", "lineHeight": "44px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "headline-large", "fontSize": "32px", "lineHeight": "40px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "headline-medium", "fontSize": "28px", "lineHeight": "36px", "fontWeight": 400, "letterSpacing": "0px", "usage": "A poet's initial inside the 84px portrait disc when no portrait loads.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "headline-small", "fontSize": "24px", "lineHeight": "32px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "title-large", "fontSize": "22px", "lineHeight": "28px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Top app bar titles (poem title, app name گنجور).", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "title-medium", "fontSize": "16px", "lineHeight": "24px", "fontWeight": 500, "letterSpacing": "0.15px", "usage": "Poet names on cards and rows; breadcrumbs.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "title-small", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "letterSpacing": "0.1px", "usage": "Section labels in the reading settings sheet, in primary.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "body-large", "fontSize": "16px", "lineHeight": "24px", "fontWeight": 400, "letterSpacing": "0.5px", "usage": "List item headlines and setting titles (Material default text).", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "body-medium", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 400, "letterSpacing": "0.25px", "usage": "Poem summary, list supporting text, empty states.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "body-small", "fontSize": "12px", "lineHeight": "16px", "fontWeight": 400, "letterSpacing": "0.4px", "usage": "Secondary notes in on-surface-variant: metre, couplet summaries, setting notes, source line, pin hint.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "label-large", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "letterSpacing": "0.1px", "usage": "Buttons, TextButtons and chip labels.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "label-medium", "fontSize": "12px", "lineHeight": "16px", "fontWeight": 500, "letterSpacing": "0.5px", "usage": "Small badges and captions.", "sample": "گنجور — خوانندهٔ شعر پارسی" }, { "name": "label-small", "fontSize": "11px", "lineHeight": "16px", "fontWeight": 500, "letterSpacing": "0.5px", "usage": "The \"AI-generated by Ganjoor\" note above a summary, in primary.", "sample": "گنجور — خوانندهٔ شعر پارسی" } ] }, { "name": "Interface — English (Libron)", "family": "libron", "styles": [ { "name": "en-display-large", "fontSize": "57px", "lineHeight": "64px", "fontWeight": 400, "letterSpacing": "-0.25px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "Search poems for “Hafez”" }, { "name": "en-display-medium", "fontSize": "45px", "lineHeight": "52px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "Search poems for “Hafez”" }, { "name": "en-display-small", "fontSize": "36px", "lineHeight": "44px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "Search poems for “Hafez”" }, { "name": "en-headline-large", "fontSize": "32px", "lineHeight": "40px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "Search poems for “Hafez”" }, { "name": "en-headline-medium", "fontSize": "28px", "lineHeight": "36px", "fontWeight": 400, "letterSpacing": "0px", "usage": "A poet's initial inside the 84px portrait disc when no portrait loads.", "sample": "Search poems for “Hafez”" }, { "name": "en-headline-small", "fontSize": "24px", "lineHeight": "32px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Material 3 default scale; carried for completeness, not used on any current screen.", "sample": "Search poems for “Hafez”" }, { "name": "en-title-large", "fontSize": "22px", "lineHeight": "28px", "fontWeight": 400, "letterSpacing": "0px", "usage": "Top app bar titles (poem title, app name گنجور).", "sample": "Search poems for “Hafez”" }, { "name": "en-title-medium", "fontSize": "16px", "lineHeight": "24px", "fontWeight": 500, "letterSpacing": "0.15px", "usage": "Poet names on cards and rows; breadcrumbs.", "sample": "Search poems for “Hafez”" }, { "name": "en-title-small", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "letterSpacing": "0.1px", "usage": "Section labels in the reading settings sheet, in primary.", "sample": "Search poems for “Hafez”" }, { "name": "en-body-large", "fontSize": "16px", "lineHeight": "24px", "fontWeight": 400, "letterSpacing": "0.5px", "usage": "List item headlines and setting titles (Material default text).", "sample": "Search poems for “Hafez”" }, { "name": "en-body-medium", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 400, "letterSpacing": "0.25px", "usage": "Poem summary, list supporting text, empty states.", "sample": "Search poems for “Hafez”" }, { "name": "en-body-small", "fontSize": "12px", "lineHeight": "16px", "fontWeight": 400, "letterSpacing": "0.4px", "usage": "Secondary notes in on-surface-variant: metre, couplet summaries, setting notes, source line, pin hint.", "sample": "Search poems for “Hafez”" }, { "name": "en-label-large", "fontSize": "14px", "lineHeight": "20px", "fontWeight": 500, "letterSpacing": "0.1px", "usage": "Buttons, TextButtons and chip labels.", "sample": "Search poems for “Hafez”" }, { "name": "en-label-medium", "fontSize": "12px", "lineHeight": "16px", "fontWeight": 500, "letterSpacing": "0.5px", "usage": "Small badges and captions.", "sample": "Search poems for “Hafez”" }, { "name": "en-label-small", "fontSize": "11px", "lineHeight": "16px", "fontWeight": 500, "letterSpacing": "0.5px", "usage": "The \"AI-generated by Ganjoor\" note above a summary, in primary.", "sample": "Search poems for “Hafez”" } ] } ] }, "spacing": { "note": "Compose dp values as written in the screens; 1dp = 1px here.", "tokens": [ { "name": "space-2", "value": "2px", "usage": "Hairline gaps: CircularProgressIndicator stroke width." }, { "name": "space-4", "value": "4px", "usage": "Icon-to-text gap (pin mark beside a name), header bottom padding, summary top padding." }, { "name": "space-6", "value": "6px", "usage": "Vertical padding around each couplet." }, { "name": "space-8", "value": "8px", "usage": "The default gap: chip spacing, settings sheet rows, card internals, top list padding." }, { "name": "space-12", "value": "12px", "usage": "Poet grid gutters and screen side padding on lists; poet card padding; settings toggle top margin." }, { "name": "space-16", "value": "16px", "usage": "List bottom padding; empty-state padding; gap before the source line." }, { "name": "space-20", "value": "20px", "usage": "Reader column side padding; settings sheet side padding." }, { "name": "space-24", "value": "24px", "usage": "Space above the summary and the previous/next poem row." }, { "name": "space-32", "value": "32px", "usage": "Bottom padding of the reader and the settings sheet." } ] }, "radius": { "note": "The app sets no shapes of its own; these are the Material 3 shape scale the components use.", "tokens": [ { "name": "radius-xs", "value": "4px", "usage": "OutlinedTextField (Material extraSmall)." }, { "name": "radius-sm", "value": "8px", "usage": "FilterChip (Material small)." }, { "name": "radius-md", "value": "12px", "usage": "Card — poet cards in the grid (Material medium)." }, { "name": "radius-lg", "value": "16px", "usage": "Material large; unused today." }, { "name": "radius-xl", "value": "28px", "usage": "Top corners of ModalBottomSheet and AlertDialog (Material extraLarge)." }, { "name": "radius-full", "value": "9999px", "usage": "Buttons, TextButtons, IconButton ripples, portrait discs (CircleShape)." } ] }, "size": { "note": "Fixed component sizes from the screens (dp = px).", "tokens": [ { "name": "icon-pin", "value": "16px", "usage": "The pin mark beside a pinned poet." }, { "name": "icon-inline", "value": "18px", "usage": "Share glyph inside a TextButton; download progress ring." }, { "name": "icon-small", "value": "20px", "usage": "Couplet options chevron; small progress rings." }, { "name": "icon", "value": "24px", "usage": "Default Material icon size in app bars and list rows." }, { "name": "touch-compact", "value": "32px", "usage": "The couplet options IconButton." }, { "name": "avatar-row", "value": "44px", "usage": "Poet portrait disc in list view." }, { "name": "touch", "value": "48px", "usage": "IconButton and the non-interactive download tick box, so ticks and arrows line up." }, { "name": "avatar-card", "value": "84px", "usage": "Poet portrait disc on a grid card." }, { "name": "poet-grid-min", "value": "132px", "usage": "Minimum column width of the adaptive poet grid." } ] } }