diff --git a/documentation/design-tokens.css b/documentation/design-tokens.css
new file mode 100644
index 00000000..bedd6f4a
--- /dev/null
+++ b/documentation/design-tokens.css
@@ -0,0 +1,954 @@
+/**
+ * Y STEM and Chess — Design Tokens
+ * ============================================================
+ * Standalone CSS stylesheet for use by AI coding agents and any
+ * environment that does NOT have access to the Tailwind CSS build.
+ *
+ * No build step required. Link directly:
+ *
+ *
+ * Or reference the raw GitHub URL for external agents.
+ *
+ * Mirrors the design token system in tailwind.config.js and index.css.
+ * See design.md for usage rules and anti-patterns.
+ * ============================================================
+ */
+
+
+/* ============================================================
+ SECTION 1: CSS Custom Properties (Design Tokens)
+ ============================================================ */
+
+:root {
+
+ /* ----------------------------------------------------------
+ 1.1 Color Palette
+ Source: tailwind.config.js → theme.extend.colors
+ ---------------------------------------------------------- */
+
+ /* Brand greens */
+ --color-primary: #7FCC26; /* Main brand green — CTAs, active states, focus rings */
+ --color-secondary: #BFD99E; /* Muted green — hover states on icons, supporting accents */
+ --color-soft: #E5F3D2; /* Light green — page background, icon containers, card tints */
+
+ /* Accent */
+ --color-accent: #EAD94C; /* Yellow — gamification highlights, active toolbar icons, badge borders */
+
+ /* Neutrals */
+ --color-dark: #1F1F1F; /* Near-black — primary text, borders, btn-primary background */
+ --color-gray: #5C5C5C; /* Secondary text — body copy, nav links, dropdown items */
+ --color-muted: #8A8A8A; /* Placeholder text, disabled states, metadata labels */
+ --color-border-light: #D6D6D6; /* Borders, dividers */
+ --color-light: #F9FAF7; /* Off-white — surfaces: navbar, footer, forms, modals, dropdowns */
+
+ /* Semantic / Error */
+ --color-red: #D64545; /* Errors, destructive actions, invalid input borders */
+ --color-red-light: #F5E9E9; /* Error backgrounds */
+
+
+ /* ----------------------------------------------------------
+ 1.2 Typography
+ Source: Google Fonts — Lato (400, 500, 700)
+ ---------------------------------------------------------- */
+
+ --font-family-base: 'Lato', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
+
+ --font-weight-normal: 400;
+ --font-weight-medium: 500;
+ --font-weight-bold: 700;
+
+ /* Type scale — pixel equivalents of Tailwind's rem scale */
+ --text-xs: 0.75rem; /* 12px — captions, metadata, copyright */
+ --text-sm: 0.875rem; /* 14px — labels, timestamps, small body */
+ --text-base: 1rem; /* 16px — default body text */
+ --text-lg: 1.125rem; /* 18px — nav links, slightly larger body */
+ --text-xl: 1.25rem; /* 20px — large body, card descriptions */
+ --text-2xl: 1.5rem; /* 24px — footer wordmark, sub-headings */
+ --text-3xl: 1.875rem; /* 30px — section headings */
+ --text-4xl: 2.25rem; /* 36px — hero headings (desktop) */
+
+ /* Line heights */
+ --leading-tight: 1.25;
+ --leading-normal: 1.5;
+ --leading-relaxed: 1.625; /* Default for body text blocks */
+
+
+ /* ----------------------------------------------------------
+ 1.3 Spacing Scale (4px base)
+ Mirrors Tailwind's default spacing scale
+ ---------------------------------------------------------- */
+
+ --space-0: 0;
+ --space-1: 0.25rem; /* 4px */
+ --space-2: 0.5rem; /* 8px */
+ --space-3: 0.75rem; /* 12px */
+ --space-4: 1rem; /* 16px */
+ --space-5: 1.25rem; /* 20px */
+ --space-6: 1.5rem; /* 24px */
+ --space-8: 2rem; /* 32px */
+ --space-10: 2.5rem; /* 40px */
+ --space-12: 3rem; /* 48px */
+ --space-16: 4rem; /* 64px */
+ --space-20: 5rem; /* 80px */
+ --space-24: 6rem; /* 96px */
+
+
+ /* ----------------------------------------------------------
+ 1.4 Border Radius
+ ---------------------------------------------------------- */
+
+ --radius-sm: 0.125rem; /* 2px — rarely used */
+ --radius-md: 0.375rem; /* 6px — small elements */
+ --radius-lg: 0.5rem; /* 8px — rounded-lg — dropdowns, icon containers */
+ --radius-xl: 0.75rem; /* 12px — rounded-xl — btn-green, inputs */
+ --radius-2xl: 1rem; /* 16px — rounded-2xl — modals, forms */
+ --radius-3xl: 1.5rem; /* 24px — rounded-3xl — brand tier cards */
+ --radius-full: 9999px; /* Full pill — btn-primary, avatar circles, dots */
+
+
+ /* ----------------------------------------------------------
+ 1.5 Shadows
+ Source: tailwind.config.js → theme.extend.boxShadow
+ ---------------------------------------------------------- */
+
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
+
+ /* Brand card shadows — the most visually distinctive pattern */
+ --shadow-card-yellow: 1.25rem 1.25rem 0.063rem rgb(209, 230, 28); /* Free card — offset yellow */
+ --shadow-card-green: 1.25rem 1.25rem 0.063rem rgb(115, 179, 19); /* Premium card — offset green */
+
+
+ /* ----------------------------------------------------------
+ 1.6 Animation
+ ---------------------------------------------------------- */
+
+ --duration-fast: 150ms; /* Modals, snappy micro-interactions */
+ --duration-base: 300ms; /* Nav links, dropdowns, card hovers */
+ --duration-slow: 500ms; /* Button color transitions */
+
+ --easing-default: ease;
+ --easing-out: ease-out;
+
+
+ /* ----------------------------------------------------------
+ 1.7 Z-Index Scale
+ ---------------------------------------------------------- */
+
+ --z-base: 0;
+ --z-above: 10;
+ --z-dropdown: 20; /* Dropdowns and nav menus */
+ --z-sticky: 50; /* Sticky navbar */
+ --z-modal: 50; /* Modals and overlays */
+}
+
+
+/* ============================================================
+ SECTION 2: Base Reset & Body Defaults
+ Mirrors src/index.css base styles
+ ============================================================ */
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-family: var(--font-family-base);
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+ color: var(--color-dark);
+ background-color: var(--color-soft);
+}
+
+a {
+ text-decoration: none;
+ color: inherit;
+}
+
+button {
+ font-family: inherit;
+ cursor: pointer;
+}
+
+
+/* ============================================================
+ SECTION 3: Component Classes
+ Mirrors @layer components in src/index.css
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 3.1 Button: Primary
+ Dark pill CTA. Use on light/soft backgrounds.
+ Example: "Donate", "Join Now!", "Get Started!"
+ ---------------------------------------------------------- */
+.btn-primary {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ background-color: var(--color-dark);
+ color: var(--color-light);
+ font-family: var(--font-family-base);
+ font-size: var(--text-base);
+ font-weight: var(--font-weight-bold); /* semibold approximated as bold */
+ line-height: var(--leading-relaxed);
+
+ padding: var(--space-3) var(--space-8);
+ border-radius: var(--radius-full);
+ border: 2px solid var(--color-dark);
+
+ cursor: pointer;
+ transition:
+ transform var(--duration-slow) var(--easing-default),
+ background-color var(--duration-slow) var(--easing-default);
+}
+
+.btn-primary:hover {
+ transform: scale(1.05);
+ background-color: #000;
+}
+
+.btn-primary:active {
+ transform: scale(0.95);
+}
+
+.btn-primary:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 2px var(--color-primary);
+}
+
+
+/* ----------------------------------------------------------
+ 3.2 Button: Green
+ Primary brand green rounded button. Use inside forms, modals.
+ Example: "Enter", "OK", "Confirm"
+ ---------------------------------------------------------- */
+.btn-green {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ background-color: var(--color-primary);
+ color: var(--color-light);
+ font-family: var(--font-family-base);
+ font-size: var(--text-xl);
+ font-weight: var(--font-weight-bold);
+
+ padding: var(--space-3) var(--space-8);
+ border-radius: var(--radius-xl);
+ border: none;
+ box-shadow: var(--shadow-md);
+
+ cursor: pointer;
+ transition:
+ opacity var(--duration-base) var(--easing-default),
+ transform var(--duration-base) var(--easing-default);
+}
+
+.btn-green:hover {
+ opacity: 0.9;
+ transform: scale(1.05);
+}
+
+.btn-green:active {
+ transform: scale(0.95);
+}
+
+.btn-green:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.btn-green:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(127, 204, 38, 0.5);
+}
+
+
+/* ----------------------------------------------------------
+ 3.3 Button: Toolbar
+ Transparent icon-only button for the student dashboard toolbar.
+ Must contain only an SVG element as a child.
+ ---------------------------------------------------------- */
+.btn-toolbar {
+ position: relative;
+ flex: 1;
+ max-width: 20rem;
+ padding: 0;
+ background-color: transparent;
+ border: none;
+ border-radius: var(--radius-lg);
+ cursor: pointer;
+ transition:
+ transform var(--duration-base) var(--easing-default);
+}
+
+.btn-toolbar:hover {
+ transform: scale(1.05);
+}
+
+.btn-toolbar:active {
+ transform: scale(0.95);
+}
+
+.btn-toolbar:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 2px var(--color-accent);
+}
+
+
+/* ----------------------------------------------------------
+ 3.4 Scrollbar: Activity Feed
+ Custom green scrollbar for the activity timeline container.
+ ---------------------------------------------------------- */
+.activity-scrollbar {
+ scrollbar-width: thin;
+ scrollbar-color: var(--color-primary) var(--color-soft);
+}
+
+.activity-scrollbar::-webkit-scrollbar {
+ width: 6px;
+}
+
+.activity-scrollbar::-webkit-scrollbar-track {
+ background: var(--color-soft);
+}
+
+.activity-scrollbar::-webkit-scrollbar-thumb {
+ background-color: var(--color-primary);
+ border-radius: var(--radius-full);
+}
+
+
+/* ============================================================
+ SECTION 4: Layout Utilities
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 4.1 Page Container
+ Standard section container with horizontal padding.
+ ---------------------------------------------------------- */
+.container-page {
+ width: 100%;
+ max-width: 80rem; /* max-w-7xl = 1280px */
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: var(--space-6);
+ padding-right: var(--space-6);
+}
+
+@media (min-width: 768px) {
+ .container-page {
+ padding-left: var(--space-8);
+ padding-right: var(--space-8);
+ }
+}
+
+/* ----------------------------------------------------------
+ 4.2 Dashboard Container
+ Wider container for full-width dashboard layouts.
+ ---------------------------------------------------------- */
+.container-dashboard {
+ width: 100%;
+ max-width: 96rem; /* max-w-screen-2xl = 1536px */
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: var(--space-6);
+ padding-right: var(--space-6);
+}
+
+
+/* ============================================================
+ SECTION 5: Card Components
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 5.1 Standard Content Card
+ Subtle bordered card for list items and content blocks.
+ ---------------------------------------------------------- */
+.card {
+ background-color: var(--color-light);
+ border: 1px solid var(--color-border-light);
+ border-radius: var(--radius-lg);
+ padding: var(--space-4);
+ box-shadow: var(--shadow-sm);
+ transition: box-shadow var(--duration-base) var(--easing-default);
+}
+
+.card:hover {
+ box-shadow: var(--shadow-md);
+}
+
+
+/* ----------------------------------------------------------
+ 5.2 Brand Card — Green (Free tier)
+ Large rounded card with offset yellow shadow.
+ ---------------------------------------------------------- */
+.card-brand-green {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ background-color: var(--color-primary);
+ border-radius: var(--radius-3xl);
+ box-shadow: var(--shadow-card-yellow);
+ padding: var(--space-8);
+ gap: var(--space-4);
+
+ width: 100%;
+}
+
+
+/* ----------------------------------------------------------
+ 5.3 Brand Card — Light (Premium tier)
+ Large rounded card with offset green shadow.
+ ---------------------------------------------------------- */
+.card-brand-light {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ background-color: var(--color-light);
+ border-radius: var(--radius-3xl);
+ box-shadow: var(--shadow-card-green);
+ padding: var(--space-8);
+ gap: var(--space-4);
+
+ width: 100%;
+}
+
+
+/* ----------------------------------------------------------
+ 5.4 Auth / Form Card
+ Centered form panel. Max width 384px (max-w-sm).
+ ---------------------------------------------------------- */
+.card-form {
+ width: 100%;
+ max-width: 24rem; /* 384px */
+ background-color: var(--color-light);
+ border-radius: var(--radius-2xl);
+ border: 2px solid var(--color-dark);
+ box-shadow: var(--shadow-md);
+ padding: var(--space-8);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6);
+}
+
+
+/* ----------------------------------------------------------
+ 5.5 CTA Box
+ Full-width bordered call-to-action block.
+ ---------------------------------------------------------- */
+.card-cta {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-6);
+
+ border: 4px solid var(--color-primary);
+ border-radius: var(--radius-lg);
+ padding: var(--space-12) var(--space-6);
+}
+
+
+/* ============================================================
+ SECTION 6: Modal Components
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 6.1 Modal Overlay
+ Full-screen dark backdrop. Centers modal content.
+ ---------------------------------------------------------- */
+.modal-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: var(--z-modal);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--space-4);
+ background-color: rgba(31, 31, 31, 0.5); /* dark/50 */
+}
+
+
+/* ----------------------------------------------------------
+ 6.2 Modal Content Panel
+ The white card that slides in on top of the overlay.
+ ---------------------------------------------------------- */
+.modal-content {
+ background-color: var(--color-light);
+ width: 100%;
+ max-width: 24rem; /* 384px */
+ border-radius: var(--radius-2xl);
+ box-shadow: var(--shadow-xl);
+ padding: var(--space-8);
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--space-5);
+
+ animation: modal-in var(--duration-fast) var(--easing-out);
+}
+
+
+/* ----------------------------------------------------------
+ 6.3 Modal Icon Containers
+ ---------------------------------------------------------- */
+.modal-icon-success {
+ width: 4rem;
+ height: 4rem;
+ border-radius: var(--radius-full);
+ background-color: rgba(127, 204, 38, 0.2); /* primary/20 */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.modal-icon-error {
+ width: 4rem;
+ height: 4rem;
+ border-radius: var(--radius-full);
+ background-color: var(--color-red-light);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.modal-spinner {
+ width: 4rem;
+ height: 4rem;
+ border-radius: var(--radius-full);
+ border: 4px solid var(--color-soft);
+ border-top-color: var(--color-primary);
+ animation: spin 1s linear infinite;
+}
+
+
+/* ============================================================
+ SECTION 7: Form Elements
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 7.1 Standard Input
+ Rounded input with brand focus state.
+ ---------------------------------------------------------- */
+.input-base {
+ width: 100%;
+ border-radius: var(--radius-xl);
+ border: 2px solid var(--color-border-light);
+ padding: var(--space-3) var(--space-4);
+ font-family: var(--font-family-base);
+ font-size: var(--text-sm);
+ color: var(--color-dark);
+ background-color: #fff;
+ caret-color: var(--color-dark);
+ transition: border-color var(--duration-base) var(--easing-default);
+}
+
+.input-base:focus {
+ outline: none;
+ border-color: var(--color-primary);
+}
+
+
+/* ----------------------------------------------------------
+ 7.2 Input — Error State
+ ---------------------------------------------------------- */
+.input-error {
+ border-color: var(--color-red);
+}
+
+.input-error:focus {
+ border-color: var(--color-red);
+}
+
+
+/* ----------------------------------------------------------
+ 7.3 Form Label
+ ---------------------------------------------------------- */
+.label {
+ display: block;
+ font-size: var(--text-sm);
+ font-weight: var(--font-weight-bold);
+ color: var(--color-dark);
+ margin-bottom: var(--space-1);
+}
+
+
+/* ----------------------------------------------------------
+ 7.4 Error / Alert Text
+ ---------------------------------------------------------- */
+.error-text {
+ color: var(--color-red);
+ font-weight: var(--font-weight-bold);
+ font-size: var(--text-sm);
+ text-align: center;
+}
+
+
+/* ============================================================
+ SECTION 8: Navigation
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 8.1 NavBar Shell
+ Sticky top navigation bar.
+ ---------------------------------------------------------- */
+.navbar {
+ background-color: var(--color-light);
+ border-bottom: 2px solid var(--color-dark);
+ position: sticky;
+ top: 0;
+ z-index: var(--z-sticky);
+ height: 6rem; /* h-24 */
+}
+
+/* ----------------------------------------------------------
+ 8.2 Nav Link
+ Standard navigation link — text, hover to primary.
+ ---------------------------------------------------------- */
+.nav-link {
+ padding: 0 var(--space-4);
+ font-size: var(--text-lg);
+ font-weight: var(--font-weight-medium);
+ color: var(--color-dark);
+ transition: color var(--duration-base) var(--easing-default);
+ text-decoration: none;
+}
+
+.nav-link:hover {
+ color: var(--color-primary);
+}
+
+/* ----------------------------------------------------------
+ 8.3 Dropdown Panel
+ Floating dropdown menu for nav sections.
+ ---------------------------------------------------------- */
+.nav-dropdown {
+ position: absolute;
+ z-index: var(--z-dropdown);
+ margin-top: var(--space-3);
+ width: 16rem; /* w-64 */
+ border-radius: var(--radius-md);
+ background-color: var(--color-light);
+ padding: var(--space-4);
+ box-shadow: var(--shadow-lg);
+}
+
+.nav-dropdown-header {
+ font-size: var(--text-base);
+ font-weight: var(--font-weight-bold);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--color-dark);
+ margin-bottom: var(--space-2);
+}
+
+.nav-dropdown-link {
+ font-size: var(--text-base);
+ color: var(--color-gray);
+ transition: color var(--duration-base) var(--easing-default);
+ text-decoration: none;
+ display: block;
+}
+
+.nav-dropdown-link:hover {
+ color: var(--color-primary);
+}
+
+
+/* ============================================================
+ SECTION 9: Footer
+ ============================================================ */
+
+.footer {
+ width: 100%;
+ background-color: var(--color-light);
+ border-top: 2px solid var(--color-dark);
+ padding-top: var(--space-10);
+ padding-bottom: var(--space-8);
+}
+
+.footer-icon-container {
+ width: 2.5rem; /* 40px */
+ height: 2.5rem;
+ background-color: var(--color-soft);
+ border-radius: var(--radius-md);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid rgba(127, 204, 38, 0.2); /* primary/20 */
+ transition: background-color var(--duration-base), color var(--duration-base);
+}
+
+.footer-icon-container:hover {
+ background-color: var(--color-primary);
+ color: var(--color-light);
+}
+
+.footer-social-btn {
+ padding: var(--space-2);
+ border-radius: var(--radius-lg);
+ transition: background-color var(--duration-base) var(--easing-default);
+ display: inline-flex;
+}
+
+.footer-social-btn:hover {
+ background-color: var(--color-soft);
+}
+
+
+/* ============================================================
+ SECTION 10: Activity Timeline
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ 10.1 Timeline Container
+ Scrollable feed with dotted left border.
+ ---------------------------------------------------------- */
+.timeline-container {
+ position: relative;
+ max-height: 700px;
+ overflow-y: auto;
+ padding-right: var(--space-2);
+}
+
+/* Apply activity-scrollbar styles */
+.timeline-container {
+ scrollbar-width: thin;
+ scrollbar-color: var(--color-primary) var(--color-soft);
+}
+
+/* ----------------------------------------------------------
+ 10.2 Timeline Track
+ The vertical dotted line.
+ ---------------------------------------------------------- */
+.timeline-track {
+ position: absolute;
+ left: 1rem; /* left-4 */
+ top: 0;
+ bottom: 0;
+ width: 0;
+ border-left: 3px dotted var(--color-gray);
+}
+
+/* ----------------------------------------------------------
+ 10.3 Timeline Dot
+ Green circle marker for each activity.
+ ---------------------------------------------------------- */
+.timeline-dot {
+ position: absolute;
+ left: -2.25rem; /* -left-9 */
+ top: 1.5rem; /* top-6 */
+ width: 0.75rem;
+ height: 0.75rem;
+ background-color: var(--color-primary);
+ border-radius: var(--radius-full);
+ border: 2px solid var(--color-light);
+ box-shadow: var(--shadow-sm);
+}
+
+
+/* ============================================================
+ SECTION 11: Loading Spinner
+ ============================================================ */
+
+.spinner {
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+ border: 3px solid rgba(127, 204, 38, 0.3);
+ border-top-color: var(--color-primary);
+ border-radius: var(--radius-full);
+ animation: spin 1s linear infinite;
+}
+
+.spinner-lg {
+ width: 4rem;
+ height: 4rem;
+ border-width: 4px;
+}
+
+
+/* ============================================================
+ SECTION 12: Typography Utility Classes
+ ============================================================ */
+
+.text-hero {
+ font-size: var(--text-3xl);
+ font-weight: var(--font-weight-bold);
+ color: var(--color-dark);
+ line-height: var(--leading-relaxed);
+}
+
+@media (min-width: 768px) {
+ .text-hero {
+ font-size: var(--text-4xl);
+ }
+}
+
+.text-section-heading {
+ font-size: var(--text-3xl);
+ font-weight: var(--font-weight-bold);
+ color: var(--color-dark);
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ .text-section-heading {
+ font-size: var(--text-4xl);
+ }
+}
+
+.text-body-large {
+ font-size: var(--text-xl);
+ color: var(--color-gray);
+ line-height: var(--leading-relaxed);
+}
+
+.text-body {
+ font-size: var(--text-base);
+ color: var(--color-dark);
+ line-height: var(--leading-relaxed);
+}
+
+.text-body-secondary {
+ font-size: var(--text-base);
+ color: var(--color-gray);
+ line-height: var(--leading-relaxed);
+}
+
+.text-label {
+ font-size: var(--text-xs);
+ font-weight: var(--font-weight-bold);
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: var(--color-muted);
+}
+
+.text-error {
+ color: var(--color-red);
+ font-weight: var(--font-weight-bold);
+}
+
+.text-accent-link {
+ color: var(--color-primary);
+ text-decoration: underline;
+ cursor: pointer;
+ transition: color var(--duration-base) var(--easing-default);
+}
+
+.text-accent-link:hover {
+ color: var(--color-secondary);
+}
+
+
+/* ============================================================
+ SECTION 13: Avatar / Profile Picture
+ ============================================================ */
+
+.avatar {
+ position: relative;
+ width: 3.5rem; /* 56px */
+ height: 3.5rem;
+ border-radius: var(--radius-full);
+ background-color: var(--color-light);
+ border: 2px solid var(--color-primary);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: var(--shadow-sm);
+ cursor: pointer;
+ transition: transform var(--duration-base) var(--easing-default);
+}
+
+.avatar:hover {
+ transform: scale(1.05);
+}
+
+.avatar:active {
+ transform: scale(0.95);
+}
+
+
+/* ============================================================
+ SECTION 14: Keyframe Animations
+ Mirrors tailwind.config.js → theme.extend.keyframes
+ ============================================================ */
+
+/* ----------------------------------------------------------
+ Modal entry — scale + fade in
+ Usage: apply animation: modal-in 0.15s ease-out
+ ---------------------------------------------------------- */
+@keyframes modal-in {
+ 0% {
+ opacity: 0;
+ transform: scale(0.95) translateY(8px);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ }
+}
+
+/* ----------------------------------------------------------
+ Fade out — for toast/notification dismissal
+ Usage: apply animation: fade-out 0.4s ease 2.1s forwards
+ ---------------------------------------------------------- */
+@keyframes fade-out {
+ to {
+ opacity: 0;
+ transform: translateY(-5px);
+ }
+}
+
+/* ----------------------------------------------------------
+ Shake — for form validation errors
+ Usage: apply animation: shake 0.5s ease
+ ---------------------------------------------------------- */
+@keyframes shake {
+ 0%, 100% { transform: translateX(0); }
+ 25% { transform: translateX(-5px); }
+ 75% { transform: translateX(5px); }
+}
+
+/* ----------------------------------------------------------
+ Spin — for loading states
+ Usage: apply animation: spin 1s linear infinite
+ ---------------------------------------------------------- */
+@keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* Convenience animation classes */
+.animate-modal-in {
+ animation: modal-in 150ms ease-out;
+}
+
+.animate-fade-out {
+ animation: fade-out 0.4s ease 2.1s forwards;
+}
+
+.animate-shake {
+ animation: shake 0.5s ease;
+}
+
+.animate-spin {
+ animation: spin 1s linear infinite;
+}
diff --git a/documentation/design-tokens.rn.ts b/documentation/design-tokens.rn.ts
new file mode 100644
index 00000000..c0f996e3
--- /dev/null
+++ b/documentation/design-tokens.rn.ts
@@ -0,0 +1,531 @@
+/**
+ * Y STEM and Chess — React Native Design Tokens
+ * ============================================================
+ * Import this file into any React Native / Expo component:
+ *
+ * import { colors, spacing, typography, radius, shadows } from './design-tokens.rn';
+ *
+ * All values are React Native-compatible (unitless numbers for
+ * dimensions, hex strings for colors, named shadow objects for
+ * iOS/Android). No CSS units (rem, px) are used.
+ *
+ * Mirrors design-tokens.css and tailwind.config.js exactly.
+ * See design.md for usage rules and anti-patterns.
+ * ============================================================
+ */
+
+import { Platform, TextStyle, ViewStyle } from 'react-native';
+
+
+/* ============================================================
+ 1. COLOR PALETTE
+ Source: tailwind.config.js → theme.extend.colors
+ ============================================================ */
+
+export const colors = {
+ // Brand greens
+ primary: '#7FCC26', // Main brand green — CTAs, active states, focus rings
+ secondary: '#BFD99E', // Muted green — hover/inactive states, icon tints
+ soft: '#E5F3D2', // Light green — screen backgrounds, card tints, icon containers
+
+ // Accent
+ accent: '#EAD94C', // Yellow — gamification highlights, active toolbar icons, badge borders
+
+ // Neutrals
+ dark: '#1F1F1F', // Near-black — primary text, borders, btn-primary background
+ gray: '#5C5C5C', // Secondary text — body copy, descriptions
+ muted: '#8A8A8A', // Placeholder text, disabled states, metadata labels
+ borderLight: '#D6D6D6', // Borders, dividers, separators
+ light: '#F9FAF7', // Off-white — card surfaces, form backgrounds, modals
+
+ // Semantic / Error
+ red: '#D64545', // Errors, destructive actions, invalid input borders
+ redLight: '#F5E9E9', // Error state backgrounds
+
+ // Transparent helpers
+ primaryFaint: 'rgba(127, 204, 38, 0.1)', // primary/10 — subtle green tint
+ primaryLight: 'rgba(127, 204, 38, 0.2)', // primary/20 — success icon container
+ primaryMid: 'rgba(127, 204, 38, 0.3)', // primary/30 — icon tint
+ darkOverlay: 'rgba(31, 31, 31, 0.5)', // dark/50 — modal backdrop
+ accentFaint: 'rgba(234, 217, 76, 0.2)', // accent/20 — tutor section bg
+ white10: 'rgba(255, 255, 255, 0.1)',
+ white20: 'rgba(255, 255, 255, 0.2)',
+ white50: 'rgba(255, 255, 255, 0.5)',
+ white60: 'rgba(255, 255, 255, 0.6)',
+ white80: 'rgba(255, 255, 255, 0.8)',
+} as const;
+
+export type ColorKey = keyof typeof colors;
+
+
+/* ============================================================
+ 2. TYPOGRAPHY
+ Font: Lato (load via @expo-google-fonts/lato or embed assets)
+ ============================================================ */
+
+export const fontFamily = {
+ /**
+ * Load Lato via Expo:
+ * import { useFonts, Lato_400Regular, Lato_700Bold } from '@expo-google-fonts/lato';
+ *
+ * Then use fontFamily.regular, fontFamily.bold, etc.
+ */
+ regular: 'Lato_400Regular',
+ medium: 'Lato_500Medium', // Load Lato_500Medium if available, else use regular
+ bold: 'Lato_700Bold',
+
+ // System fallback (use until fonts load)
+ system: Platform.OS === 'ios' ? 'System' : 'Roboto',
+} as const;
+
+export const fontWeight = {
+ normal: '400' as TextStyle['fontWeight'],
+ medium: '500' as TextStyle['fontWeight'],
+ bold: '700' as TextStyle['fontWeight'],
+} as const;
+
+/**
+ * Type scale — matches the Tailwind/web type scale.
+ * Values are unitless numbers (React Native interprets as dp/pt).
+ */
+export const fontSize = {
+ xs: 12, // Captions, metadata, copyright labels
+ sm: 14, // Labels, timestamps, small body text
+ base: 16, // Default body text
+ lg: 18, // Nav links, slightly larger body
+ xl: 20, // Large body, card descriptions, btn-green text
+ '2xl': 24, // Sub-headings, footer wordmark
+ '3xl': 30, // Section headings
+ '4xl': 36, // Hero headings
+} as const;
+
+export const lineHeight = {
+ tight: 1.25,
+ normal: 1.5,
+ relaxed: 1.625, // Default for body text blocks
+} as const;
+
+/** Convenience: multiply fontSize by lineHeight to get absolute lineHeight for RN */
+export const getLineHeight = (size: number, ratio: number = lineHeight.relaxed) =>
+ Math.round(size * ratio);
+
+
+/* ============================================================
+ 3. SPACING SCALE
+ 4px base, matches Tailwind default spacing.
+ Values are unitless numbers (dp/pt in React Native).
+ ============================================================ */
+
+export const spacing = {
+ 0: 0,
+ 1: 4, // space-1
+ 2: 8, // space-2
+ 3: 12, // space-3
+ 4: 16, // space-4
+ 5: 20, // space-5
+ 6: 24, // space-6
+ 8: 32, // space-8
+ 10: 40, // space-10
+ 12: 48, // space-12
+ 14: 56, // space-14
+ 16: 64, // space-16
+ 20: 80, // space-20
+ 24: 96, // space-24
+} as const;
+
+
+/* ============================================================
+ 4. BORDER RADIUS
+ Values are unitless numbers (dp/pt in React Native).
+ ============================================================ */
+
+export const radius = {
+ sm: 2, // Rarely used
+ md: 6, // Small elements
+ lg: 8, // Dropdowns, icon containers — rounded-lg
+ xl: 12, // Inputs, btn-green — rounded-xl
+ '2xl': 16, // Modals, form cards — rounded-2xl
+ '3xl': 24, // Brand tier cards — rounded-3xl
+ full: 9999, // Full pill — btn-primary, avatars, dots
+} as const;
+
+
+/* ============================================================
+ 5. SHADOWS
+ React Native requires separate iOS and Android shadow styles.
+ Use the spread operator to apply: { ...shadows.sm }
+ ============================================================ */
+
+export const shadows = {
+ sm: Platform.select({
+ ios: {
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 1 },
+ shadowOpacity: 0.05,
+ shadowRadius: 2,
+ },
+ android: { elevation: 1 },
+ }) as ViewStyle,
+
+ md: Platform.select({
+ ios: {
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 2 },
+ shadowOpacity: 0.10,
+ shadowRadius: 4,
+ },
+ android: { elevation: 3 },
+ }) as ViewStyle,
+
+ lg: Platform.select({
+ ios: {
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 4 },
+ shadowOpacity: 0.10,
+ shadowRadius: 8,
+ },
+ android: { elevation: 6 },
+ }) as ViewStyle,
+
+ xl: Platform.select({
+ ios: {
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 8 },
+ shadowOpacity: 0.10,
+ shadowRadius: 16,
+ },
+ android: { elevation: 12 },
+ }) as ViewStyle,
+
+ /**
+ * Brand card shadows — the most visually distinctive pattern.
+ * Offset yellow/green shadow used on the Free and Premium tier cards.
+ * Note: React Native doesn't support offset shadows the same way CSS does.
+ * These approximate the visual with a colored, offset shadow.
+ */
+ cardYellow: Platform.select({
+ ios: {
+ shadowColor: 'rgb(209, 230, 28)',
+ shadowOffset: { width: 10, height: 10 },
+ shadowOpacity: 0.9,
+ shadowRadius: 1,
+ },
+ android: { elevation: 8 }, // Android elevation doesn't support colored shadows
+ }) as ViewStyle,
+
+ cardGreen: Platform.select({
+ ios: {
+ shadowColor: 'rgb(115, 179, 19)',
+ shadowOffset: { width: 10, height: 10 },
+ shadowOpacity: 0.9,
+ shadowRadius: 1,
+ },
+ android: { elevation: 8 },
+ }) as ViewStyle,
+} as const;
+
+
+/* ============================================================
+ 6. ANIMATION DURATIONS
+ Use with React Native's Animated API or react-native-reanimated.
+ Values in milliseconds.
+ ============================================================ */
+
+export const duration = {
+ fast: 150, // Modal entry, snappy micro-interactions
+ base: 300, // Nav transitions, card hover equivalents
+ slow: 500, // Button color transitions
+} as const;
+
+
+/* ============================================================
+ 7. COMPONENT STYLE PRESETS
+ Ready-to-use StyleSheet-compatible objects for common patterns.
+ Spread into your StyleSheet.create() definitions.
+ ============================================================ */
+
+/**
+ * Button: Primary
+ * Dark pill CTA. Equivalent to .btn-primary on web.
+ * Usage: "Donate", "Join Now!", "Get Started!"
+ */
+export const btnPrimaryStyle = {
+ backgroundColor: colors.dark,
+ borderRadius: radius.full,
+ borderWidth: 2,
+ borderColor: colors.dark,
+ paddingVertical: spacing[3],
+ paddingHorizontal: spacing[8],
+ alignItems: 'center' as const,
+ justifyContent: 'center' as const,
+};
+
+export const btnPrimaryTextStyle: TextStyle = {
+ color: colors.light,
+ fontFamily: fontFamily.bold,
+ fontSize: fontSize.base,
+ fontWeight: fontWeight.bold,
+ lineHeight: getLineHeight(fontSize.base, lineHeight.relaxed),
+};
+
+/**
+ * Button: Green
+ * Primary brand green rounded button. Equivalent to .btn-green on web.
+ * Usage: "Enter", "Start Lesson", "Let's Go!"
+ */
+export const btnGreenStyle = {
+ backgroundColor: colors.primary,
+ borderRadius: radius.xl,
+ paddingVertical: spacing[3],
+ paddingHorizontal: spacing[8],
+ alignItems: 'center' as const,
+ justifyContent: 'center' as const,
+ ...shadows.md,
+};
+
+export const btnGreenTextStyle: TextStyle = {
+ color: colors.light,
+ fontFamily: fontFamily.bold,
+ fontSize: fontSize.xl,
+ fontWeight: fontWeight.bold,
+};
+
+/**
+ * Input: Default
+ * Rounded input with brand focus/error states.
+ */
+export const inputBaseStyle = {
+ width: '100%' as const,
+ borderRadius: radius.xl,
+ borderWidth: 2,
+ borderColor: colors.borderLight,
+ paddingVertical: spacing[3],
+ paddingHorizontal: spacing[4],
+ backgroundColor: '#ffffff',
+ color: colors.dark,
+ fontSize: fontSize.sm,
+ fontFamily: fontFamily.regular,
+};
+
+export const inputFocusStyle = {
+ borderColor: colors.primary,
+};
+
+export const inputErrorStyle = {
+ borderColor: colors.red,
+};
+
+/**
+ * Card: Content (subtle)
+ * Equivalent to .card on web. Activity entries, list items.
+ */
+export const cardStyle = {
+ backgroundColor: colors.light,
+ borderRadius: radius.lg,
+ borderWidth: 1,
+ borderColor: colors.borderLight,
+ padding: spacing[4],
+ ...shadows.sm,
+};
+
+/**
+ * Card: Brand Green (Free tier)
+ * Equivalent to .card-brand-green on web.
+ */
+export const cardBrandGreenStyle = {
+ backgroundColor: colors.primary,
+ borderRadius: radius['3xl'],
+ padding: spacing[8],
+ alignItems: 'center' as const,
+ ...shadows.cardYellow,
+};
+
+/**
+ * Card: Brand Light (Premium tier)
+ * Equivalent to .card-brand-light on web.
+ */
+export const cardBrandLightStyle = {
+ backgroundColor: colors.light,
+ borderRadius: radius['3xl'],
+ padding: spacing[8],
+ alignItems: 'center' as const,
+ ...shadows.cardGreen,
+};
+
+/**
+ * Card: Form / Auth panel
+ * Equivalent to .card-form on web. Login, signup.
+ */
+export const cardFormStyle = {
+ backgroundColor: colors.light,
+ borderRadius: radius['2xl'],
+ borderWidth: 2,
+ borderColor: colors.dark,
+ padding: spacing[8],
+ ...shadows.md,
+};
+
+/**
+ * Modal overlay
+ * Full-screen dark backdrop. Equivalent to .modal-overlay on web.
+ */
+export const modalOverlayStyle = {
+ flex: 1,
+ backgroundColor: colors.darkOverlay,
+ alignItems: 'center' as const,
+ justifyContent: 'center' as const,
+ padding: spacing[4],
+};
+
+/**
+ * Modal content panel
+ * Equivalent to .modal-content on web.
+ */
+export const modalContentStyle = {
+ backgroundColor: colors.light,
+ width: '100%' as const,
+ maxWidth: 384,
+ borderRadius: radius['2xl'],
+ padding: spacing[8],
+ alignItems: 'center' as const,
+ gap: spacing[5],
+ ...shadows.xl,
+};
+
+/**
+ * Avatar / Profile picture circle
+ */
+export const avatarStyle = {
+ width: 56,
+ height: 56,
+ borderRadius: radius.full,
+ backgroundColor: colors.light,
+ borderWidth: 2,
+ borderColor: colors.primary,
+ alignItems: 'center' as const,
+ justifyContent: 'center' as const,
+ ...shadows.sm,
+};
+
+/**
+ * Nav link text
+ * Equivalent to .nav-link on web.
+ */
+export const navLinkTextStyle: TextStyle = {
+ fontSize: fontSize.lg,
+ fontFamily: fontFamily.medium,
+ fontWeight: fontWeight.medium,
+ color: colors.dark,
+};
+
+/**
+ * Section heading
+ * Equivalent to .text-section-heading on web.
+ */
+export const sectionHeadingStyle: TextStyle = {
+ fontSize: fontSize['3xl'],
+ fontFamily: fontFamily.bold,
+ fontWeight: fontWeight.bold,
+ color: colors.dark,
+ textAlign: 'center',
+};
+
+/**
+ * Hero heading
+ * Equivalent to .text-hero on web.
+ */
+export const heroHeadingStyle: TextStyle = {
+ fontSize: fontSize['3xl'],
+ fontFamily: fontFamily.bold,
+ fontWeight: fontWeight.bold,
+ color: colors.dark,
+ lineHeight: getLineHeight(fontSize['3xl'], lineHeight.relaxed),
+};
+
+/**
+ * Body text — primary
+ */
+export const bodyTextStyle: TextStyle = {
+ fontSize: fontSize.base,
+ fontFamily: fontFamily.regular,
+ color: colors.dark,
+ lineHeight: getLineHeight(fontSize.base, lineHeight.relaxed),
+};
+
+/**
+ * Body text — secondary / descriptive
+ */
+export const bodySecondaryTextStyle: TextStyle = {
+ fontSize: fontSize.base,
+ fontFamily: fontFamily.regular,
+ color: colors.gray,
+ lineHeight: getLineHeight(fontSize.base, lineHeight.relaxed),
+};
+
+/**
+ * Label / metadata
+ * Equivalent to .text-label on web.
+ */
+export const labelTextStyle: TextStyle = {
+ fontSize: fontSize.xs,
+ fontFamily: fontFamily.bold,
+ fontWeight: fontWeight.bold,
+ color: colors.muted,
+ textTransform: 'uppercase',
+ letterSpacing: 1.2,
+};
+
+/**
+ * Error text
+ */
+export const errorTextStyle: TextStyle = {
+ fontSize: fontSize.sm,
+ fontFamily: fontFamily.bold,
+ fontWeight: fontWeight.bold,
+ color: colors.red,
+};
+
+/**
+ * Timeline dot (activity feed)
+ */
+export const timelineDotStyle = {
+ width: 12,
+ height: 12,
+ borderRadius: radius.full,
+ backgroundColor: colors.primary,
+ borderWidth: 2,
+ borderColor: colors.light,
+ ...shadows.sm,
+};
+
+
+/* ============================================================
+ 8. SCREEN LAYOUT CONSTANTS
+ Common layout values for screen-level containers.
+ ============================================================ */
+
+export const layout = {
+ screenPaddingH: spacing[6], // Horizontal padding for most screens (24px)
+ screenPaddingV: spacing[8], // Vertical padding for most screens (32px)
+ sectionSpacing: spacing[12], // Space between major sections (48px)
+ cardGap: spacing[4], // Gap between cards in a list (16px)
+ formFieldGap: spacing[6], // Gap between form fields (24px)
+ labelFieldGap: spacing[2], // Gap between label and input (8px)
+ maxFormWidth: 384, // Max width for auth/form screens (max-w-sm equivalent)
+ navBarHeight: 96, // NavBar height — h-24 equivalent
+} as const;
+
+
+/* ============================================================
+ 9. CHESS-SPECIFIC TOKENS
+ Values used across the chess board UI components.
+ ============================================================ */
+
+export const chess = {
+ boardBg: '#f5f9f0',
+ boardDotColor: 'rgba(127, 204, 38, 0.28)',
+ boardDotSize: 22, // Background dot grid spacing
+ hatchColor: 'rgba(127, 204, 38, 0.07)',
+ highlightSquare: 'rgba(127, 204, 38, 0.4)',
+ lastMoveDark: '#2D6A4F', // Dark move cell background
+} as const;
diff --git a/documentation/design.md b/documentation/design.md
new file mode 100644
index 00000000..9978889c
--- /dev/null
+++ b/documentation/design.md
@@ -0,0 +1,583 @@
+# Y STEM and Chess — design.md
+
+> **For AI coding agents:** Load this file alongside `design-tokens.css` before generating any UI for the Y STEM and Chess platform. This document is the authoritative source of truth for visual language, component patterns, copywriting, and layout decisions. Do not invent design choices — use only what is documented here.
+
+---
+
+## 1. Brand Identity
+
+**Organization:** Y STEM and Chess Inc. — a nonprofit in Boise, Idaho.
+**Mission:** Empower socially and economically underserved children to pursue STEM careers through chess, math, computer science, and mentoring.
+**Platform:** An educational web app where students learn, play chess, take lessons, solve puzzles, and track progress with a mentor.
+
+### Tone
+- **Encouraging and accessible** — students are often young and underserved; the platform should feel safe and welcoming
+- **Warm but professional** — not childish, not corporate
+- **Action-oriented** — verbs drive CTAs: Play, Learn, Empower, Join, Get Started, Donate
+- **Inclusive** — "Everyone is included. Everyone is welcome." is a core brand phrase
+
+### Three Core Words
+`Play` · `Learn` · `Empower`
+
+These appear in the footer and should be used as a lens when naming features or writing headings.
+
+---
+
+## 2. Color System
+
+All colors are defined as Tailwind tokens in `tailwind.config.js`. **Never use raw hex values in JSX or TSX — always use Tailwind tokens or CSS variables from `design-tokens.css`.**
+
+### Palette
+
+| Token | Hex | Usage |
+|---|---|---|
+| `primary` | `#7FCC26` | Brand green. CTAs, active states, accents, toolbar backgrounds, progress indicators, timeline dots, focus rings |
+| `secondary` | `#BFD99E` | Muted green. Hover states on SVG icons, inactive toolbar icons, supporting accent |
+| `soft` | `#E5F3D2` | Light green. Page background (with chess piece SVG pattern), card backgrounds, icon containers, scrollbar track |
+| `accent` | `#EAD94C` | Yellow. Active toolbar icon color, badge highlights, book card borders |
+| `dark` | `#1F1F1F` | Near-black. Primary text, navbar border, footer border, card borders, button bg for `btn-primary` |
+| `gray` | `#5C5C5C` | Secondary text. Body copy, nav link color (non-hover), dropdown items, timestamps, description text |
+| `muted` | `#8A8A8A` | Placeholder text, disabled states, uppercase labels in footer contact section |
+| `borderLight` | `#D6D6D6` | Borders, dividers, tab dividers, card borders in low-emphasis contexts |
+| `light` | `#F9FAF7` | Off-white. Navbar background, footer background, form backgrounds, modal backgrounds, card surfaces, dropdown surfaces |
+| `red` | `#D64545` | Errors, destructive actions, validation failure borders |
+| `redLight` | `#F5E9E9` | Error state backgrounds (e.g., error modal icon container) |
+
+### Color Rules
+
+**Do:**
+- Use `primary` for interactive elements that signal "do this" (buttons, links on hover, focus rings)
+- Use `dark` on `light` for primary text — maximum contrast
+- Use `gray` on `light` for secondary/descriptive text
+- Use `soft` as the default page background (it includes a chess-piece SVG pattern)
+- Use `accent` only for highlights and gamification elements — not for primary actions
+- Use `primary/20` or `primary/30` (Tailwind opacity modifier) for subtle icon container tints
+
+**Don't:**
+- Use hardcoded hex values anywhere in JSX/TSX
+- Use `primary` as a text color on `soft` backgrounds (insufficient contrast at small sizes)
+- Use `accent` for error or destructive states — that's `red` / `redLight`
+- Use `secondary` as a background for large areas — it's for hover states and icon tints
+- Mix `gray` and `muted` arbitrarily — `gray` is for body content, `muted` is for metadata/labels
+
+---
+
+## 3. Typography
+
+### Font
+
+**Family:** `Lato`
+**Fallbacks:** `system-ui, -apple-system, BlinkMacSystemFont, sans-serif`
+**Loaded from:** Google Fonts (weights 400, 500, 700)
+
+```html
+
+```
+
+The body always receives `font-family: Lato, ...` via the Tailwind `font-sans` extension. Do not apply a different font family to any element.
+
+### Type Scale (observed in production)
+
+| Role | Tailwind | Size | Weight | Color | Notes |
+|---|---|---|---|---|---|
+| Hero H1 | `text-3xl md:text-4xl font-bold` | 30–36px | 700 | `text-dark` | Left-aligned, `leading-relaxed` |
+| Section H2 | `text-3xl md:text-4xl font-bold` | 30–36px | 700 | `text-dark` | Often centered |
+| Card H3 | `text-xl md:text-2xl font-bold` | 20–24px | 700 | `text-dark` | |
+| Nav links | `text-lg font-medium` | 18px | 500 | `text-dark` | Hover: `text-primary` |
+| Body large | `text-xl md:text-2xl` | 20–24px | 400 | `text-gray` | Used in hero subtext |
+| Body default | `text-base` | 16px | 400 | `text-dark` or `text-gray` | |
+| Body small | `text-sm` | 14px | 400 | `text-gray` | Descriptions, timestamps |
+| Caption / Label | `text-xs font-bold uppercase tracking-widest` | 12px | 700 | `text-muted` | Footer copyright, metadata labels |
+| Dropdown section header | `text-base font-bold uppercase tracking-wide` | 16px | 700 | `text-dark` | |
+
+### Typography Rules
+
+- **Line height:** Use `leading-relaxed` (1.625) for body text blocks. Use `leading-normal` for default. Use `leading-tight` only for display/hero headings where line-height would cause too much space.
+- **Bold usage:** `font-bold` (700) for headings and labels. `font-semibold` (600) for button text. `font-medium` (500) for nav links and interactive text. `font-normal` (400) for body copy.
+- **Uppercase:** Only use for labels, metadata, section sub-labels, and the footer tagline. Never uppercase primary headings or CTA text.
+- **Text colors on primary backgrounds:** Use `text-light` (`#F9FAF7`) for text placed on `bg-primary` green backgrounds.
+
+---
+
+## 4. Layout & Spacing
+
+### Container Widths
+
+| Context | Tailwind | Notes |
+|---|---|---|
+| Standard page sections | `max-w-7xl mx-auto px-6 md:px-8` | Hero, books, sponsors |
+| Full-bleed dashboard | `max-w-screen-2xl mx-auto px-6` | Student profile, mentor dashboard |
+| Narrow forms | `max-w-sm` | Login, signup — centered with `flex items-center justify-center` |
+| Modal content | `max-w-sm` | Always centered in a full-screen overlay |
+| Dropdown menus | `w-64` (About Us), `w-48` (Profile) | Absolute positioned |
+
+### Page Structure
+
+Every page follows this shell:
+```
+