Repository navigation
Releases: MartinSA04/StudyCompanion
Release list
v4.2.0 — phone polish: touch targets, launch screens, installed-app nav
Polish pass over the installed-app surface on iPhone.
Touch targets (#7)
--control-h was 38px, under the 44px minimum Apple's HIG and Material both set — while .nav-link already honoured 44px on mobile, so the icon controls were an inconsistency rather than a considered density.
Bumped under @media (pointer: coarse): keyed on the pointer, not the viewport, because a narrow desktop window is still mouse-driven and 38px is the deliberate marginalia density there. One token covers topbar buttons, the theme toggle, stepper controls, search palette rows and the flashcard buttons; .sidebar-close loses its magic 40px and sizes off the token too.
Launch screens (#7)
An installed guide showed a blank screen from tap to first paint. iOS has no manifest-driven splash — WebKit's manifest support is still partial, background_color doesn't produce one, and any image whose media query doesn't match the launch window exactly is ignored — so this is a table of 19 device classes × 2 orientations, rendered as a field of the course accent with the >_ mark centred.
One table generates both the link tags and the build's render list, so a tag can't outlive its file — the failure that would silently reintroduce the blank launch.
Drawer scroll containment (#7)
Reaching the end of a long nav in the mobile drawer handed the remaining momentum to the article behind it. overscroll-behavior: contain.
Installed-app navigation (#6)
course.hubUrl points at a different origin than the guide, so it falls outside the PWA scope: tapping Alle kurs in the installed app handed the URL to an in-app browser sheet instead of navigating, which read as the app breaking. Hidden under (display-mode: standalone), scoped to that one link so the course nav is untouched. It still shows in every browser tab.
Also
Manifest id, so app identity doesn't ride on start_url.
Launch images encode at compressionLevel: 9 (24 kB rather than 84 kB on the largest). palette: true would reach 8 kB but was rejected: it turned the build from 4.1s into 11.9s, and that cost would land in every consuming repo's CI on every deploy.
Upgrading
No schema change — SCHEMA_VERSION stays 4, no migration needed. Bump your pin to #v4.2.0 and run pnpm install. The launch images and icons are generated from course.yaml's accent at build; nothing to author.
v4.1.0 — app icons, share card, installed-app safe area
Icons — the home-screen tile no longer reads as a black box (#4)
rasterizeIcons used to resize one SVG for four targets whose framing requirements contradict each other, so a single geometry had to be wrong somewhere. Four mechanical defects fixed:
- No safe area. Artwork sat at a 6.25% margin; the iOS squircle cuts inside that, so the keyline ran into the edge and the tile read over-zoomed.
- Maskable icon was clipped. Frame corners sat at 62% radius against Android's 40% limit.
- Wrong black.
#0b0e14is a cool blue-black; DESIGN.md requires warm Flexoki neutrals. - Accent was invisible. Six courses differed only by a 5px hairline at 60px.
The mark is now knocked out of a field of the course accent (via the existing contrastText, so a pale accent gets a dark mark automatically), in two framings: bleed for the targets iOS and Android mask, rounded for the unmasked manifest any icons and the tab favicon.
No dark/tinted variant is possible for web-app icons — it's a native-app asset-catalog feature, still undocumented for PWAs on iOS 26. Tinted mode does apply, flattening to luminance, which is why a dark ground with a mid-luminance accent mark was rejected.
Also drops rel="mask-icon" / safari-pinned-tab.svg, ignored since Safari 15.
Share card (#4)
og-image.png at 1200×630 replaces the transparent square icon, and twitter:card rises to summary_large_image. Mark only, no per-page text: typesetting through sharp means librsvg + fontconfig and glyph metrics that vary by build machine. Per-page text remains on ROADMAP, rescoped to exactly that.
Installed app: topbar was unreachable (#3)
With viewport-fit=cover + black-translucent, the standalone web view is laid out from y=0, so the sticky topbar pinned under the status bar and Dynamic Island and its controls were untappable. Safari never showed it. Fixed at the token: --safe-top feeds both the bar's padding and --topbar-h, so all seven offsets derived from that token stay correct.
Releases are one commit now (#2)
course-template/pnpm-lock.yaml recorded a github:…#vX.Y.Z specifier that pnpm resolves against the remote, so it could only be regenerated after the tag was pushed — making every release two commits whose first was red by construction, 13 times over. The template now ships no lockfile.
Enforcement got stronger, not weaker: release.test.ts asserts the template pin equals the version the tree declares, caught at the release commit rather than one commit later. This is the first tag in the repo's history with a green CI run — ci.yml runs on tags again, and the hub deploy has its pnpm test gate back.
Upgrading
No schema change — SCHEMA_VERSION stays 4, no migration needed. Bump your pin to #v4.1.0 and run pnpm install. Your icons and share card are regenerated from course.yaml's accent at build; nothing to author.