Skip to content

Mobile/UX overhaul: collapsible cards, topic filter, progress & resume, a11y - #11

Merged
dineshbyte merged 18 commits into
mainfrom
fix/mobile-header-align
Jun 20, 2026
Merged

Mobile/UX overhaul: collapsible cards, topic filter, progress & resume, a11y#11
dineshbyte merged 18 commits into
mainfrom
fix/mobile-header-align

Conversation

@dineshbyte

Copy link
Copy Markdown
Owner

What & why

Type of change

  • Content — new lesson / track, or reworked existing content
  • Content fix — typo, clarity, accuracy, or diagram fix
  • Bug fix — broken link, layout, search, etc.
  • Feature — site/tooling capability
  • Chore / docs / CI

Scope

Checklist

  • node scripts/check-broken-links.js passes (no broken internal links)
  • node scripts/validate-content.js passes (SEO tags, interview data-levels, JSON-LD, sitemap in sync)
  • New/renamed pages are added to docs/sitemap.xml
  • Each page has a unique <title> (· StackDepth), meta description, canonical, and Open Graph tags

For content changes

  • Visual-first: the concept is carried by diagrams/tables/cards; prose only labels them (passes the "skim with text too small to read" ship test)
  • Accurate & cited: non-obvious claims cite high-trust sources (RFCs, specs, vendor/standards docs) — no claims from memory
  • Interview panel present where expected, with valid data-level values (core / senior / staff / design)
  • Quiz options are length-balanced; dark and light modes both legible

Notes for the reviewer

On phones the topbar wraps the search to its own row, leaving the brand,
Star, and theme-toggle buttons packed on the left with empty space on the
right. Add .brand{margin-right:auto} at <=640px so the brand keeps the left
edge and the Star + theme buttons sit at the right edge — the conventional,
balanced app-header layout. Desktop is unaffected (its margin-left:auto on
.search already handles spacing).
- Track cards: tighten tile padding, lesson-chip size/spacing, and tfoot gap
  at <=640px so cards don't take the whole screen on mobile.
- Footer: center the columns (brand block, Quick links, Connect/social) on
  mobile — the social links (Medium, LinkedIn, etc.) now sit centered.

CSS-only; desktop unaffected. Same branch as the header right-align fix.
Wrap each track card's lesson list in a native <details>. On mobile the list
collapses behind a 'Lessons' summary so cards are short and several tracks fit
on screen at once; tap to expand. On desktop the lessons stay visible as before
(a small script syncs the details 'open' state to the viewport via matchMedia,
placed right after the grid so desktop expands during parse with no flash and
mobile stays collapsed). Lesson <a> links remain in the DOM for SEO/crawlers.

Markup change is uniform across all 9 tiles; CSS + script only, desktop view
unchanged.
…tion states

- Cards collapse on every resolution (not just mobile): lesson lists stay in a
  <details> closed by default, so the landing shows a dense grid of compact
  track cards that scan well — pairs with the new filter. Removed the
  viewport-sync script (no longer needed; closed by default everywhere).
- Topic filter: a chip row (All / AI & LLMs / Distributed / Data & storage /
  APIs & design) filters cards by data-cat; integrates with search (clears it),
  re-applies after a search is cleared. Chips scroll horizontally on mobile.
- Interaction states: :focus-visible outlines for keyboard a11y, :active tap
  feedback on chips/lesson-links/pills/results/buttons, hover+active on the
  Lessons toggle, is-active on the selected filter chip, chevron on open.
- Fix CSS source-order bug: mobile card/grid/filter overrides were before the
  base rules (equal specificity -> base won), so they never applied. Moved them
  to the end block, after the base component rules. Also trimmed the hero on
  mobile so the filter + cards surface sooner.

Verified: filter works (AI chip -> only AI cards), chips scroll on mobile,
cards collapse on desktop+mobile, gates pass.
…lesson heading

Lesson heading (mobile): h1 now clamp(1.45rem,6vw,2.2rem) + overflow-wrap so it
scales down and never overflows on narrow phones; at <=540px the eyebrow/kicker
and meta shrink with tighter letter-spacing and the h1 drops to clamp(1.45,7vw,
1.95rem) — fixes the oversized/awkward heading on small screens.

Cards: added a keyword tag row to every track card (e.g. RAG · Retrieval ·
Embeddings) — scannable and indexable text for SEO. On mobile the description is
hidden (still in the DOM for SEO) and the hero paragraph is line-clamped, so
cards collapse to header + tags + Lessons toggle and ~3 fit per screen. Tags +
description both show on desktop.

All CSS/markup; verified at 500px (mobile rules) and desktop.
…ooter social

- Tags cycle through six distinct hues (per-tag --tg) so each card's tag row
  reads multi-colour instead of one track colour.
