Sakīna Canvas — Consolidated Design Review & Adjudicated Resolutions
July 2026. Four parallel reviews (submission loop, schedule/time, comms/Today variants, appointments/onboarding/coach) audited the canvas after the F1–F5 screens (newer, built from the Apr–May coach-feedback synthesis) were added alongside the older sections (00–07). Findings below, each with an adjudicated resolution — these are decisions, not options. F screens are the source of truth wherever old and new conflict.
Status legend: ☐ todo · ✓ applied
A. Data contradictions (hard bugs — fix first)
A1 ✓ Duplicate revoke countdown
SakRecSubmitted (sak-recording.jsx:249-251) shows "Revoke window open · 9:12 left";
SakSubmissionPending (sak-feedback.jsx:361-375) shows "6:52 left" for the same
submission.
Resolution: Remove the inline revoke line from SakRecSubmitted entirely. Its
"View my submission" CTA is the sole path; SakSubmissionPending owns all revoke UI.
Keep the pending screen's countdown at 6:52.
A2 ✓ Week 7 lifecycle contradiction
SakSubmissionFeedback eyebrow says "Week 7 · Reviewed" (sak-feedback.jsx:198) while
the SakSubmissions archive row for week 7 says status "practiced"
(sak-extras.jsx:198). SakRecPractice is also scoped to Week 7.
Resolution: Single timeline: week 7 = reviewed (feedback just arrived, not yet
practiced — matches the feedback screen and practice screen). Change the archive row
for week 7 to status: "reviewed". Weeks 1–6 in the archive stay practiced/heard
as-is. Additionally add a week 8 row with status: "review" at the top of the
archive (the in-flight submission SakSubmissionPending tracks), so the archive and
the live loop agree. SubStatusPill (sak-extras.jsx:307-317) currently renders
review and reviewed nearly identically — differentiate: review = muted/ink tint
("In review"), reviewed = warm/gold tint ("Feedback ready").
A3 ✓ Schedule day disagreement
Sessions tab (sak-schedule.jsx:17-23) puts all five week-8 items on Tuesday;
SakWeekAtGlance (sak-feedback.jsx:486-498) spreads the same sessions across
Mon/Tue/Thu/Sun.
Resolution: F2's week layout is canonical: Mon 10:00 AM class "Idghām with
ghunnah"; Tue 2:00 PM "Sisters' Reading Circle" + Tue 7:00 PM "Idghām review &
practice"; Thu 9:00 PM "Drop-in Q&A"; Sun 11:59 PM submission deadline. Update the
Sessions tab's Tuesday timeline to show only Tuesday's items (2:00 PM QRC, 7:00 PM
class) plus a quiet trailing "Sunday · submission deadline" reference row is NOT
needed — the day-strip owns other days. Update SakToday's "Sessions today" rows
(sak-core.jsx:75-83) to the same Tuesday facts (2:00 PM QRC live-now can stay as the
live example; second row = 7:00 PM class — adjust times/titles to match). The
deadline on Today ("Due tonight · 11:59 PM EST", sak-core.jsx:621) becomes
"Due Sunday · 11:59 PM".
A4 ✓ Coach identity: Rania vs Amina
F5 books the 1:1 with "Ust. Rania" (sak-appointments.jsx:77,154,207) while 25+
references everywhere else (onboarding, profile, recording, coach app) say Ust. Amina,
and SakCoachSchedule (sak-coach.jsx:346) puts Sarah's recurring 1:1 on Amina's own
schedule.
Resolution: One coach. Sarah's coach is Ust. Amina for both async feedback and
the Year-2 one-to-one. Rename Rania→Amina in sak-appointments.jsx (booking coach card
becomes "Ust. Amina · Your coach" — keep the quiet "Change" link; changing coach is a
legitimate affordance). The one legitimate Rania reference stays:
SakCoachStudent's shared note "Ust. Rania · Week 6 · one-to-one" (sak-coach.jsx:302)
— it demonstrates the cross-coach shared-notes requirement (a student may see a
substitute coach); leave it.
A5 ✓ Timezone math between booking and coach schedule
Student books "Tuesdays 8:20 PM Toronto (EDT)"; coach schedule shows the same slot
"4:20 PM Cairo (EEST)". EDT→EEST is +7h, so 8:20 PM Toronto = 3:20 AM Cairo. Wrong.
Resolution: Change the student slot times to morning: booking grid becomes Tuesday
9:20 AM (selected) with neighbouring slots 9:00/9:40/10:00 etc., CTA copy "Book
Tuesdays 9:20 AM · all 15 weeks". SakAppointmentDetail time = "Tue · 9:20 AM ·
20 min". Coach side stays 4:20 PM Cairo (9:20 AM EDT + 7h = 4:20 PM EEST ✓).
B. Structural consolidation
B1 ✓ Today exists 7 ways — reduce to 1 component + named states
Canonical SakToday (sak-core.jsx), SakTodayRest (sak-states.jsx:18-95),
SakTodayCountdown (sak-feedback.jsx:574-623), plus shoot-out B/C/D
(sak-shootout.jsx). Glass reintroduces the "On track" pill banned by AUDIT rule R3.
Resolution: (a) Remove section 07 from the canvas (main.jsx) and move
sak-shootout.jsx to _archive/ — Manuscript (SakToday) is canonical per AUDIT.md;
drop the <script> tag for sak-shootout.jsx from index.html. (b) Keep
SakTodayRest and SakTodayCountdown as screens but visually align them to the
canonical hero anatomy: same strip placement, same CTA slot conventions (countdown's
"Add start date to calendar" stays its primary). Label them in main.jsx section 06 /
F4 as "Today — state: rest day" / "Today — state: pre-semester" so it reads as one
screen with states.
B2 ✓ Two "my week" surfaces
Sessions tab and SakWeekAtGlance both answer "what's on this week?"; Week-at-a-glance
is an orphan (nothing routes to it).
Resolution: Keep both, define the relationship: the Sessions tab's header
calendar icon (sak-schedule.jsx:30) opens Week at a glance. Add a canvas
annotation (DCPostIt or artboard sublabel) stating this routing on both artboards.
Do NOT attempt a full merge in the mockup — the day timeline (zoom-in) and week list
(overview) are two density levels of one surface; the spec will document that.
B3 ✓ Timezone treatment sweep
F2's banner ("All times shown in Toronto (EDT)") is the only correct treatment; bare "EST" strings survive in sak-schedule.jsx:290,300,301 (notif rows), sak-profile.jsx:238,246, sak-states.jsx:150, sak-core.jsx:621. Resolution: Delete every per-item "EST"/"EDT" suffix. Profile's timezone field becomes "Toronto · Eastern (EDT)" (one account = one city; Toronto is canonical, drop "EST · New York"). Notification rows show bare local times (the sheet inherits the app-wide local-time rule). Add the F2-style one-line zone banner to the Sessions tab header area (under the day strip, quiet, same copy pattern). Cohort line (sak-profile.jsx:246) becomes "Tuesday 2 PM local".
B4 ✓ Announcements exist in 3 places
Board (sak-comms.jsx), notif-sheet announcement rows (sak-schedule.jsx:301), settings toggle default OFF (sak-settings.jsx:52). Same schedule-change fact hardcoded twice with different copy. Resolution: (a) Settings "Announcements" toggle defaults ON. (b) Align the duplicated copy: both the board row and the notif row say "Thursday's Level Class moved to 11:00 AM". (c) The notifications sheet is the inbox; announcement-type rows deep-link to the board. Annotate this routing on the artboards. Keep both screens.
B5 ✓ "Message your coach" has 3 labels
"Send a question" (SakCoach, sak-extras.jsx:76-79), "Message" (SakProfile coach panel,
sak-profile.jsx:104-113), "Write to your coach…" (thread composer).
Resolution: Standardize the CTA verb to "Message" on both SakCoach (primary
CTA becomes "Message Ust. Amina") and Profile's coach panel. Composer placeholder
stays. Both route to SakMessageThread.
C. Orphaned screens / dead ends
C1 ✓ Announcements + Report-issue have zero entry points
Resolution: (a) Add an "Announcements" row to SakNotifSheet header area — a
quiet "megaphone" row pinned above the New group ("Announcements · 1 pinned" with
chevron), linking to the board. (b) In SakProfile's Support section
(sak-profile.jsx:138-145), rename "Contact support" to "Report an issue" (it opens
the SakReportIssue sheet — its auto-attached-context design supersedes a generic
contact row). Keep "Help center" and "Resources".
C2 ✓ Appointments flow is an orphan
Nothing on Today/Sessions routes to SakBookAppointment/SakAppointmentDetail.
Resolution: Add a "One-to-one" row to the Sessions tab's Tuesday timeline
(the booked 9:20 AM slot, type chip "1:1", tinted like Hours) that drills to
SakAppointmentDetail. Add an artboard annotation: "Year 2 only — Year 1 accounts
never see 1:1 rows. Book flow entry: Sessions → calendar icon → 'Book your
one-to-one' (also surfaced during Year-2 enrollment)."
C3 ✓ Practice loop dead-ends
SakRecPractice records a take with no next state (sak-feedback.jsx:451-467).
Resolution: Reuse the existing review chrome: add a small "practice" variant state
note — after recording, the student sees Play / Re-record / "Attach to feedback"
(not "Submit to Ust. Amina") and no attempts dots (practice takes don't burn
attempts). Implement as a new artboard "Practice — review take" in F1 using
SakRecReview's components with the practice header (SakNavDrill "Week 7 ·
Practice") — do not modify SakRecReview itself.
C4 ✓ Orphaned session-detail frames
SakSessionDetail/SakSessionDetailQRC (sak-schedule.jsx:356-598) unreachable since
rows became inline shelves.
Resolution: Keep the components, but remove their standalone rationale confusion:
annotate in main.jsx comments that they are notification-tap deep-link
destinations (tapping a session reminder push opens the full page). No artboard
changes needed; they aren't currently on the canvas.
C5 ✓ Availability grid is a fake onboarding step
SakOnbAvailability hardcodes SakDots total={6} done={4} and skips
OnboardingShell (sak-appointments.jsx:263-271).
Resolution: It is NOT part of first-run onboarding. Convert its header to
SakNavDrill (eyebrow "Fall 2026 · Year 2", title "Availability"), remove the dots.
Relabel the artboard in main.jsx F5: "Availability — asked during Year-2 booking".
Core onboarding stays 6 steps.
D. Consistency debts
D1 ✓ Coach schedule doesn't distinguish fixed vs flex bookings
Resolution: In SakCoachSchedule, Sarah's row keeps "Recurring · Week 8";
Khadija's row gets "This week only" in the same slot — one-word vocabulary:
Recurring / This week only.
D2 ✓ Bespoke audio primitives linger
SakRecReview hand-rolls a 54px play circle (sak-recording.jsx:174-180) instead of
FbPlayBtn.
Resolution: Swap it for FbPlayBtn. (Mic buttons: leave the three bespoke mic
buttons as-is for the mockup; note in spec that production should share one
component.)
D3 ✓ AUDIT.md has no entry for the F screens' anchors
Resolution: Append a short "F-screens" table to AUDIT.md's per-screen log after all fixes land (anchor + status ✓), and log the resolutions applied from this file.
Out of scope for the mockup (documented in the spec instead)
- Full merge of week view into Sessions tab (two density levels, one surface) — spec.
- Two-coach model for Year 2 — rejected for now; single assigned coach. Revisit if scheduling capacity demands it.
- Shared
RecMicButtonprimitive — production concern. - 20-appointment credits, AI feedback summaries, student-centric QRC scheduling algorithm — backlog (see TRACEABILITY.md).