diff --git a/src/shared/lib/helpers/createResponsiveManager/createResponsiveManager.svelte.ts b/src/shared/lib/helpers/createResponsiveManager/createResponsiveManager.svelte.ts
new file mode 100644
index 0000000..1332c22
--- /dev/null
+++ b/src/shared/lib/helpers/createResponsiveManager/createResponsiveManager.svelte.ts
@@ -0,0 +1,231 @@
+// $shared/lib/createResponsiveManager.svelte.ts
+
+/**
+ * Breakpoint definitions following common device sizes
+ * Customize these values to match your design system
+ */
+export interface Breakpoints {
+ /** Mobile devices (portrait phones) */
+ mobile: number;
+ /** Tablet portrait */
+ tabletPortrait: number;
+ /** Tablet landscape */
+ tablet: number;
+ /** Desktop */
+ desktop: number;
+ /** Large desktop */
+ desktopLarge: number;
+}
+
+/**
+ * Default breakpoints (matches common Tailwind-like breakpoints)
+ */
+const DEFAULT_BREAKPOINTS: Breakpoints = {
+ mobile: 640, // sm
+ tabletPortrait: 768, // md
+ tablet: 1024, // lg
+ desktop: 1280, // xl
+ desktopLarge: 1536, // 2xl
+};
+
+/**
+ * Orientation type
+ */
+export type Orientation = 'portrait' | 'landscape';
+
+/**
+ * Creates a reactive responsive manager that tracks viewport size and breakpoints.
+ *
+ * Provides reactive getters for:
+ * - Current breakpoint detection (isMobile, isTablet, etc.)
+ * - Viewport dimensions (width, height)
+ * - Device orientation (portrait/landscape)
+ * - Custom breakpoint matching
+ *
+ * @param customBreakpoints - Optional custom breakpoint values
+ * @returns Responsive manager instance with reactive properties
+ *
+ * @example
+ * ```svelte
+ *
+ *
+ * {#if responsive.isMobile}
+ *
+ * {:else if responsive.isTablet}
+ *
+ * {:else}
+ *
+ * {/if}
+ *
+ *
Width: {responsive.width}px
+ *
Orientation: {responsive.orientation}
+ * ```
+ */
+export function createResponsiveManager(customBreakpoints?: Partial
) {
+ const breakpoints: Breakpoints = {
+ ...DEFAULT_BREAKPOINTS,
+ ...customBreakpoints,
+ };
+
+ // Reactive state
+ let width = $state(typeof window !== 'undefined' ? window.innerWidth : 0);
+ let height = $state(typeof window !== 'undefined' ? window.innerHeight : 0);
+
+ // Derived breakpoint states
+ const isMobile = $derived(width < breakpoints.mobile);
+ const isTabletPortrait = $derived(
+ width >= breakpoints.mobile && width < breakpoints.tabletPortrait,
+ );
+ const isTablet = $derived(
+ width >= breakpoints.tabletPortrait && width < breakpoints.desktop,
+ );
+ const isDesktop = $derived(
+ width >= breakpoints.desktop && width < breakpoints.desktopLarge,
+ );
+ const isDesktopLarge = $derived(width >= breakpoints.desktopLarge);
+
+ // Convenience groupings
+ const isMobileOrTablet = $derived(width < breakpoints.desktop);
+ const isTabletOrDesktop = $derived(width >= breakpoints.tabletPortrait);
+
+ // Orientation
+ const orientation = $derived(height > width ? 'portrait' : 'landscape');
+ const isPortrait = $derived(orientation === 'portrait');
+ const isLandscape = $derived(orientation === 'landscape');
+
+ // Touch device detection (best effort)
+ const isTouchDevice = $derived(
+ typeof window !== 'undefined'
+ && ('ontouchstart' in window || navigator.maxTouchPoints > 0),
+ );
+
+ /**
+ * Initialize responsive tracking
+ * Call this in an $effect or component mount
+ */
+ function init() {
+ if (typeof window === 'undefined') return;
+
+ const handleResize = () => {
+ width = window.innerWidth;
+ height = window.innerHeight;
+ };
+
+ // Use ResizeObserver for more accurate tracking
+ const resizeObserver = new ResizeObserver(handleResize);
+ resizeObserver.observe(document.documentElement);
+
+ // Fallback to window resize event
+ window.addEventListener('resize', handleResize, { passive: true });
+
+ // Initial measurement
+ handleResize();
+
+ return () => {
+ resizeObserver.disconnect();
+ window.removeEventListener('resize', handleResize);
+ };
+ }
+
+ /**
+ * Check if current width matches a custom breakpoint
+ * @param min - Minimum width (inclusive)
+ * @param max - Maximum width (exclusive)
+ */
+ function matches(min: number, max?: number): boolean {
+ if (max !== undefined) {
+ return width >= min && width < max;
+ }
+ return width >= min;
+ }
+
+ /**
+ * Get the current breakpoint name
+ */
+ const currentBreakpoint = $derived(
+ (() => {
+ if (isMobile) return 'mobile';
+ if (isTabletPortrait) return 'tabletPortrait';
+ if (isTablet) return 'tablet';
+ if (isDesktop) return 'desktop';
+ if (isDesktopLarge) return 'desktopLarge';
+ return 'xs'; // Fallback for very small screens
+ })(),
+ );
+
+ return {
+ // Dimensions
+ get width() {
+ return width;
+ },
+ get height() {
+ return height;
+ },
+
+ // Standard breakpoints
+ get isMobile() {
+ return isMobile;
+ },
+ get isTabletPortrait() {
+ return isTabletPortrait;
+ },
+ get isTablet() {
+ return isTablet;
+ },
+ get isDesktop() {
+ return isDesktop;
+ },
+ get isDesktopLarge() {
+ return isDesktopLarge;
+ },
+
+ // Convenience groupings
+ get isMobileOrTablet() {
+ return isMobileOrTablet;
+ },
+ get isTabletOrDesktop() {
+ return isTabletOrDesktop;
+ },
+
+ // Orientation
+ get orientation() {
+ return orientation;
+ },
+ get isPortrait() {
+ return isPortrait;
+ },
+ get isLandscape() {
+ return isLandscape;
+ },
+
+ // Device capabilities
+ get isTouchDevice() {
+ return isTouchDevice;
+ },
+
+ // Current breakpoint
+ get currentBreakpoint() {
+ return currentBreakpoint;
+ },
+
+ // Methods
+ init,
+ matches,
+
+ // Breakpoint values (for custom logic)
+ breakpoints,
+ };
+}
+
+export const responsiveManager = createResponsiveManager();
+
+if (typeof window !== 'undefined') {
+ responsiveManager.init();
+}
+
+/**
+ * Type for the responsive manager instance
+ */
+export type ResponsiveManager = ReturnType;
diff --git a/src/shared/lib/helpers/index.ts b/src/shared/lib/helpers/index.ts
index f325d4f..a5bcd1c 100644
--- a/src/shared/lib/helpers/index.ts
+++ b/src/shared/lib/helpers/index.ts
@@ -33,3 +33,9 @@ export {
} from './createCharacterComparison/createCharacterComparison.svelte';
export { createPersistentStore } from './createPersistentStore/createPersistentStore.svelte';
+
+export {
+ createResponsiveManager,
+ type ResponsiveManager,
+ responsiveManager,
+} from './createResponsiveManager/createResponsiveManager.svelte';
diff --git a/src/shared/lib/index.ts b/src/shared/lib/index.ts
index 7cde5c5..56882c0 100644
--- a/src/shared/lib/index.ts
+++ b/src/shared/lib/index.ts
@@ -6,6 +6,7 @@ export {
createEntityStore,
createFilter,
createPersistentStore,
+ createResponsiveManager,
createTypographyControl,
createVirtualizer,
type Entity,
@@ -14,6 +15,8 @@ export {
type FilterModel,
type LineData,
type Property,
+ type ResponsiveManager,
+ responsiveManager,
type TypographyControl,
type VirtualItem,
type Virtualizer,
@@ -23,3 +26,5 @@ export {
export { splitArray } from './utils';
export { springySlideFade } from './transitions';
+
+export { ResponsiveProvider } from './providers';
diff --git a/src/shared/lib/providers/ResponsiveProvider/ResponsiveProvider.svelte b/src/shared/lib/providers/ResponsiveProvider/ResponsiveProvider.svelte
new file mode 100644
index 0000000..6f205b1
--- /dev/null
+++ b/src/shared/lib/providers/ResponsiveProvider/ResponsiveProvider.svelte
@@ -0,0 +1,30 @@
+
+
+
+{@render children()}
diff --git a/src/shared/lib/providers/index.ts b/src/shared/lib/providers/index.ts
new file mode 100644
index 0000000..768deb7
--- /dev/null
+++ b/src/shared/lib/providers/index.ts
@@ -0,0 +1 @@
+export { default as ResponsiveProvider } from './ResponsiveProvider/ResponsiveProvider.svelte';