- Start button: a full-width primary CTA at the card BOTTOM (links to the
  track's first lesson) — moved out of the header to avoid clashing with long
  titles + the lesson-count badge. In-card collapsible lesson list hidden
  (kept in the DOM for SEO); header stays clean (icon + title + count).
- Footer Connect links are a centered inline row (Twitter / X · Medium ·
  LinkedIn · GitHub) instead of a vertical stack.
- Each filter chip now shows a count of tracks in that category
  (All 9 · AI & LLMs 2 · Distributed 2 · Data & storage 3 · APIs & design 2),
  computed from the cards so it can't drift.
- Start is now stateful: clicking it (or reading any lesson) records the track
  in localStorage ('sd:progress'); on return the card's button becomes
  '↻ Continue →' and links to the latest lesson the user was on. interview.js
  (loaded on every lesson/bank page) updates the resume point as you read;
  reference sheets/READMEs are skipped so Continue always lands on a lesson.
  Degrades silently if storage is blocked.
Render each filter chip's track count as a small circular pill (inverted on the
active chip for contrast) instead of plain dim text.
- Start/Continue button: was white-on-accent which failed WCAG AA on several
  tracks (teal/green/amber ~3.2-4.4:1) and badly in dark mode (light accents).
  Now light theme darkens the accent (white text passes AA) and dark theme uses
  the light accent with dark text. Reference 'Glossary/Resources' pills no longer
  use low-contrast --muted (now --ink, weight 500). Darkened light --muted
  (#6c6862 -> #5f5b54) so secondary text clears AA site-wide.
- Resume banner: a dismissible 'Pick up where you left off — <track>' banner at
  the top of the hub, shown only when progress exists (reads sd:last + sd:progress
  recorded by interview.js), with a Continue button to the exact lesson.

Verified light + dark renders; gates pass.
- Start/Continue (and the resume-banner Continue) now use the ink/bg pair —
  the same as the active 'All tracks' filter chip — instead of per-track
  accents: consistent across tracks and maximal contrast in both themes
  (dark button + light text in light mode; inverts in dark mode).
- Fix card spacing: removed the redundant .tfoot margin-top (it stacked on the
  flex gap, creating a too-large gap before the reference pills) and the stray
  .start margin-top:auto, so section spacing is even across all cards and
  resolutions.
The tags and lesson-count badges used the pure hue as text on a faint tint,
which fell below WCAG AA for the lighter hues in light mode and went low-contrast
on the dark card in dark mode. Mix the hue toward the theme's --ink for the text
(color-mix 70% hue + --ink) so each tag keeps its distinct colour but the label
is readable in both themes; nudged the tint/border up slightly for definition.
- Start/Continue (cards + resume banner) now use the brand accent (indigo)
  instead of flat black — consistent and accessible (white text light / dark
  text on the lighter dark-theme accent).
- Fix the banner X: '.resume{display:flex}' was overriding the [hidden]
  attribute (author rule beats UA [hidden]), so dismiss never hid it. Added
  '.resume[hidden]{display:none}'. Dismissal now also persists per track
  (sd:resume-x) so it doesn't reappear on reload.
- Banner redesign: message first, X moved to the top-right corner, cleaner
  wrap on mobile.
The refresh icon and the message were separate flex items, so when the
Continue button wrapped to its own line on narrow phones the icon ended up
alone on a row above the text. Group icon + text in a .resume-msg flex unit so
they always stay together; only the Continue button wraps below.
GitHub Pages serves .md as plain text (we use .nojekyll), so the Glossary and
Resources links opened unreadable raw markdown. Convert each track's
GLOSSARY.md / RESOURCES.md to a styled on-site HTML page (pandoc + the lesson
design system: tokens.css, lesson.css, a hubbar, SEO meta) and point all links
at the .html. Markdown stays the source of truth; scripts/build-reference-pages.py
regenerates the HTML. Added the 8 pages to sitemap.xml.
Sum each track's per-lesson read times (from the lessons' meta) and show a
'~Xh Ym read' line with a small clock glyph above the Start button — always
visible on mobile and desktop. Kept it out of the header badge (which stays
'N lessons') to avoid crowding the title + tag row on small screens.
- Active filter chip used flat black (--ink) while everything else (Start,
  banner, etc.) is the indigo brand accent — switch it to var(--accent) so the
  palette is consistent (dark text on the lighter dark-theme accent).
- Remove the per-card emoji icon squares for a cleaner, text-first card header
  (track colour identity still comes from the top border + tags).
The banner duplicated the card's Continue button. Removed it; instead the
started track's card becomes the resume element: a 'Continue where you left off'
eyebrow + accent ring, a 'Lesson N of M' progress bar (in place of the read-time
line), the Continue button, and it floats to the top of the grid (most-recent
track, from sd:last). More interactive and no duplication.
Distinguish resuming from starting: the in-progress card now uses a green
'continue' accent (eyebrow, ring, progress bar, and Continue button) while
Start cards stay indigo. Light theme darkens the green so white button text
clears AA; dark theme uses the lighter green token with dark text.
@dineshbyte
dineshbyte merged commit d69e52b into main Jun 20, 2026
2 checks passed
@dineshbyte
dineshbyte deleted the fix/mobile-header-align branch June 20, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant