@flamingo-stack/openframe-frontend-core 0.0.202 → 0.0.203-snapshot.20260522034243

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/{chunk-OII2IERE.cjs → chunk-25LVV26X.cjs} +4 -4
  2. package/dist/chunk-25LVV26X.cjs.map +1 -0
  3. package/dist/{chunk-55HF462A.js → chunk-CPXLQ57U.js} +6 -7
  4. package/dist/chunk-CPXLQ57U.js.map +1 -0
  5. package/dist/{chunk-JIKTMXTZ.cjs → chunk-QQONFWAN.cjs} +945 -784
  6. package/dist/chunk-QQONFWAN.cjs.map +1 -0
  7. package/dist/{chunk-3B43AHYE.cjs → chunk-RMB5DVED.cjs} +6 -7
  8. package/dist/chunk-RMB5DVED.cjs.map +1 -0
  9. package/dist/{chunk-4ML3NA2L.js → chunk-XGL5FKIK.js} +4 -4
  10. package/dist/chunk-XGL5FKIK.js.map +1 -0
  11. package/dist/{chunk-IDULPYOU.js → chunk-ZXDILOFR.js} +1947 -1786
  12. package/dist/chunk-ZXDILOFR.js.map +1 -0
  13. package/dist/components/chat/chat-ticket-item.d.ts.map +1 -1
  14. package/dist/components/features/index.cjs +4 -4
  15. package/dist/components/features/index.js +3 -3
  16. package/dist/components/features/select-button.d.ts.map +1 -1
  17. package/dist/components/index.cjs +6 -4
  18. package/dist/components/index.cjs.map +1 -1
  19. package/dist/components/index.js +5 -3
  20. package/dist/components/navigation/index.cjs +4 -4
  21. package/dist/components/navigation/index.js +3 -3
  22. package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
  23. package/dist/components/resizable.d.ts +1 -1
  24. package/dist/components/shared/product-release/product-release-card-skeleton.d.ts.map +1 -1
  25. package/dist/components/shared/product-release/product-release-card.d.ts.map +1 -1
  26. package/dist/components/ui/button/split-button.d.ts.map +1 -1
  27. package/dist/components/ui/data-table/data-table-row.d.ts +16 -4
  28. package/dist/components/ui/data-table/data-table-row.d.ts.map +1 -1
  29. package/dist/components/ui/file-manager/index.cjs +52 -52
  30. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  31. package/dist/components/ui/file-manager/index.js +3 -3
  32. package/dist/components/ui/file-manager/index.js.map +1 -1
  33. package/dist/components/ui/floating-tooltip.d.ts +3 -1
  34. package/dist/components/ui/floating-tooltip.d.ts.map +1 -1
  35. package/dist/components/ui/index.cjs +6 -4
  36. package/dist/components/ui/index.cjs.map +1 -1
  37. package/dist/components/ui/index.d.ts +1 -0
  38. package/dist/components/ui/index.d.ts.map +1 -1
  39. package/dist/components/ui/index.js +5 -3
  40. package/dist/components/ui/input-trigger.d.ts.map +1 -1
  41. package/dist/components/ui/radio-group.d.ts.map +1 -1
  42. package/dist/components/ui/ticket-info-section.d.ts.map +1 -1
  43. package/dist/components/ui/ticket-note-card.d.ts.map +1 -1
  44. package/dist/components/ui/truncate-text.d.ts +33 -0
  45. package/dist/components/ui/truncate-text.d.ts.map +1 -0
  46. package/dist/components/user-summary-stub.d.ts.map +1 -1
  47. package/dist/hooks/index.cjs +2 -2
  48. package/dist/hooks/index.js +1 -1
  49. package/dist/index.cjs +6 -4
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.js +5 -3
  52. package/package.json +1 -1
  53. package/src/components/chat/chat-container.tsx +2 -2
  54. package/src/components/chat/chat-ticket-item.tsx +2 -3
  55. package/src/components/features/board/ticket-card.tsx +2 -2
  56. package/src/components/features/filters-dropdown.tsx +1 -1
  57. package/src/components/features/notifications/notification-tile.tsx +2 -2
  58. package/src/components/features/policy-configuration-panel.tsx +1 -1
  59. package/src/components/features/push-button-selector.tsx +1 -1
  60. package/src/components/features/select-button.tsx +2 -3
  61. package/src/components/features/video-bites-display.tsx +1 -1
  62. package/src/components/features/waitlist-form.tsx +1 -1
  63. package/src/components/filter-chip.tsx +1 -1
  64. package/src/components/layout/title-block.tsx +2 -2
  65. package/src/components/navigation/header-organization-filter.tsx +1 -1
  66. package/src/components/navigation/navigation-sidebar.tsx +107 -54
  67. package/src/components/platform/ScriptInfoSection.tsx +1 -1
  68. package/src/components/shared/onboarding/onboarding-step-card.tsx +2 -2
  69. package/src/components/shared/product-release/product-release-card-skeleton.tsx +58 -26
  70. package/src/components/shared/product-release/product-release-card.tsx +170 -133
  71. package/src/components/shared/product-release/release-detail-page.tsx +1 -1
  72. package/src/components/ui/assignee-dropdown.tsx +3 -3
  73. package/src/components/ui/autocomplete.tsx +2 -2
  74. package/src/components/ui/button/split-button.tsx +3 -5
  75. package/src/components/ui/checkbox-block.tsx +1 -1
  76. package/src/components/ui/data-table/data-table-row.tsx +82 -48
  77. package/src/components/ui/device-card-compact.tsx +2 -2
  78. package/src/components/ui/device-card.tsx +2 -2
  79. package/src/components/ui/entity-image.tsx +1 -1
  80. package/src/components/ui/field-wrapper.tsx +1 -1
  81. package/src/components/ui/file-manager/file-manager-table-row.tsx +2 -2
  82. package/src/components/ui/file-upload.tsx +2 -2
  83. package/src/components/ui/filter-list.tsx +1 -1
  84. package/src/components/ui/floating-tooltip.tsx +9 -5
  85. package/src/components/ui/hidden-tags-popup.tsx +1 -1
  86. package/src/components/ui/index.ts +1 -0
  87. package/src/components/ui/info-card.tsx +2 -2
  88. package/src/components/ui/input-trigger.tsx +1 -2
  89. package/src/components/ui/organization-card.tsx +3 -3
  90. package/src/components/ui/radio-group.tsx +2 -3
  91. package/src/components/ui/search-input.tsx +2 -2
  92. package/src/components/ui/service-card.tsx +3 -3
  93. package/src/components/ui/tag.tsx +1 -1
  94. package/src/components/ui/tags-manager.tsx +2 -2
  95. package/src/components/ui/ticket-attachments-list.tsx +1 -1
  96. package/src/components/ui/ticket-info-section.tsx +2 -3
  97. package/src/components/ui/ticket-note-card.tsx +4 -1
  98. package/src/components/ui/toaster.tsx +3 -3
  99. package/src/components/ui/truncate-text.tsx +116 -0
  100. package/src/components/user-summary-stub.tsx +32 -26
  101. package/src/components/vendor-display-button.tsx +1 -1
  102. package/src/stories/SplitButton.stories.tsx +7 -1
  103. package/dist/chunk-3B43AHYE.cjs.map +0 -1
  104. package/dist/chunk-4ML3NA2L.js.map +0 -1
  105. package/dist/chunk-55HF462A.js.map +0 -1
  106. package/dist/chunk-IDULPYOU.js.map +0 -1
  107. package/dist/chunk-JIKTMXTZ.cjs.map +0 -1
  108. package/dist/chunk-OII2IERE.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  "use client"
