Capstone project — design and implement a complete Instructor Profile page for DevBootstrap applying all design principles: CRAP, visual hierarchy, color theory, typography, layout composition, Gestalt, psychology, and systematic review.
This capstone project brings together every design principle from the module — Contrast, Repetition, Alignment, Proximity, visual hierarchy, color theory, typography essentials, layout composition, Gestalt principles, design psychology, and the systematic review process — into a single complete implementation.
You will design and build an Instructor Profile page for DevBootstrap. This page type is complex enough to require all principles while being scoped enough to complete in a reasonable session. The page includes a profile header, statistics section, course listings, and testimonials — each requiring different design decisions.
For each major CSS decision, the rationale references a specific principle from the module. By the end, you should be able to explain every styling choice in design principle terms.
The most effective approach to principled implementation starts with planning — defining hierarchy, color decisions, spacing system, and composition before touching CSS.
Instructor Profile Page Planning:
1Level 1 (Primary — 2 elements):
2 - Instructor name (page title)
3 - Featured course (conversion goal)
4
5Level 2 (Secondary — 6-8 elements):
6 - Course count, student count, rating (credibility)
7 - Section headings (navigation)
8 - Enroll CTAs on each course card
9
10Level 3 (Tertiary — unlimited):
11 - Instructor bio text
12 - Course metadata
13 - Review quotes
14 - Social links1From design system tokens only:
2 - Primary text: --color-text (#111827)
3 - Muted text: --color-text-muted (#6B7280)
4 - Action color: --color-action (#2563EB)
5 - Background variants: --color-bg-page, --color-bg-surface
6 - Status: success (enrolled), danger (unavailable course)
7No new colors introduced1Page title: var(--text-fluid-h1) — 2rem → 3.75rem fluid
2Section headings: var(--text-3xl) = 1.875rem/700
3Card titles: var(--text-xl) = 1.25rem/600
4Body text: var(--text-base) = 1rem/400/1.6 line-height
5Meta/captions: var(--text-sm) = 0.875rem/4001Section padding: var(--space-16) top/bottom
2Container horizontal: clamp(1rem, 4vw, 2.5rem)
3Card internal: var(--space-5) all sides
4Form groups: var(--space-1) label-input, var(--space-6) between groups1Profile header: asymmetrical balance (photo left, info right)
2 Ratio: 1fr auto (photo flexible, info wraps content)
3Stats bar: symmetrical (equal 3-column)
4Course grid: auto-fill with 280px minimum
5Testimonials: 2-column grid, quotes card pattern1Proximity: instructor credentials group tight (name, title, rating, enrollment)
2Similarity: all course cards identical appearance
3Continuity: section flow top-to-bottom logical order
4Figure-Ground: sticky enrollment sidebar elevated with shadowThe profile header implements asymmetrical balance and applies proximity grouping to instructor credentials.
CSS implementation:
1/* Profile header: asymmetrical balance
2 CRAP: all four principles active
3 Hierarchy: name is Level 1, credentials Level 2, bio Level 3 */
4
5.profile-header {
6 /* ALIGNMENT: grid creates consistent layout */
7 display: grid;
8 grid-template-columns: auto 1fr; /* photo: auto; content: fills rest */
9 gap: var(--space-8);
10 align-items: start;
11
12 /* ALIGNMENT: same padding as all page sections */
13 padding: var(--space-12) 0;
14}
15
16.profile-photo {
17 /* BALANCE: photo has high visual weight (large, colored, elevated) */
18 width: 8rem; /* 128px — substantial but not dominant */
19 height: 8rem;
20 border-radius: 50%; /* circular = max visual isolation = more weight */
21 object-fit: cover;
22 flex-shrink: 0;
23 box-shadow: 0 4px 16px rgb(0 0 0 / 0.12);
24 border: 3px solid var(--color-bg-page); /* white ring = polish */
25}
26
27.profile-content {
28 display: flex;
29 flex-direction: column;
30 gap: var(--space-1); /* PROXIMITY: credentials tight to each other = one unit */
31}
32
33.profile-name {
34 /* Level 1 — CONTRAST: dominant element */
35 font-size: var(--text-fluid-h1); /* REPETITION: same as all page h1s */
36 font-weight: 700;
37 line-height: 1.2;
38 color: var(--color-text); /* REPETITION: same as all headings */
39 letter-spacing: -0.025em; /* REPETITION: same as all large headings */
40 margin: 0;
41}
42
43.profile-title {
44 /* Level 2 — CONTRAST: clearly smaller/lighter than name */
45 font-size: var(--text-xl); /* 20px vs 2-3.75rem name */
46 font-weight: 500;
47 color: var(--color-text-muted); /* CONTRAST: lighter = less important */
48 margin: 0;
49}
50
51/* Rating row: proximity group (all on same line = related) */
52.profile-rating {
53 display: flex;
54 align-items: center; /* ALIGNMENT: baseline alignment */
55 gap: var(--space-3);
56 margin-top: var(--space-3); /* PROXIMITY: slight gap = new sub-group */
57}
58
59.profile-rating-value {
60 font-size: 1.125rem;
61 font-weight: 700;
62 color: var(--color-text);
63}
64
65.profile-rating-stars {
66 display: flex;
67 gap: 0.125rem;
68 color: #f59e0b; /* amber — semantic color for star ratings */
69}
70
71.profile-rating-count {
72 font-size: var(--text-sm);
73 color: var(--color-text-muted); /* Level 3 — detail information */
74}
75
76/* PROXIMITY: bio separated from credentials by larger gap */
77.profile-bio {
78 font-size: var(--text-md);
79 line-height: 1.65;
80 color: var(--color-text-muted);
81 margin-top: var(--space-4); /* PROXIMITY: gap > credential gap = new group */
82 max-width: 55ch; /* TYPOGRAPHY: optimal line length */
83}Statistics section uses symmetrical balance and identical card formatting to apply Repetition and Gestalt Similarity.
Statistics section:
1/* Stats: symmetrical balance (3 equal columns)
2 Gestalt Similarity: all stats look identical = they are the same type of content
3 CRAP Repetition: same token for all stat values and labels */
4
5.stats-section {
6 background-color: var(--color-bg-surface); /* CONTRAST: section separation */
7 border-top: 1px solid var(--color-border);
8 border-bottom: 1px solid var(--color-border);
9 padding: var(--space-10) 0;
10}
11
12.stats-grid {
13 display: grid;
14 grid-template-columns: repeat(3, 1fr); /* ALIGNMENT: equal symmetrical columns */
15 gap: var(--space-6);
16 max-width: 40rem; /* constrain to comfortable width */
17 margin-inline: auto;
18 text-align: center; /* ALIGNMENT: centered for symmetrical stat display */
19}
20
21.stat-value {
22 /* Level 2 CONTRAST: large numbers for at-a-glance scanning */
23 font-size: 2.25rem; /* 36px — large but not Level 1 */
24 font-weight: 700;
25 color: var(--color-text);
26 line-height: 1;
27 display: block;
28 font-variant-numeric: tabular-nums; /* TYPOGRAPHY: fixed-width numbers */
29}
30
31.stat-label {
32 /* Level 3 CONTRAST: minimal, informational */
33 font-size: var(--text-xs);
34 font-weight: 600;
35 text-transform: uppercase;
36 letter-spacing: 0.08em; /* TYPOGRAPHY: uppercase needs tracking */
37 color: var(--color-text-muted);
38 margin-top: var(--space-1); /* PROXIMITY: tight to its value = same unit */
39}
40
41/* Course Grid: auto-fill cards
42 Gestalt Similarity: all cards IDENTICAL appearance */
43.courses-section {
44 padding: var(--space-12) 0;
45}
46
47.courses-heading {
48 font-size: var(--text-3xl); /* REPETITION: same as all section headings */
49 font-weight: 700;
50 color: var(--color-text);
51 margin: 0 0 var(--space-8);
52}
53
54.courses-grid {
55 display: grid;
56 grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
57 gap: var(--space-6);
58}
59
60/* GESTALT SIMILARITY: each course card is identical
61 Users learn the pattern once and scan without re-learning */Testimonials with continuity:
1/* Testimonials: 2-column grid
2 Gestalt Continuity: cards arranged in reading-order left-to-right flow */
3
4.testimonials-section {
5 background-color: var(--color-bg-surface); /* CONTRAST: section separation */
6 padding: var(--space-12) 0;
7}
8
9.testimonials-grid {
10 display: grid;
11 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
12 gap: var(--space-5);
13}
14
15.testimonial-card {
16 background-color: var(--color-bg-page);
17 border-radius: var(--radius-lg); /* REPETITION: same as course cards */
18 border: 1px solid var(--color-border);
19 padding: var(--space-5);
20 display: flex;
21 flex-direction: column;
22 gap: var(--space-4); /* PROXIMITY: content sections in card */
23}
24
25.testimonial-quote {
26 font-size: var(--text-base);
27 line-height: 1.65;
28 color: var(--color-text);
29 margin: 0;
30 font-style: italic; /* visual signal: this is a quote */
31}
32
33/* quote marks via pseudo-element */
34.testimonial-quote::before { content: '\201C'; } /* left double quotation mark */
35.testimonial-quote::after { content: '\201D'; } /* right double quotation mark */
36
37.testimonial-author {
38 display: flex;
39 align-items: center; /* ALIGNMENT: photo and text on same baseline */
40 gap: var(--space-3);
41 /* PROXIMITY: pushed to bottom of card (margin-top: auto) = separated from quote */
42 margin-top: auto;
43}After implementation, run the 30-minute review and document every significant CSS decision with its principle rationale.
Design review results (abbreviated):
1PHASE 1: 5-Second Test
2 Result: PASS
3 'This is an instructor profile page' — name dominant, photo clear
4 'I can browse and enroll in their courses' — courses section obvious
5
6PHASE 2: Squint Test
7 Result: PASS
8 Dominant: instructor name, course card thumbnails (correct — they are Level 1 and 2)
9 Receded: bio text, metadata (correct — they are Level 3)
10
11PHASE 3: CRAP
12 Contrast: all text meets WCAG AA (verified with DevTools)
13 Repetition: all tokens used consistently, no hardcoded values
14 Alignment: grid-based throughout, no manual pixel positioning
15 Proximity: stat values close to labels, bio separated from credentials
16
17PHASE 4: Gestalt and Psychology
18 Similarity: all course cards identical ✓
19 Proximity: rating stars group tight ✓
20 Figure-ground: card elevation correct ✓
21 Hick's Law: primary CTA per card = one decision ✓
22 Fitts's Law: all CTAs ≥ 44px height ✓
23
24PHASE 5: Responsive and Accessibility
25 375px: photo and content stack vertically ✓
26 768px: 2-column course grid ✓
27 1440px: 3-column course grid ✓
28 Keyboard: all interactive elements have focus rings ✓
29 Contrast: all text passes ✓
30
31VIOLATION FOUND:
32 Category badge: #60a5fa on #eff6ff = 2.67:1 (fails)
33 Fix: color: #1d4ed8 (7.0:1) ✓Design decision documentation:
1Decision log for Instructor Profile page:
2
31. Photo: width 8rem, border-radius: 50%, border: 3px solid white
4 Principle: Gestalt Figure-Ground — circular photo with white ring
5 establishes instructor photo as figure, ring separates from background
6 Effect: photo visually pops from any background color
7
82. Profile name: font-size fluid h1, font-weight: 700
9 Principle: Visual Hierarchy Level 1 — instructor name is the primary
10 identifiable element; all subsequent scanning uses name as anchor
11
123. Stats section: background-color: --color-bg-surface
13 Principle: CRAP Contrast — alternating page/surface backgrounds
14 creates section separation without borders or dividers
15 Principle: CRAP Repetition — same pattern as other alternating sections
16
174. Stat values: text-align: center, tabular-nums
18 Principle: Alignment — centered symmetrical stat display
19 Principle: Typography — tabular-nums ensures multi-digit numbers
20 do not cause layout shifts when values change
21
225. course grid: auto-fill minmax(280px, 1fr)
23 Principle: Gestalt Continuity — auto-fill creates a natural visual flow
24 Principle: Alignment — all cards snap to same column structure
25 Psychology: Fitts's Law — full-width card CTA at bottom is maximum
26 horizontal target size for enrollment conversionThe complete, reviewed CSS for the DevBootstrap Instructor Profile page with all principle violations resolved.
1/* INSTRUCTOR PROFILE PAGE — Complete CSS
2 All design principle decisions documented inline */
3
4/* Base layout: page sections alternate bg colors (CRAP Contrast + Repetition) */
5.page-section--white { background-color: var(--color-bg-page); }
6.page-section--surface { background-color: var(--color-bg-surface); }
7
8/* All sections share same container structure (CRAP Alignment + Repetition) */
9.page-section .container {
10 max-width: 80rem;
11 margin-inline: auto;
12 padding: var(--space-12) clamp(1rem, 4vw, 2.5rem);
13}
14
15/* ===== PROFILE HEADER ===== */
16/* Asymmetrical balance: photo has high visual weight (circular, elevated, colored)
17 content has larger area but lower density — they balance without being equal */
18
19.profile-header { display: grid; grid-template-columns: auto 1fr; gap: var(--space-8); align-items: start; }
20
21.profile-photo {
22 width: 8rem; height: 8rem;
23 border-radius: 50%; /* circular = high visual isolation = visual weight */
24 object-fit: cover;
25 box-shadow: 0 4px 16px rgb(0 0 0 / 0.12);
26 border: 3px solid var(--color-bg-page);
27 flex-shrink: 0;
28}
29
30/* Level 1 Hierarchy: instructor name dominates */
31.profile-name {
32 font-size: var(--text-fluid-h1); /* max contrast with all other text */
33 font-weight: 700;
34 color: var(--color-text);
35 letter-spacing: -0.025em;
36 margin: 0 0 var(--space-1);
37}
38
39/* Level 2 Hierarchy: title supports name */
40.profile-title {
41 font-size: var(--text-xl);
42 font-weight: 500;
43 color: var(--color-text-muted); /* lighter = lower hierarchy */
44 margin: 0 0 var(--space-3);
45}
46
47/* Level 2 Hierarchy: rating is credibility signal */
48.profile-meta {
49 display: flex; align-items: center; gap: var(--space-3);
50 flex-wrap: wrap;
51}
52
53.meta-stat {
54 display: flex; align-items: center; gap: var(--space-1);
55 font-size: var(--text-sm);
56 color: var(--color-text-muted);
57}
58
59.meta-stat strong { color: var(--color-text); font-weight: 600; }
60
61/* Level 3 Hierarchy: bio is background reading */
62.profile-bio {
63 margin-top: var(--space-5); /* Proximity: larger gap = new section */
64 font-size: var(--text-base); line-height: 1.65;
65 color: var(--color-text-muted);
66 max-width: 55ch;
67}
68
69/* ===== STATISTICS ===== */
70/* Symmetrical balance: 3 equal columns communicate equal importance */
71
72.stats-inner { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; }
73
74.stat-value {
75 font-size: var(--text-4xl); font-weight: 700;
76 color: var(--color-text); line-height: 1;
77 font-variant-numeric: tabular-nums;
78 display: block;
79}
80
81.stat-label {
82 font-size: var(--text-xs); font-weight: 600;
83 text-transform: uppercase; letter-spacing: 0.08em;
84 color: var(--color-text-muted);
85 margin-top: var(--space-1);
86}
87
88/* ===== COURSES ===== */
89/* Gestalt Similarity: every card identical = users learn pattern once */
90
91.section-heading {
92 font-size: var(--text-3xl); font-weight: 700;
93 color: var(--color-text);
94 margin: 0 0 var(--space-8);
95}
96
97.courses-grid {
98 display: grid;
99 grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
100 gap: var(--space-6);
101}
102
103/* ===== TESTIMONIALS ===== */
104/* Figure-Ground: cards elevated above section surface background */
105
106.testimonials-grid {
107 display: grid;
108 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
109 gap: var(--space-5);
110}
111
112.testimonial-card {
113 background: var(--color-bg-page); /* figure: pure white */
114 border-radius: var(--radius-lg); /* Repetition: same as course cards */
115 border: 1px solid var(--color-border);
116 box-shadow: 0 2px 8px rgb(0 0 0 / 0.06); /* elevation = figure */
117 padding: var(--space-5);
118 display: flex; flex-direction: column; gap: var(--space-4);
119}
120
121.testimonial-quote {
122 font-size: var(--text-base); line-height: 1.65;
123 color: var(--color-text); font-style: italic;
124 margin: 0; flex: 1;
125}
126
127.testimonial-author {
128 display: flex; align-items: center; gap: var(--space-3);
129 margin-top: auto; /* Proximity: pushed to bottom = separated from quote */
130}
131
132.author-avatar {
133 width: 2.5rem; height: 2.5rem;
134 border-radius: 50%; object-fit: cover; flex-shrink: 0;
135}
136
137.author-name { font-size: var(--text-sm); font-weight: 600; color: var(--color-text); }
138.author-role { font-size: var(--text-xs); color: var(--color-text-muted); }Every CSS decision in this implementation has a documented principle rationale. The asymmetrical balance in the header (circular photo vs content area) uses visual weight factors: the photo's circular isolation and elevation make it visually heavy despite being smaller than the content area. The symmetrical 3-column statistics section communicates equal importance through identical visual treatment. Auto-fill courses grid applies Gestalt Similarity — all cards look identical, so users learn the card pattern once and scan efficiently. The testimonial cards use margin-top: auto on the author section to push it to the bottom of its flex container, creating Proximity separation between the quote content and the attribution, mirroring how blockquotes are conventionally formatted.
Congratulations on completing the Design Principles for Developers module. You now have a complete toolkit for evaluating and implementing designs with principled intent — apply these principles to your next project and use the 30-minute review process as your standard pre-PR quality check.
Your progress is saved in this browser, on this device only.