Drag or use arrows to rank your preferences. The optimizer uses this order to allocate credits.
{result.achieved.length > 0
? `${result.achieved.length} specialization${result.achieved.length > 1 ? 's' : ''} achieved`
diff --git a/openspec/changes/analysis-ux-improvements/.openspec.yaml b/openspec/changes/analysis-ux-improvements/.openspec.yaml
new file mode 100644
index 0000000..0b4defe
--- /dev/null
+++ b/openspec/changes/analysis-ux-improvements/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-03-01
diff --git a/openspec/changes/analysis-ux-improvements/design.md b/openspec/changes/analysis-ux-improvements/design.md
new file mode 100644
index 0000000..918fdae
--- /dev/null
+++ b/openspec/changes/analysis-ux-improvements/design.md
@@ -0,0 +1,43 @@
+## Context
+
+The app is a single-page React application for EMBA course planning. Users select courses from elective sets, rank specializations by priority, and an optimizer allocates credits to determine which specializations are achieved. The UI has three usability gaps identified in the proposal: terse algorithm descriptions, minimal loading feedback, and hidden credit breakdowns for achieved specializations.
+
+All three changes are scoped to existing React components with no new dependencies, API changes, or data model changes.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Make the optimization mode descriptions clear enough that users understand the practical trade-off without needing external documentation.
+- Provide immediate visual feedback via skeleton placeholders when analysis is in progress.
+- Ensure users always see credit breakdowns for achieved specializations without requiring discovery of click-to-expand.
+
+**Non-Goals:**
+- Redesigning the ModeToggle layout or switching to a different control type (dropdown, radio, etc.).
+- Adding a global progress bar or percentage indicator for the worker.
+- Making non-achieved specializations expandable.
+- Adding animation/transition effects to the skeleton loading.
+
+## Decisions
+
+### Algorithm explanations approach
+**Decision**: Replace the single-line `
` description below the segmented control with a multi-line explanation block that describes each mode in terms of its practical behavior and when to use it.
+
+**Rationale**: Users need to understand the trade-off (breadth vs. guarantee) to make an informed choice. A slightly longer description (2-3 sentences) directly below the active button conveys this without cluttering the UI. Alternative considered: tooltips on each button — rejected because they require hover (not mobile-friendly) and hide information by default.
+
+### Skeleton loading approach
+**Decision**: When `loading` is true and no `analysis` exists for a set, render skeleton placeholder rectangles in place of the course choice buttons. Replace the "analyzing..." text label with these visual placeholders.
+
+**Rationale**: Skeleton screens communicate that content is loading and will appear in-place, reducing perceived wait time. They also reserve layout space, preventing content jumps. Alternative considered: spinner overlay — rejected because it blocks interaction and doesn't communicate what's loading.
+
+**Implementation**: Render 2-3 rectangular `
` elements with a light pulsing background (`#e5e7eb` with CSS animation) sized to match the course choice buttons. No external library needed — a simple CSS keyframe animation suffices.
+
+### Achieved specializations default expanded
+**Decision**: Initialize the `expanded` state set to contain all achieved specialization IDs instead of an empty set. Update it whenever `result.achieved` changes.
+
+**Rationale**: The credit breakdown is the most useful information for achieved specializations — users shouldn't need to discover a click affordance to see it. Users can still click to collapse if they want a compact view. Alternative considered: removing the expand/collapse entirely — rejected because users may want the compact view once they've reviewed the breakdown.
+
+## Risks / Trade-offs
+
+- **Longer mode descriptions take space** → Kept to 2-3 sentences; acceptable given users only have two modes and this is a key decision point.
+- **Skeleton animation adds CSS** → Minimal; a single `@keyframes` rule via inline styles or a `