diff --git a/apps/web/src/lib/ui/atoms/Badge.svelte b/apps/web/src/lib/ui/atoms/Badge.svelte
new file mode 100644
index 0000000..a405089
--- /dev/null
+++ b/apps/web/src/lib/ui/atoms/Badge.svelte
@@ -0,0 +1,35 @@
+
+
+
+
+
diff --git a/apps/web/src/lib/ui/atoms/Button.svelte b/apps/web/src/lib/ui/atoms/Button.svelte
new file mode 100644
index 0000000..384a979
--- /dev/null
+++ b/apps/web/src/lib/ui/atoms/Button.svelte
@@ -0,0 +1,53 @@
+
+
+
+
+
diff --git a/apps/web/src/lib/ui/atoms/Skeleton.svelte b/apps/web/src/lib/ui/atoms/Skeleton.svelte
new file mode 100644
index 0000000..697b046
--- /dev/null
+++ b/apps/web/src/lib/ui/atoms/Skeleton.svelte
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/apps/web/src/lib/ui/atoms/VisuallyHidden.svelte b/apps/web/src/lib/ui/atoms/VisuallyHidden.svelte
new file mode 100644
index 0000000..72a51a9
--- /dev/null
+++ b/apps/web/src/lib/ui/atoms/VisuallyHidden.svelte
@@ -0,0 +1,11 @@
+
+
+
diff --git a/apps/web/src/lib/ui/data/GroupCard.svelte b/apps/web/src/lib/ui/data/GroupCard.svelte
new file mode 100644
index 0000000..26295ce
--- /dev/null
+++ b/apps/web/src/lib/ui/data/GroupCard.svelte
@@ -0,0 +1,52 @@
+
+
+
+
+
+ {#if previews?.length}
+
+
Sin responsable (hasta 3):
+
+ {#each previews as t}
+ -
+ #{t.display_code ?? t.id} — {t.description}
+ {#if t.due_date} (vence: {t.due_date}){/if}
+
+ {/each}
+
+
+ {/if}
+
+
+
diff --git a/apps/web/src/lib/ui/data/TaskItem.svelte b/apps/web/src/lib/ui/data/TaskItem.svelte
new file mode 100644
index 0000000..6f6a1e1
--- /dev/null
+++ b/apps/web/src/lib/ui/data/TaskItem.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+ #{code}
+ {description}
+ {#if due_date}
+ {#if status === 'overdue'}
+ vence: {due_date}
+ {:else if status === 'soon'}
+ vence: {due_date}
+ {:else}
+ vence: {due_date}
+ {/if}
+ {/if}
+
+ {#if assignees?.length}
+
+ asignados: {assignees.join(', ')}
+
+ {/if}
+
+
+
diff --git a/apps/web/src/lib/ui/inputs/SegmentedControl.svelte b/apps/web/src/lib/ui/inputs/SegmentedControl.svelte
new file mode 100644
index 0000000..7e1780f
--- /dev/null
+++ b/apps/web/src/lib/ui/inputs/SegmentedControl.svelte
@@ -0,0 +1,45 @@
+
+
+
+ {#each options as opt}
+
+ {/each}
+
+
+
diff --git a/apps/web/src/lib/ui/inputs/TextField.svelte b/apps/web/src/lib/ui/inputs/TextField.svelte
new file mode 100644
index 0000000..aadcb58
--- /dev/null
+++ b/apps/web/src/lib/ui/inputs/TextField.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/apps/web/src/lib/ui/layout/AppShell.svelte b/apps/web/src/lib/ui/layout/AppShell.svelte
index 4bdb612..a65fb21 100644
--- a/apps/web/src/lib/ui/layout/AppShell.svelte
+++ b/apps/web/src/lib/ui/layout/AppShell.svelte
@@ -1,13 +1,14 @@