main has moved on since this branch opened, and most of what it carried has been
answered better there:
- the reading settings no longer need a fallback to the sheet, because they fold
the columns away and take the room that frees (
|
||
|---|---|---|
| .. | ||
| assets | ||
| components | ||
| wireframes | ||
| README.md | ||
| tokens.json | ||
Ganjoor design system
This folder holds the app's design system, extracted from its code:
tokens.json: colours for all six themes, type styles, spacing, radii and sizes.components/: usage guidelines for each component, with a static preview.assets/: the logo and icons as SVG.wireframes/: the tablet and foldable layout, state by state.
The font files referenced in tokens.json (fonts/…) are the app's own, in app/src/main/res/font/, and the store screenshots are in fastlane/metadata/android/fa/images/. The previews use CSS variables named after the tokens. They render in the published design system artifact, which generates those variables from tokens.json.
Ganjoor is a quiet, long-form reader for Persian poetry, made for Persian, Urdu and Arabic script. The poem is the interface: everything else gets out of its way, says plainly what it does, and works offline. The palette comes from Persian tilework, turquoise with saffron accents, alongside warm paper tones for long sessions.
Built on Material 3 (Jetpack Compose). Tokens follow the Material colour roles one to one, so primary here is MaterialTheme.colorScheme.primary in the app.
Content fundamentals
- Persian first. The interface defaults to Persian whatever the phone's locale, and also speaks Urdu and English. The app is called گنجور in every language. Languages are named in their own script (فارسی · اردو · English).
- Right-to-left, always. The whole interface lays out and navigates RTL, even when the UI language is English. Directional icons mirror.
- Plain, specific, honest. Say what happened and what to do next, without blaming the reader: "This isn't downloaded. Turn off offline mode, or download it first." is right; "Network error" is not. A setting's note says when it applies: "Applies to the dark themes; saves power on OLED screens".
- Sentence case, no exclamation marks, no emoji. Labels are short verbs or nouns: Save this passage, Copy, Share, Download every poet. A state replaces the verb: Saved.
- Credit and disclose. AI text is always labelled: "AI-generated by Ganjoor, not by the poet". The app is unofficial and says so in About. It is never presented as ganjoor.net's own.
- Give the reader something useful. Listings show each poem's opening line under its title, because "Ghazal 237" tells you nothing.
Visual foundations
Colour and themes
Six themes, all the same roles. Light and Dark use turquoise primary with saffron secondary. Sepia and Sepia night are aged-paper schemes with walnut primary; the night one is dark without a blue cast. OLED black isn't a separate palette. It is a flag on either dark theme that moves only the surfaces towards black (in Oklab) and leaves text and accents exactly as they are. That gives the two themes Dark · OLED black and Sepia night · OLED black.
- Page ground is
surface. Primary text ison-surface; secondary text and icons areon-surface-variant. primaryis for what you can tap or what is active: tappable breadcrumbs, TextButtons, section labels, a saved bookmark, the pin mark. It is never used for running text.- Selected chips and portrait discs use
secondary-containerwithon-secondary-container. - Poet cards use
surface-container-highest; sheets usesurface-container-low; the bottom search bar usessurface-tonal-3. downloaded(green) appears only with the check-circle, so the state is never shown by colour alone.- Every text pair named in a token's notes meets 4.5:1 in all six themes. Sepia's
outlineis 3.3:1 onsurface, which passes for borders only.
Typography
- Poems are always Noto Naskh Arabic or Noto Nastaliq Urdu, whatever the UI language. Use
poem-naskhby default andpoem-nastaliqwhen the reader picks it. The reader chooses a size from 14 to 40px (default 22) and a weight of Regular, Medium, Semibold or Bold, because thin naskh strokes wash out on a lit screen, especially in dark themes. Leading is 1.8× for naskh and 2.4× for nastaliq, whose diagonal stacking and deep descenders would otherwise clip. - The Persian and Urdu interface uses the Material 3 type scale in Naskh (
title-medium,body-small…). - The English interface uses the same scale in Libron, a reading serif (
en-title-medium…). Libron never sets a poem.
Layout and spacing
Values are the Compose dp values written in the code (1dp = 1px): space-20 for the reader column and settings sheet sides, space-12 for list sides and grid gutters, space-8 as the default gap, and space-6 above and below each couplet. Touch targets are touch (48px). The poet grid is adaptive with columns of at least poet-grid-min.
Couplets stack on a phone: the first hemistich aligns to the start, the second to the end. Prose (Golestan, Nowruznameh) is justified. On large screens the hemistichs sit side by side (see ColumnBrowser).
One-handed reach: the poets search lives in a bottom bar, and the settings open as a bottom sheet.
Shape, elevation, motion
Shapes are Material's: radius-sm for chips, radius-md for cards, radius-xl for sheet tops and radius-full for buttons and portrait discs. There are no drop shadows. Elevation is tonal: surface containers step up in tone. Motion is Material's default. The one custom transition is ColumnBrowser's column slide, 400ms emphasized-decelerate.
States
Pressed and hovered states use Material's state layers. A focus ring is 2px primary with a 2px offset, at least 3:1 on every surface. Show a selection with a fill (a chip or the selected pane row) as well as a check mark or a change of word.
Imagery
Poet portraits come from Ganjoor and are cropped into a circle on secondary-container. The poet's initial sits underneath, so a missing portrait never leaves a hole. There are no other illustrations.
Iconography
Material Icons in the filled style, at 24px, tinted with colour roles (see the Icons group). Use the standard Android share glyph wherever there is sharing, because people recognise it before reading the label. The brand mark is the eight-pointed khatam star (see Logos). There is no wordmark: گنجور is set in Naskh.
Large screens
Tablets and unfolded foldables use ColumnBrowser. Tapping a poet collapses the home grid into a narrow poets column on the far right (portrait with the name underneath). To its left come the poet's books, then the chapters or poems of the open book, each column scrolling on its own. Older columns narrow as new ones open, so the poem stays near the middle, and a top-bar button hides the columns when the reader wants to focus on the poem. The dictionary and reading settings open in a panel on the left, beside the poem rather than over it. Phones are unchanged.