2
2
 
3
- import { useCallback, useLayoutEffect, useMemo, useState } from 'react'
3
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react'
4
4
  import { useLocalStorage } from '../../hooks/ui/use-local-storage'
5
- import { useLgUp } from '../../hooks/ui/use-media-query'
5
+ import { useLgUp, useMdUp } from '../../hooks/ui/use-media-query'
6
6
  import { NavigationSidebarConfig, NavigationSidebarItem } from '../../types/navigation'
7
7
  import { cn } from '../../utils'
8
8
  import { NavigationSidebarHeader } from './navigation-sidebar-header'
@@ -23,25 +23,57 @@ export interface NavigationSidebarProps {
23
23
  }
24
24
 
25
25
  export function NavigationSidebar({ config, disabled = false }: NavigationSidebarProps) {
26
+ const isMdUp = useMdUp() ?? false
26
27
  const isLgUp = useLgUp() ?? false
27
28
 
28
- // useLocalStorage reads from localStorage first, then falls back to this value
29
- const [minimized, setMinimized] = useLocalStorage<boolean>(
29
+ // Tablet = md viewport but not lg. On tablet the sidebar floats over the
30
+ // content area (overlay) instead of pushing it like on desktop.
31
+ const isTablet = isMdUp && !isLgUp
32
+
33
+ // Desktop preference persists across sessions. Tablet state is in-memory
34
+ // only so entering tablet always starts minimized without clobbering the
35
+ // user's desktop choice.
36
+ const [desktopMinimized, setDesktopMinimized] = useLocalStorage<boolean>(
30
37
  STORAGE_KEY,
31
- !isLgUp || (config.minimized ?? false)
38
+ config.minimized ?? false,
32
39
  )
40
+ const [tabletMinimized, setTabletMinimized] = useState(true)
41
+
42
+ useEffect(() => {
43
+ if (isTablet) setTabletMinimized(true)
44
+ }, [isTablet])
45
+
46
+ const minimized = isTablet ? tabletMinimized : desktopMinimized
33
47
 
34
48
  // Enable transitions only after the correct width is painted
35
49
  const [transitionsEnabled, setTransitionsEnabled] = useState(false)
36
50
 
37
- // On tablet (md but not lg), force minimized layout regardless of stored value
38
- const isMinimized = !isLgUp || minimized
39
- const showLabel = isLgUp && !minimized
51
+ const isOverlayOpen = isTablet && !minimized
52
+
53
+ const showLabel = !minimized
40
54
 
41
55
  const handleToggle = useCallback(() => {
42
- setMinimized(prev => !prev)
56
+ if (isTablet) {
57
+ setTabletMinimized(prev => !prev)
58
+ } else {
59
+ setDesktopMinimized(prev => !prev)
60
+ }
43
61
  config.onToggleMinimized?.()
44
- }, [setMinimized, config])
62
+ }, [isTablet, setDesktopMinimized, config])
63
+
64
+ const closeOverlay = useCallback(() => {
65
+ setTabletMinimized(true)
66
+ }, [])
67
+
68
+ // Dismiss the tablet overlay with Escape so it behaves like a transient panel
69
+ useEffect(() => {
70
+ if (!isOverlayOpen) return
71
+ const handleKeyDown = (e: KeyboardEvent) => {
72
+ if (e.key === 'Escape') closeOverlay()
73
+ }
74
+ document.addEventListener('keydown', handleKeyDown)
75
+ return () => document.removeEventListener('keydown', handleKeyDown)
76
+ }, [isOverlayOpen, closeOverlay])
45
77
 
