Skip to content

Visual: Dark mode on key pages after background token fix. #52

Description

@p3n74

Synced from Winnow plan Quality Assessment and UI/UX mastery (c7b3c344-85c6-40eb-823e-c4e6d3f81bb6).

Section: Validation Checklist
Status at sync: open
Task key: validation-checklist/0/visual-dark-mode-on-key-pages-after-background-token-fix

Details

  • Visual: Dark mode on key pages after background token fix.

Current Scope

  • In scope: apps/web (Next.js) primary user journeys: marketing home, treatments listing + modals, consultations booking, login/sign-up, dashboard shell.
  • Out of scope (this pass): apps/native deep dive (separate pass); remote DB changes.

Notes

  • Keep graph-oriented structure: root plan → sections → primary tasks → nested sidequests.
  • Sidequests attach to a parent task via nested checklist indentation, not a separate section.
  • Performance guidelines for follow-up: docs/performance-optimization.md.

Audit findings (structured table)

Repo paths verified under /Users/bastionii/Documents/Github/precisione/apps/web/. Date of audit: 2026-05-04.

Category Issue description Severity Recommended fix
Technical apps/web/src/app/page.tsx imports Footer but never renders it — dead import and noise for bundlers/linters. Low Remove the unused Footer import.
Technical layout.tsx sets body to bg-[#fdf8f0] while index.css applies body { @apply bg-background text-foreground } — theme tokens and dark mode diverge from marketing chrome. Medium Prefer className="... bg-background" (or a dedicated --cream CSS variable in :root) so light/dark stay coherent with ModeToggle.
Technical dashboard.tsx logs customerState to the console in production builds. Medium Delete console.log / console.warn or guard with process.env.NODE_ENV === "development".
Technical Subscription CTAs only call console.warn — no navigation, toast, or disabled UI; users perceive broken controls. High Until Polar returns: disabled + tooltip or inline text (“Billing is not available yet”), or toast.info(...).
Technical consultations-client.tsx recomputes min/max day bounds inside .map() for every calendar cell (42× per render). Medium Hoist once per render: const minSelectableDay = useMemo(...); const maxSelectableDay = useMemo(...);
Technical sign-in-form.tsx passes width="250" / height="125" as strings to next/image. Low Use numeric props: width={250} height={125}.
Technical page-layout.tsx duplicates Header/Footer but is unused anywhere in apps/web. Low Remove file or refactor routes to use it intentionally (avoid double chrome with root layout).
A11Y Home contact overlay (page.tsx) is a plain div — no role="dialog", aria-labelledby, focus trap, or Escape to close. High Use Radix Dialog / AlertDialog or implement WAI-ARIA dialog pattern + useEffect focus restore.
A11Y Treatment modals (treatments-page.tsx, landing/treatments.tsx) same overlay gap; close button only, no dialog semantics. High Same as above; ensure first focusable inside panel on open.
A11Y consultations-client.tsx: <label> text is not associated with controls (htmlFor / matching id missing on inputs, select, textarea). Medium Example: <label htmlFor="fullName"> + <input id="fullName" ... />.
A11Y Calendar month navigation buttons show only / with aria-hidden on glyphs — control has no accessible name. Medium Add aria-label="Previous month" / "Next month" on the Buttons.
A11Y footer.tsx: “Instagram” and “Facebook” are <span>s, not links — screen readers and keyboard users hit a dead end. Medium Use <a href="..." rel="noopener noreferrer"> with real URLs (match hero Facebook link).
A11Y VisualsContent hero image uses alt="logo" — vague for assistive tech. Low Match branding: alt="Precisione logo" (same as header).
A11Y Decorative Google SVG in auth buttons should be hidden from AT. Low Add aria-hidden="true" on the <svg>.
A11Y user-menu.tsx: DropdownMenuItem wrapping a full Button for “Sign Out” is an awkward composite; email row is focusable menu item without action. Medium Use DropdownMenuItem with onSelect for sign-out; render email as DropdownMenuLabel or plain text node.
A11Y mode-toggle.tsx: Moon icon uses absolute positioning but trigger Button is not relative — icon may misalign; ensure stacked icons live in relative container. Low Add className="relative" to the icon Button.
A11Y “Scroll down to meet the team” uses animate-pulse — can disturb users with vestibular/motion sensitivity. Medium Wrap in @media (prefers-reduced-motion: reduce) { animation: none; } or Tailwind motion-reduce:animate-none.
UX Modals (treatments, home) do not close on backdrop click; users expect click-outside dismiss (common pattern). Medium onClick on backdrop stopPropagation on panel; close when backdrop receives direct click.
UX Footer social labels look like links but do nothing — Mom Test drop-off for “find us on social”. High Real URLs + external link affordance.
UX Dashboard primary actions give no feedback — highest drop-off for logged-in users exploring “Pro”. High Align with recommended technical fix (copy + disabled or real flow).
UX Consultations: date picker popover stays open until a day is picked; no explicit “Cancel” and easy to leave orphan overlay on small screens. Low Add dismiss control + click-outside + Escape.
Visual sign-up-form.tsx “Already have an account?” uses text-indigo-600 — breaks OKLCH primary/foreground system used elsewhere. Low Drop custom indigo; use variant="link" default (primary token).
Visual Desktop nav uses label.toUpperCase(); mobile drawer uses sentence case — inconsistent brand voice. Low Choose one convention (title case recommended for readability).
Visual Mix of arbitrary text sizes (text-[11px], text-[0.68rem]) vs Tailwind scale — weak alignment to 4/8px rhythm. Low Standardize on text-xs (12px) minimum for body/supporting copy.
Performance Large next/image fill usages (e.g. doctor cards) should set sizes to reduce wrong intrinsic loads on mobile vs desktop. Medium e.g. sizes="(max-width: 768px) 100vw, 50vw" on Image fill.
Performance Home IntersectionObserver effect captures slides from first render; if children change, cleanup may be incomplete. Low Store sectionRef children in ref updated on layout, or observe in callback ref pattern.

Sidequests (nested under timeline)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions