You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AccentColor is configured correctly but not honoured — system controls fall back to blue #102
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColoris set in the build settings.
Assets.xcassets/AccentColor.colorset/Contents.jsondoes hold the brand green, with a correct
dark-appearance variant.
Yet links and system controls render system blue, not brand green.
Setting .tint(ILColor.primary) on RootView fixes it for the hierarchy below that point, and #101
does exactly that. But that is a workaround layered over an unexplained cause, not a fix.
Why it matters beyond links
.tint does not cross into sheet content — proven while answering #80's deep-link question: a
sheet presented from InterlinedListApp inherited the colour scheme but kept a system-blue "Cancel"
until its content was tinted directly.
So every independently-presented surface needs its own .tint, and any one that is missed silently
reverts to blue. A correctly-honoured global accent would cover all of them at once. Today the app
has an unknown number of un-tinted sheets.
Worth investigating
Why the global accent is ignored. Candidates: the colorset name not matching what the build
setting expects, the asset not being compiled into the right catalog, or Info.plist / UIWindow level configuration overriding it.
Whether UIView.appearance().tintColor (set alongside the existing UINavigationBar.appearance() configuration in InterlinedListApp.configureNavigationBarAppearance())
would cover UIKit-hosted surfaces the SwiftUI .tint cannot reach.
Audit every .sheet / .fullScreenCover in Views/ for a missing tint once the root cause is
known — if the global accent can be made to work, they can all drop their local tints instead.
Acceptance criteria
The cause is identified and written down (even if the conclusion is "the global accent cannot
work here, tint explicitly").
No surface renders system blue where brand green is intended, in both appearances.
If explicit tinting stays the answer, there is one documented place to add it for a new sheet.
Low urgency — #101 makes the visible case correct. This is about not having an unexplained
workaround and an unaudited set of sheets.
The asset, the build setting and Info.plist were all correct. Verified against the built
product rather than the source: InterlinedList.app/Info.plist carries NSAccentColorName = AccentColor, assetutil --info Assets.car shows the colour compiled in with both appearance
variants, and UIColor(named: "AccentColor") resolves to brand green at runtime.
The app was destroying its own accent at launch.configureNavigationBarAppearance() ran from InterlinedListApp.init(), and these two lines are the trigger:
Materialising a bar-button state appearance that early resolves UIKit's default bar-button
styling before UIApplication has adopted the accent asset. UIKit then caches system blue as the process tint for the rest of the launch, so UIColor.tintColor and Color.accentColor stay blue
permanently.
Narrowed statement by statement: constructing UIBarButtonItemAppearance() without touching .normal, setting UINavigationBar.appearance().tintColor, assigning a UINavigationBarAppearance
to the proxy, and reading UINavigationBar.appearance() are each harmless alone. A differential
control app with a red accent honoured it on the same Xcode/simulator — and still did after being
handed this app's Info.plist verbatim — so neither the custom plist nor the iOS version was ever
implicated.
UIView.appearance().tintColor (candidate #2 in this issue) was not needed; the real accent
covers everything it would have.
The fix
configureNavigationBarAppearance() moved to AppDelegate.application(_:didFinishLaunchingWithOptions:).
Both hierarchy-wide .tint workarounds are gone. AppAccentColorTests guards it — the two
process-tint assertions genuinely fail when the old init() is restored.
Sheet audit
64 .sheet presentations across 22 files; zero .fullScreenCover. Exactly one carried a tint
(the deep-link sheet); every other relied on RootView's tint reaching it — which worked for sheets
below RootView and not for the one presented above it. With a working accent, a new sheet now
needs nothing. Remaining .tint call sites are legitimately local (swipe-action backgrounds, a ProgressView on a dark overlay) and were left alone. The convention is documented in CLAUDE.md.
Bonus bug fixed
The deep-link sheet's explicit .tint(ILColor.link) was also a contrast bug: ILColor.link is #184860, identical to the masthead, so that sheet's "Cancel" was invisible. Screenshot-confirmed.
Deliberate colour decision
Links move from teal #184860 to green #2FA877 — app-wide, since the accent reaches everything.
Screenshots of both were compared side by side and green was chosen deliberately: it is what the
asset holds, and green is already the action colour in 30+ places versus 3 for link.
Not verified
No authenticated surface was seen rendered — feed, lists, documents, settings and the ~60 sheets they
present. The mechanism is process-wide and test-asserted, so they should follow, but that is
inference. Only the login screen and the deep-link sheet were observed directly, in both appearances.
Activity
Adron commentedon Sep 17, 2026
Fixed in #113, now merged. Closing.
Root cause — not what this issue guessed
The asset, the build setting and
Info.plistwere all correct. Verified against the builtproduct rather than the source:
InterlinedList.app/Info.plistcarriesNSAccentColorName = AccentColor,assetutil --info Assets.carshows the colour compiled in with both appearancevariants, and
UIColor(named: "AccentColor")resolves to brand green at runtime.The app was destroying its own accent at launch.
configureNavigationBarAppearance()ran fromInterlinedListApp.init(), and these two lines are the trigger:Materialising a bar-button state appearance that early resolves UIKit's default bar-button
styling before
UIApplicationhas adopted the accent asset. UIKit then caches system blue as theprocess tint for the rest of the launch, so
UIColor.tintColorandColor.accentColorstay bluepermanently.
Narrowed statement by statement: constructing
UIBarButtonItemAppearance()without touching.normal, settingUINavigationBar.appearance().tintColor, assigning aUINavigationBarAppearanceto the proxy, and reading
UINavigationBar.appearance()are each harmless alone. A differentialcontrol app with a red accent honoured it on the same Xcode/simulator — and still did after being
handed this app's
Info.plistverbatim — so neither the custom plist nor the iOS version was everimplicated.
UIView.appearance().tintColor(candidate #2 in this issue) was not needed; the real accentcovers everything it would have.
The fix
configureNavigationBarAppearance()moved toAppDelegate.application(_:didFinishLaunchingWithOptions:).Both hierarchy-wide
.tintworkarounds are gone.AppAccentColorTestsguards it — the twoprocess-tint assertions genuinely fail when the old
init()is restored.Sheet audit
64
.sheetpresentations across 22 files; zero.fullScreenCover. Exactly one carried a tint(the deep-link sheet); every other relied on
RootView's tint reaching it — which worked for sheetsbelow
RootViewand not for the one presented above it. With a working accent, a new sheet nowneeds nothing. Remaining
.tintcall sites are legitimately local (swipe-action backgrounds, aProgressViewon a dark overlay) and were left alone. The convention is documented inCLAUDE.md.Bonus bug fixed
The deep-link sheet's explicit
.tint(ILColor.link)was also a contrast bug:ILColor.linkis#184860, identical to the masthead, so that sheet's "Cancel" was invisible. Screenshot-confirmed.Deliberate colour decision
Links move from teal
#184860to green#2FA877— app-wide, since the accent reaches everything.Screenshots of both were compared side by side and green was chosen deliberately: it is what the
asset holds, and green is already the action colour in 30+ places versus 3 for
link.Not verified
No authenticated surface was seen rendered — feed, lists, documents, settings and the ~60 sheets they
present. The mechanism is process-wide and test-asserted, so they should follow, but that is
inference. Only the login screen and the deep-link sheet were observed directly, in both appearances.