46
78
  const handleItemClick = useCallback((item: NavigationSidebarItem, event?: React.MouseEvent) => {
47
79
  event?.stopPropagation()
@@ -58,14 +90,12 @@ export function NavigationSidebar({ config, disabled = false }: NavigationSideba
58
90
  secondaryItems: config.items.filter(item => item.section === 'secondary'),
59
91
  }), [config.items])
60
92
 
61
- const sidebarWidth = useMemo(() => {
62
- if (isLgUp === undefined) {
63
- return `${MINIMIZED_WIDTH}px`
64
- }
65
- return isMinimized ? `${MINIMIZED_WIDTH}px` : `${EXPANDED_WIDTH}px`
66
- }, [isLgUp, isMinimized])
93
+ const sidebarWidth = useMemo(
94
+ () => (minimized ? `${MINIMIZED_WIDTH}px` : `${EXPANDED_WIDTH}px`),
95
+ [minimized],
96
+ )
67
97
 
68
- const isHydrated = isLgUp !== undefined
98
+ const isHydrated = isMdUp !== undefined && isLgUp !== undefined
69
99
 
70
100
  useLayoutEffect(() => {
71
101
  if (isHydrated && !transitionsEnabled) {
@@ -77,36 +107,47 @@ export function NavigationSidebar({ config, disabled = false }: NavigationSideba
77
107
  }, [isHydrated, transitionsEnabled])
78
108
 
79
109
  return (
80
- <aside
81
- className={cn(
82
- "flex-col h-full hidden md:flex",
83
- "bg-ods-card border-r border-ods-border",
84
- transitionsEnabled && "transition-[width] duration-300",
85
- config.className,
110
+ <>
111
+ {/* Backdrop scrim — only visible on tablet while the overlay is open */}
112
+ <div
113
+ className={cn(
114
+ "fixed inset-0 z-[40] bg-black/50",
115
+ "hidden md:block lg:hidden",
116
+ "transition-opacity duration-300",
117
+ isOverlayOpen ? "opacity-100" : "opacity-0 pointer-events-none",
118
+ )}
119
+ onClick={closeOverlay}
120
+ aria-hidden="true"
121
+ />
122
+
123
+ {/* Flex-flow placeholder — reserves the collapsed 56px slot on tablet so
124
+ the main content keeps its position while the sidebar floats above it */}
125
+ {isTablet && (
126
+ <div
127
+ className="h-full hidden md:block flex-shrink-0"
128
+ style={{ width: `${MINIMIZED_WIDTH}px` }}
129
+ aria-hidden="true"
130
+ />
86
131
  )}
87
- style={{ width: sidebarWidth }}
88
- aria-label="Main navigation sidebar"
89
- >
90
- {isHydrated && (
91
- <>
92
- <NavigationSidebarHeader minimized={isMinimized} />
93
-
94
- <div className="flex-1 flex flex-col justify-between py-4">
95
- <nav className="flex flex-col" aria-label="Primary navigation">
96
- {primaryItems.map(item => (
97
- <NavigationSidebarItemButton
98
- key={item.id}
99
- item={item}
100
- showLabel={showLabel}
101
- disabled={disabled}
102
- onClick={handleItemClick}
103
- />
104
- ))}
105
- </nav>
106
-
107
- {secondaryItems.length > 0 && (
108
- <nav className="flex flex-col" aria-label="Secondary navigation">
109
- {secondaryItems.map(item => (
132
+
133
+ <aside
134
+ className={cn(
135
+ "flex-col hidden md:flex flex-shrink-0",
136
+ "bg-ods-card border-r border-ods-border",
137
+ isTablet ? "fixed top-0 left-0 h-screen z-[45]" : "relative h-full",
138
+ transitionsEnabled && "transition-[width] duration-300",
139
+ config.className,
140
+ )}
141
+ style={{ width: sidebarWidth }}
142
+ aria-label="Main navigation sidebar"
143
+ >
144
+ {isHydrated && (
145
+ <>
146
+ <NavigationSidebarHeader minimized={minimized} />
147
+
148
+ <div className="flex-1 flex flex-col justify-between py-4 overflow-y-auto">
149
+ <nav className="flex flex-col" aria-label="Primary navigation">
150
+ {primaryItems.map(item => (
110
151
  <NavigationSidebarItemButton
111
152
  key={item.id}
112
153
  item={item}
@@ -116,18 +157,30 @@ export function NavigationSidebar({ config, disabled = false }: NavigationSideba
116
157
  />
117
158
  ))}
118
159
  </nav>
119
- )}
120
- </div>
121
160
 
122
- {isLgUp && (
161
+ {secondaryItems.length > 0 && (
162
+ <nav className="flex flex-col" aria-label="Secondary navigation">
163
+ {secondaryItems.map(item => (
164
+ <NavigationSidebarItemButton
165
+ key={item.id}
166
+ item={item}
167
+ showLabel={showLabel}
168
+ disabled={disabled}
169
+ onClick={handleItemClick}
170
+ />
171
+ ))}
172
+ </nav>
173
+ )}
174
+ </div>
175
+
123
176
  <NavigationSidebarToggle
124
- minimized={isMinimized}
177
+ minimized={minimized}
125
178
  showLabel={showLabel}
126
179
  onToggle={handleToggle}
127
180
  />
128
- )}
129
- </>
130
- )}
131
- </aside>
181
+ </>
182
+ )}
183
+ </aside>
184
+ </>
132
185
  )
133
186
  }
@@ -100,7 +100,7 @@ function InfoCell({ label, value, avatar, className }: InfoCellProps) {
100
100
 
101
101
  {/* Text content */}
102
102
  <div className="flex flex-col min-w-0">
103
- <span className="text-ods-text-primary font-['DM_Sans'] text-[14px] leading-[20px] md:text-[18px] md:leading-[24px] font-medium truncate">
103
+ <span className="text-ods-text-primary font-['DM_Sans'] text-[14px] leading-[20px] md:text-[18px] md:leading-[24px] font-medium truncate" title={value}>
104
104
  {value}
105
105
  </span>
106
106
  <span className="text-ods-text-secondary font-['DM_Sans'] text-[12px] leading-[16px] md:text-[14px] md:leading-[20px] font-medium truncate">
@@ -66,10 +66,10 @@ export function OnboardingStepCard({
66
66
  >
67
67
  {/* Left column - content */}
68
68
  <div className="flex-1 w-full md:w-auto min-w-0 flex flex-col justify-center gap-1">
69
- <h3 className="text-h4 text-ods-text-primary truncate">
69
+ <h3 className="text-h4 text-ods-text-primary truncate" title={step.title}>
70
70
  {step.title}
71
71
  </h3>
72
- <p className="font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary truncate h-[20px]">
72
+ <p className="font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary truncate h-[20px]" title={step.description}>
73
73
  {step.description}
74
74
  </p>
75
75
  </div>
@@ -15,15 +15,12 @@ export function ProductReleaseCardSkeleton({ className, size = 'default' }: Prod
15
15
  // ----- CATALOG branch — must match ProductReleaseCard size='catalog'.
16
16
  // Same outer frame (`bg-ods-system-greys-black border border-ods-border …
17
17
  // p-6 gap-4`). Inner: hero (16:9 cover + version pill + title + summary),
18
- // changelog strip placeholder (always rendered see note), metadata-grid
19
- // footer (4 cells via grid). Heights chosen to match the loaded card's
20
- // rendered metrics so the 5-card slot grid in `ReleasesList` doesn't
21
- // jump on resolve.
22
- //
23
- // Note: the loaded card hides the changelog strip when total === 0
24
- // (rare — most releases have at least one feature/fix/improvement).
25
- // The skeleton always renders the placeholder; net effect is a ~28px
26
- // shrink on empty-changelog releases. Documented tradeoff.
18
+ // changelog strip placeholder, metadata-grid footer (4 cells via grid).
19
+ // Heights chosen to match the loaded card's rendered metrics so the
20
+ // 5-card slot grid in `ReleasesList` doesn't jump on resolve. The
21
+ // loaded card ALSO always renders the changelog strip + a fixed 4-cell
22
+ // grid (with em-dash placeholders for missing values), so this
23
+ // skeleton's shape matches exactly with zero load-to-resolve reflow.
27
24
  if (size === 'catalog') {
28
25
  return (
29
26
  <div
@@ -34,27 +31,62 @@ export function ProductReleaseCardSkeleton({ className, size = 'default' }: Prod
34
31
  className,
35
32
  )}
36
33
  >
37
- {/* HERO */}
34
+ {/* HERO — placeholders use `bg-ods-border` (#3a3a3a) so they
35
+ contrast against the card's `bg-ods-system-greys-black`
36
+ (#212121) container. The metadata grid cells below use
37
+ `bg-ods-card` containers so `bg-ods-bg` placeholders work
38
+ there, but in the hero the card IS `bg-ods-card`-equivalent —
39
+ `bg-ods-bg` (#161616) is only 6 hex points darker than the
40
+ card and renders nearly invisible.
41
+
42
+ CRITICAL: title + summary use the SAME min-h containers as
43
+ the loaded card so total card height is byte-identical
44
+ between skeleton state and loaded state. Without this,
45
+ individual placeholder heights underrun the loaded card's
46
+ min-h reservations and the page jumps on resolve. */}
38
47
  <div className="flex flex-col md:flex-row gap-4 md:gap-6">
39
- <div className="w-full md:w-[256px] aspect-[16/9] bg-ods-bg rounded-lg flex-shrink-0" />
48
+ <div className="w-full md:w-[256px] aspect-[16/9] bg-ods-border rounded-lg flex-shrink-0" />
40
49
  <div className="flex-1 min-w-0 flex flex-col">
41
- {/* Version pill */}
42
- <div className="h-6 w-20 bg-ods-bg rounded mb-3" />
43
- {/* Title 2 lines */}
44
- <div className="h-7 w-3/4 bg-ods-bg rounded mb-2" />
45
- <div className="h-7 w-1/2 bg-ods-bg rounded mb-3" />
46
- {/* Summary 2 lines */}
47
- <div className="h-3 w-full bg-ods-bg/60 rounded mb-1" />
48
- <div className="h-3 w-5/6 bg-ods-bg/60 rounded" />
50
+ {/* Version pill — mirrors `flex items-center gap-3 mb-3` in
51
+ the loaded card. The loaded `<span text-lg>` renders at
52
+ line-height 28 px (Tailwind text-lg = 18 px / 28 px LH);
53
+ placeholder uses `h-7` (28 px) to match exactly. */}
54
+ <div className="flex items-center gap-3 mb-3">
55
+ <div className="h-7 w-20 bg-ods-border rounded" />
56
+ </div>
57
+ {/* Title container — SAME min-h as the loaded card so the
58
+ card height contributed by this region matches exactly. */}
59
+ <div className="min-h-[60px] md:min-h-[72px] flex flex-col gap-1.5 justify-start mb-3">
60
+ <div className="h-[25px] md:h-[30px] w-3/4 bg-ods-border rounded" />
61
+ <div className="h-[25px] md:h-[30px] w-1/2 bg-ods-border rounded" />
62
+ </div>
63
+ {/* Summary container — SAME min-h as the loaded card. The
64
+ 3 placeholder lines mirror the rendered 3-line clamp;
65
+ `bg-ods-border/70` keeps summary placeholders slightly
66
+ dimmer than title placeholders (primary vs secondary
67
+ text hierarchy). */}
68
+ <div className="min-h-[68px] md:min-h-[78px] flex flex-col gap-2 justify-start">
69
+ <div className="h-3 w-full bg-ods-border/70 rounded" />
70
+ <div className="h-3 w-11/12 bg-ods-border/70 rounded" />
71
+ <div className="h-3 w-5/6 bg-ods-border/70 rounded" />
72
+ </div>
49
73
  </div>
50
74
  </div>
51
75
 
52
- {/* CHANGELOG strip placeholder — always rendered */}
76
+ {/* CHANGELOG strip placeholder — always rendered. Inner
77
+ placeholder `h-5` mirrors the loaded strip's `text-sm`
78
+ line-height (20 px) so total height is consistent with the
79
+ loaded `border-t pt-3 + text content` (~32-33 px). */}
53
80
  <div className="border-t border-ods-border pt-3">
54
- <div className="h-4 w-2/3 bg-ods-bg/60 rounded" />
81
+ <div className="h-5 w-2/3 bg-ods-border/70 rounded" />
55
82
  </div>
56
83
 
57
- {/* METADATA GRID — 4-cell placeholder */}
84
+ {/* METADATA GRID — 4-cell placeholder. The grid cells use
85
+ `bg-ods-card` containers and `bg-ods-bg` placeholders, which
86
+ DO contrast correctly because the cells are brighter than
87
+ the placeholders. Inner content heights mirror the loaded
88
+ cells (`text-h4` ≈ 28 px + `DM_Sans 14px leading-20`) so
89
+ total grid height matches the loaded ~86 px. */}
58
90
  <div className="grid grid-cols-1 md:grid-cols-4 border border-ods-border rounded-md overflow-hidden w-full">
59
91
  {[0, 1, 2].map((i) => (
60
92
  <div
@@ -62,8 +94,8 @@ export function ProductReleaseCardSkeleton({ className, size = 'default' }: Prod
62
94
  className="bg-ods-card p-4 flex flex-col gap-3 border-b md:border-b-0 md:border-r border-ods-border"
63
95
  >
64
96
  <div className="flex flex-col gap-2">
65
- <div className="h-6 w-24 bg-ods-bg rounded" />
66
- <div className="h-3 w-16 bg-ods-bg/60 rounded" />
97
+ <div className="h-7 w-24 bg-ods-bg rounded" />
98
+ <div className="h-4 w-16 bg-ods-bg/60 rounded" />
67
99
  </div>
68
100
  </div>
69
101
  ))}
@@ -71,8 +103,8 @@ export function ProductReleaseCardSkeleton({ className, size = 'default' }: Prod
71
103
  <div className="bg-ods-card p-4 flex items-center gap-3">
72
104
  <div className="h-10 w-10 rounded-full bg-ods-bg shrink-0" />
73
105
  <div className="flex flex-col gap-2 flex-1 min-w-0">
74
- <div className="h-4 w-3/4 bg-ods-bg rounded" />
75
- <div className="h-3 w-1/2 bg-ods-bg/60 rounded" />
106
+ <div className="h-5 w-3/4 bg-ods-bg rounded" />
107
+ <div className="h-4 w-1/2 bg-ods-bg/60 rounded" />
76
108
  </div>
77
109
  </div>
78
110
  </div>