Add a Stevenson green and gold theme - #19
Open
ShankarK2009 wants to merge 3 commits into
Open
ShankarK2009 wants to merge 3 commits into
ShankarK2009 wants to merge 3 commits into
Conversation
Add a Theme picker to Settings alongside the existing color scheme and time format controls. Stevenson is the default; Classic restores the stock iOS palette the app shipped with. Green and white carry the design. Measured against WCAG, #1B5E20 and white read at 7.9:1 in both directions, but gold reaches only 3.3:1 on white and 2.4:1 on green — so gold can never be text or an icon here. That constraint sets the hierarchy: green does the structural work (tint, controls, the selected tab, the hero dial's progress arc), and gold is used strictly as a fill under near-black ink (5.6:1), where it gets exactly one job — marking the block happening now. Dark mode substitutes lightened values. #1B5E20 falls to roughly 1.6:1 on a dark background, so the green becomes #35A83F (5.5:1) and the gold #C9992B. The dial's gold track also takes less alpha there: the wash that reads as cream over white muddies into brown over black and starts competing with the arc it sits behind. A theme repaints chrome only. The colors that flag an abnormal schedule are information rather than branding, so the Late Arrival, Early Dismissal, passing period, override, and destructive colors are left untouched in both themes. Route the ID and Lunch tabs through the theme as well; their accents were previously hardcoded green regardless of any preference. The ID card keeps its own crest-sampled palette — it emulates printed stock, does not follow dark mode, and its lighter print gold carries ink at 7.0:1 against the brand gold's 5.6:1. Persist the choice in UserConfig. Blobs written before themes existed decode as Stevenson, matching a fresh install rather than pinning upgraders to Classic.
…ance Follows the stevenson.space treatment of the same two colours. The theme was carrying its identity in small accents on grey and white surfaces; this puts the colour where the eye lands first and stops each appearance from falling back to a colour it cannot actually use. Swap the accent instead of picking one. Green reads at 7.9:1 on white and dies at 1.6:1 on a dark background; gold does the reverse, failing at 3.3:1 on white and clearing 6.5:1 on dark. So light mode accents in green and dark mode accents in gold, and neither appearance is asked to carry a colour that cannot hold text there. Add the hero band: the day header and the countdown now sit in a field of school green, curved off where the day's cards begin. Dark mode keeps a green band rather than a neutral one — deep enough to read as a dark surface at 1.5:1 against black, but the screen never goes grey. The countdown gets a disc punched out of the band, matching the system appearance so its text stays correct, with the ring pulled well inside: the arc is school green, and school green on the green band is the same colour twice over. The track takes whichever school colour the arc is not wearing, so the ring reads as green and gold together in both. Introduce a light gold for use on the band. Brand gold clears only 2.4:1 against green, which rules it out entirely, but lightening it to #E8C560 reaches 4.7:1 — that single value is what lets gold appear on green at all, and it carries the status-screen glyphs and the header badges. Semantic colours stay semantic. Where the band would swallow one, the fix reinforces its shape rather than repainting it: an Early Dismissal capsule clears only 2.2:1 against green, so it keeps its red fill and gains a white border. The passing-period banner keeps its orange on an opaque card, since a 12% wash would vanish into the green. Both resolve to the old rendering under Classic, which is unchanged throughout. Extend the band to the weekend, break and summer screens, so a non-school day gets the same header rather than an icon floating on grey.
The band read as the screen's header but stopped at the safe-area inset, leaving a grey lid above it. It now runs to the top of the screen. The colour under the clock is not the band's own green. iOS draws the status bar in black in light mode and offers no way to change that outside a navigation bar — a real bar with `toolbarColorScheme(.dark)` no longer reaches the status bar on iOS 26, and `UIHostingController` does not forward `childForStatusBarStyle`, so neither route works. Full band green would carry the clock at 2.3:1. The strip is instead one step up the same green ramp, at 4.1:1 against a 3:1 bar for text that bold, and a short gradient eases it down to the band across the empty space beneath, so the two read as one field. Dark mode's clock is white, so there the strip *is* the band and the join is invisible. Classic resolves the strip to `clear` and the gradient to clear-on-clear, leaving the screen exactly as it shipped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a Theme picker to Settings → Appearance, next to the existing color scheme and time format controls. Stevenson is the default; Classic restores the stock iOS palette the app shipped with.
Modelled on how stevenson.space handles the same two colors: a green hero band, and an accent that changes with the appearance.
The accent swaps rather than being picked
Contrast rules out any single accent:
#1B5E20on white#1B5E20on a dark background#B38825on white#C9992Bon a dark backgroundGreen reads on white and dies on black; gold does the reverse. So the app accents in green in light mode and gold in dark mode, and neither appearance is asked to carry a color that cannot hold text there.
The hero band
The day header and the countdown now sit in a field of school green, curved off where the day's cards begin — extended to the weekend, break and summer screens too, so a non-school day gets a real header instead of an icon floating on grey.
Dark mode keeps a green band rather than a neutral one: deep enough to read as a dark surface (1.5:1 against black) while never letting the screen go grey.
The countdown gets a disc punched out of the band, matching the system appearance so
.primary/.secondarystay correct on it. The ring is pulled well inside the disc — the arc is school green, and school green on the green band is the same color twice over. The track takes whichever school color the arc isn't wearing, so the ring reads as green and gold in both appearances.The light gold
Brand gold clears only 2.4:1 against green, which rules it out on the band entirely. Lightening it to
#E8C560reaches 4.7:1 — that one value is what lets gold appear on green at all, and it carries the status-screen glyphs and the header badges.Semantic colors stay semantic
Late Arrival purple, Early Dismissal red, passing-period orange, the override badge and destructive red are information, not branding, and are untouched in both themes. Where the band would swallow one, the fix reinforces its shape rather than repainting it:
Both resolve to the old rendering under Classic.
Notes for review
Two judgment calls worth a look:
The ID card deliberately keeps its own crest-sampled palette. It emulates printed stock, doesn't follow dark mode, and its lighter print gold carries ink at 7.0:1 versus the brand gold's 5.6:1 — moving it onto the brand values would have cost real legibility. The two greens are close enough to read as the same school green.
Verification
swift teston both packages: 185 + 103 tests pass, including a new assertion that a pre-theme config blob decodes as Stevenson and that the preference round-trips.mainin each.