@flamingo-stack/openframe-frontend-core 0.0.406 → 0.0.407-snapshot.20260711133234

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 (167) hide show
  1. package/dist/{chunk-3KEBI6TP.cjs → chunk-2B6773QM.cjs} +1 -1
  2. package/dist/chunk-2B6773QM.cjs.map +1 -0
  3. package/dist/{chunk-TFDNJTBX.js → chunk-5HOII3WB.js} +4 -4
  4. package/dist/{chunk-E6YHDT3D.js → chunk-7Q52HP45.js} +2 -2
  5. package/dist/chunk-7Q52HP45.js.map +1 -0
  6. package/dist/{chunk-VZGU4BV6.cjs → chunk-A3RW7M6B.cjs} +29 -29
  7. package/dist/{chunk-VZGU4BV6.cjs.map → chunk-A3RW7M6B.cjs.map} +1 -1
  8. package/dist/{chunk-QAFRLO5N.cjs → chunk-CUN4CJUN.cjs} +10 -11
  9. package/dist/chunk-CUN4CJUN.cjs.map +1 -0
  10. package/dist/{chunk-6WMVBCNA.js → chunk-E4J5KKHH.js} +3 -3
  11. package/dist/{chunk-P43ZHPM6.cjs → chunk-F4KE5AZO.cjs} +40 -40
  12. package/dist/{chunk-P43ZHPM6.cjs.map → chunk-F4KE5AZO.cjs.map} +1 -1
  13. package/dist/{chunk-PQN5R5II.js → chunk-IK5AR6QG.js} +7 -7
  14. package/dist/{chunk-SOK32D6C.js → chunk-IVM47EGI.js} +346 -297
  15. package/dist/chunk-IVM47EGI.js.map +1 -0
  16. package/dist/{chunk-AYFWYOL6.js → chunk-J6M2G6TD.js} +7 -7
  17. package/dist/{chunk-NA7XJRWB.js → chunk-KFQXO7QB.js} +1 -1
  18. package/dist/chunk-KFQXO7QB.js.map +1 -0
  19. package/dist/{chunk-ISYVNPRT.cjs → chunk-KPGKNUJF.cjs} +42 -42
  20. package/dist/{chunk-ISYVNPRT.cjs.map → chunk-KPGKNUJF.cjs.map} +1 -1
  21. package/dist/{chunk-GNS65HNC.cjs → chunk-KRLBVBYU.cjs} +18 -18
  22. package/dist/{chunk-GNS65HNC.cjs.map → chunk-KRLBVBYU.cjs.map} +1 -1
  23. package/dist/{chunk-ZVUR3A33.js → chunk-KZPVN7AZ.js} +2 -2
  24. package/dist/{chunk-7RVSGGO6.js → chunk-L6OPVKVR.js} +6 -6
  25. package/dist/{chunk-OATWTTCI.js → chunk-LQWYXIKB.js} +6 -6
  26. package/dist/{chunk-COERBDG4.cjs → chunk-NEMUCNCG.cjs} +75 -75
  27. package/dist/{chunk-COERBDG4.cjs.map → chunk-NEMUCNCG.cjs.map} +1 -1
  28. package/dist/{chunk-PNJ5LMVK.js → chunk-NO2KT42M.js} +9 -10
  29. package/dist/{chunk-PNJ5LMVK.js.map → chunk-NO2KT42M.js.map} +1 -1
  30. package/dist/{chunk-LSPBPUQM.js → chunk-O5W26SCL.js} +2 -2
  31. package/dist/{chunk-VANFD4FX.cjs → chunk-RL344I7V.cjs} +7 -7
  32. package/dist/{chunk-VANFD4FX.cjs.map → chunk-RL344I7V.cjs.map} +1 -1
  33. package/dist/{chunk-CF3LBCNI.cjs → chunk-RPGFIUN3.cjs} +35 -35
  34. package/dist/{chunk-CF3LBCNI.cjs.map → chunk-RPGFIUN3.cjs.map} +1 -1
  35. package/dist/{chunk-LL4QQSAD.cjs → chunk-SOALFYU6.cjs} +479 -430
  36. package/dist/chunk-SOALFYU6.cjs.map +1 -0
  37. package/dist/{chunk-CCIBZ7TO.cjs → chunk-STGWQFYT.cjs} +5 -5
  38. package/dist/chunk-STGWQFYT.cjs.map +1 -0
  39. package/dist/{chunk-VIB4SGCD.cjs → chunk-T6ZUBXPA.cjs} +14 -14
  40. package/dist/{chunk-VIB4SGCD.cjs.map → chunk-T6ZUBXPA.cjs.map} +1 -1
  41. package/dist/{chunk-HJJXNMM7.cjs → chunk-V3EZQWHQ.cjs} +7 -7
  42. package/dist/{chunk-HJJXNMM7.cjs.map → chunk-V3EZQWHQ.cjs.map} +1 -1
  43. package/dist/{chunk-3KZXOLFK.js → chunk-VUW4G6SU.js} +4 -4
  44. package/dist/{chunk-JAPP2F4M.cjs → chunk-WGOATV3P.cjs} +77 -77
  45. package/dist/{chunk-JAPP2F4M.cjs.map → chunk-WGOATV3P.cjs.map} +1 -1
  46. package/dist/{chunk-SF4G7M6U.cjs → chunk-YRKPMYI3.cjs} +15 -15
  47. package/dist/{chunk-SF4G7M6U.cjs.map → chunk-YRKPMYI3.cjs.map} +1 -1
  48. package/dist/{chunk-XXG2Z2JT.js → chunk-ZF5O3KUQ.js} +3 -3
  49. package/dist/{chunk-C3NPMZBI.js → chunk-ZMFQWMM7.js} +3 -3
  50. package/dist/components/announcement-bar.d.ts.map +1 -1
  51. package/dist/components/case-studies/index.cjs +11 -10
  52. package/dist/components/case-studies/index.cjs.map +1 -1
  53. package/dist/components/case-studies/index.js +5 -4
  54. package/dist/components/case-studies/index.js.map +1 -1
  55. package/dist/components/chat/index.cjs +5 -4
  56. package/dist/components/chat/index.cjs.map +1 -1
  57. package/dist/components/chat/index.js +4 -3
  58. package/dist/components/chat/quick-action-chip.d.ts +11 -2
  59. package/dist/components/chat/quick-action-chip.d.ts.map +1 -1
  60. package/dist/components/contact/index.cjs +6 -5
  61. package/dist/components/contact/index.cjs.map +1 -1
  62. package/dist/components/contact/index.js +5 -4
  63. package/dist/components/docs/index.cjs +8 -8
  64. package/dist/components/docs/index.js +7 -7
  65. package/dist/components/embeds/index.cjs +6 -5
  66. package/dist/components/embeds/index.cjs.map +1 -1
  67. package/dist/components/embeds/index.js +5 -4
  68. package/dist/components/embeds/reddit-embed-client.d.ts.map +1 -1
  69. package/dist/components/faq/index.cjs +7 -6
  70. package/dist/components/faq/index.cjs.map +1 -1
  71. package/dist/components/faq/index.js +6 -5
  72. package/dist/components/features/index.cjs +5 -4
  73. package/dist/components/features/index.cjs.map +1 -1
  74. package/dist/components/features/index.js +4 -3
  75. package/dist/components/help-center-pages/index.cjs +24 -24
  76. package/dist/components/help-center-pages/index.js +15 -15
  77. package/dist/components/index.cjs +186 -180
  78. package/dist/components/index.cjs.map +1 -1
  79. package/dist/components/index.d.ts +1 -0
  80. package/dist/components/index.d.ts.map +1 -1
  81. package/dist/components/index.js +39 -33
  82. package/dist/components/index.js.map +1 -1
  83. package/dist/components/media-carousel.d.ts +28 -4
  84. package/dist/components/media-carousel.d.ts.map +1 -1
  85. package/dist/components/navigation/index.cjs +5 -4
  86. package/dist/components/navigation/index.cjs.map +1 -1
  87. package/dist/components/navigation/index.js +4 -3
  88. package/dist/components/onboarding-guides/index.cjs +9 -9
  89. package/dist/components/onboarding-guides/index.js +8 -8
  90. package/dist/components/related-content/index.cjs +7 -6
  91. package/dist/components/related-content/index.cjs.map +1 -1
  92. package/dist/components/related-content/index.js +6 -5
  93. package/dist/components/tickets/index.cjs +8 -8
  94. package/dist/components/tickets/index.js +7 -7
  95. package/dist/components/ui/index.cjs +5 -4
  96. package/dist/components/ui/index.cjs.map +1 -1
  97. package/dist/components/ui/index.js +4 -3
  98. package/dist/components/ui/tag.d.ts +3 -2
  99. package/dist/components/ui/tag.d.ts.map +1 -1
  100. package/dist/contexts/endpoints-runtime-context.d.ts +1 -1
  101. package/dist/contexts/endpoints-runtime-context.d.ts.map +1 -1
  102. package/dist/contexts/index.cjs +2 -2
  103. package/dist/contexts/index.js +1 -1
  104. package/dist/hooks/index.cjs +3 -3
  105. package/dist/hooks/index.js +2 -2
  106. package/dist/hooks/use-self-fetch.d.ts.map +1 -1
  107. package/dist/index.cjs +5 -4
  108. package/dist/index.cjs.map +1 -1
  109. package/dist/index.js +6 -5
  110. package/dist/types/announcement.cjs.map +1 -1
  111. package/dist/types/announcement.d.ts +0 -6
  112. package/dist/types/announcement.d.ts.map +1 -1
  113. package/dist/types/announcement.js.map +1 -1
  114. package/dist/types/index.cjs.map +1 -1
  115. package/dist/types/index.js.map +1 -1
  116. package/dist/utils/announcement-storage.d.ts +3 -0
  117. package/dist/utils/announcement-storage.d.ts.map +1 -1
  118. package/dist/utils/app-config.d.ts.map +1 -1
  119. package/dist/utils/color-analysis.d.ts +0 -4
  120. package/dist/utils/color-analysis.d.ts.map +1 -1
  121. package/dist/utils/index.cjs +186 -177
  122. package/dist/utils/index.cjs.map +1 -1
  123. package/dist/utils/index.js +185 -176
  124. package/dist/utils/index.js.map +1 -1
  125. package/dist/utils/media-carousel-utils-stub.d.ts +3 -1
  126. package/dist/utils/media-carousel-utils-stub.d.ts.map +1 -1
  127. package/dist/utils/ods-color-utils.d.ts +2 -1
  128. package/dist/utils/ods-color-utils.d.ts.map +1 -1
  129. package/package.json +1 -1
  130. package/src/components/announcement-bar.tsx +38 -21
  131. package/src/components/chat/quick-action-chip.tsx +18 -4
  132. package/src/components/embeds/reddit-embed-client.tsx +0 -3
  133. package/src/components/index.ts +5 -0
  134. package/src/components/media-carousel.tsx +195 -149
  135. package/src/components/ui/tag.tsx +21 -3
  136. package/src/contexts/endpoints-runtime-context.tsx +1 -1
  137. package/src/hooks/use-self-fetch.ts +10 -9
  138. package/src/stories/AnnouncementBar.stories.tsx +8 -14
  139. package/src/styles/ods-design-tokens.css +2 -0
  140. package/src/types/announcement.ts +0 -8
  141. package/src/utils/announcement-storage.ts +17 -0
  142. package/src/utils/app-config.ts +3 -2
  143. package/src/utils/color-analysis.ts +5 -2
  144. package/src/utils/media-carousel-utils-stub.ts +3 -1
  145. package/src/utils/ods-color-utils.ts +4 -7
  146. package/dist/chunk-3KEBI6TP.cjs.map +0 -1
  147. package/dist/chunk-CCIBZ7TO.cjs.map +0 -1
  148. package/dist/chunk-E6YHDT3D.js.map +0 -1
  149. package/dist/chunk-LL4QQSAD.cjs.map +0 -1
  150. package/dist/chunk-NA7XJRWB.js.map +0 -1
  151. package/dist/chunk-QAFRLO5N.cjs.map +0 -1
  152. package/dist/chunk-SOK32D6C.js.map +0 -1
  153. package/dist/utils/media-carousel-utils.d.ts +0 -10
  154. package/dist/utils/media-carousel-utils.d.ts.map +0 -1
  155. package/src/utils/.media-carousel-utils.md +0 -31
  156. package/src/utils/media-carousel-utils.ts +0 -22
  157. /package/dist/{chunk-TFDNJTBX.js.map → chunk-5HOII3WB.js.map} +0 -0
  158. /package/dist/{chunk-6WMVBCNA.js.map → chunk-E4J5KKHH.js.map} +0 -0
  159. /package/dist/{chunk-PQN5R5II.js.map → chunk-IK5AR6QG.js.map} +0 -0
  160. /package/dist/{chunk-AYFWYOL6.js.map → chunk-J6M2G6TD.js.map} +0 -0
  161. /package/dist/{chunk-ZVUR3A33.js.map → chunk-KZPVN7AZ.js.map} +0 -0
  162. /package/dist/{chunk-7RVSGGO6.js.map → chunk-L6OPVKVR.js.map} +0 -0
  163. /package/dist/{chunk-OATWTTCI.js.map → chunk-LQWYXIKB.js.map} +0 -0
  164. /package/dist/{chunk-LSPBPUQM.js.map → chunk-O5W26SCL.js.map} +0 -0
  165. /package/dist/{chunk-3KZXOLFK.js.map → chunk-VUW4G6SU.js.map} +0 -0
  166. /package/dist/{chunk-XXG2Z2JT.js.map → chunk-ZF5O3KUQ.js.map} +0 -0
  167. /package/dist/{chunk-C3NPMZBI.js.map → chunk-ZMFQWMM7.js.map} +0 -0
@@ -1,5 +1,7 @@
1
1
  export interface MediaItem {
2
- id: string;
2
+ /** Optional stable key. The carousel keys slides by index; converters may
3
+ * omit this (hub vendor/profile/category converters all do). */
4
+ id?: string;
3
5
  type: 'image' | 'video' | 'youtube';
4
6
  src: string;
5
7
  alt?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"media-carousel-utils-stub.d.ts","sourceRoot":"","sources":["../../src/utils/media-carousel-utils-stub.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAE3E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAElE"}
1
+ {"version":3,"file":"media-carousel-utils-stub.d.ts","sourceRoot":"","sources":["../../src/utils/media-carousel-utils-stub.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB;qEACiE;IACjE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAE3E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAElE"}
@@ -75,7 +75,8 @@ export declare function usePlatformColors(platform?: Platform): {
75
75
  };
76
76
  /**
77
77
  * Picks a near-black or near-white text color with adequate contrast on `hex`.
78
- * Uses Rec. 601 luminance.
78
+ * Thin wrapper over `pickReadableTextColor` (color-analysis.ts) ONE
79
+ * light-or-dark decision formula (WCAG relative luminance) for the whole lib.
79
80
  */
80
81
  export declare function getReadableTextColor(hex: string): string;
81
82
  export declare const HEX_PATTERN: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"ods-color-utils.d.ts","sourceRoot":"","sources":["../../src/utils/ods-color-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ods-color-utils.d.ts","sourceRoot":"","sources":["../../src/utils/ods-color-utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flamingo-stack/openframe-frontend-core",
3
- "version": "0.0.406",
3
+ "version": "0.0.407-snapshot.20260711133234",
4
4
  "description": "Shared design system and components for all Flamingo platforms",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useEffect, useMemo, useState } from 'react';
3
+ import { useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { X } from 'lucide-react';
5
5
  import { Button } from './ui/button';
6
6
  import { EntityIcon } from './icon-display';
@@ -9,7 +9,7 @@ import {
9
9
  isAnnouncementDismissed,
10
10
  clearLegacyAnnouncementCache,
11
11
  } from '../utils/announcement-storage';
12
- import type { AnnouncementBarProps, AnnouncementResponse } from '../types/announcement';
12
+ import type { Announcement, AnnouncementBarProps, AnnouncementResponse } from '../types/announcement';
13
13
  import { getAppType } from '../utils/app-config';
14
14
  import { useEndpointsRuntime } from '../contexts/endpoints-runtime-context';
15
15
  import { useSelfFetch } from '../hooks/use-self-fetch';
@@ -71,6 +71,15 @@ export function AnnouncementBar({
71
71
  });
72
72
  const announcement = data?.announcement ?? null;
73
73
 
74
+ // Hold the last non-null announcement so DEACTIVATION (a revalidation that
75
+ // returns null) collapses with the same 1fr->0fr animation as dismissal
76
+ // instead of unmounting in place (a hard 44px jump).
77
+ const lastAnnouncementRef = useRef<Announcement | null>(initialAnnouncement ?? null);
78
+ useEffect(() => {
79
+ if (announcement) lastAnnouncementRef.current = announcement;
80
+ }, [announcement]);
81
+ const displayAnnouncement = announcement ?? lastAnnouncementRef.current;
82
+
74
83
  // Expanded (height) state — initial value is a pure function of props so
75
84
  // the SSR HTML and the hydration render agree for every cohort.
76
85
  const [expandedState, setExpandedState] = useState<boolean>(() => initialAnnouncement != null);
@@ -109,6 +118,10 @@ export function AnnouncementBar({
109
118
  const handleDismiss = () => {
110
119
  if (previewMode || !announcement) return;
111
120
  dismissAnnouncement(platform, announcement.id);
121
+ // Release focus BEFORE the wrapper goes aria-hidden — a focused descendant
122
+ // inside an aria-hidden subtree strands screen-reader focus (and Chrome
123
+ // refuses to apply the attribute).
124
+ (document.activeElement as HTMLElement | null)?.blur?.();
112
125
  setExpandedState(false);
113
126
  };
114
127
 
@@ -119,7 +132,9 @@ export function AnnouncementBar({
119
132
  // via location.href / window.open (stored XSS).
120
133
  let safeUrl: string;
121
134
  try {
122
- const parsed = new URL(announcement.cta_url, window.location.origin);
135
+ // Resolve against the CURRENT page (not the origin) so path-relative and
136
+ // fragment CTAs keep their pre-guard semantics.
137
+ const parsed = new URL(announcement.cta_url, window.location.href);
123
138
  if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return;
124
139
  safeUrl = parsed.href;
125
140
  } catch {
@@ -130,10 +145,10 @@ export function AnnouncementBar({
130
145
  : (window.location.href = safeUrl);
131
146
  };
132
147
 
133
- // Nothing to show (and nothing to animate around): render nothing. The
134
- // dismissed/deactivated case keeps the element mounted at 0fr so the
135
- // collapse animates.
136
- if (!announcement) return null;
148
+ // Never had anything to show: render nothing. Dismissal AND deactivation
149
+ // keep the element mounted (displayAnnouncement holds the last content) at
150
+ // 0fr so the collapse animates.
151
+ if (!displayAnnouncement) return null;
137
152
 
138
153
  // Contrast is solved with the ODS THEME system, not color literals: the
139
154
  // admin background's tone selects which ODS theme scopes the bar's content
@@ -141,7 +156,7 @@ export function AnnouncementBar({
141
156
  // dark-toned needs the dark theme's). `.theme-light` / `.theme-dark` are
142
157
  // the design system's own scoping classes (ods-colors.css) and flip every
143
158
  // Tier-1 `--ods-*` primitive for descendants.
144
- const themeScope = pickReadableTextColor(announcement.background_color) === 'dark' ? 'theme-light' : 'theme-dark';
159
+ const themeScope = pickReadableTextColor(displayAnnouncement.background_color) === 'dark' ? 'theme-light' : 'theme-dark';
145
160
 
146
161
  // Inside the scope, colors reference Tier-1 theme primitives directly
147
162
  // (Tier-2 `--color-*` aliases resolve once at :root and do NOT re-resolve
@@ -152,7 +167,7 @@ export function AnnouncementBar({
152
167
  const barButtonClasses =
153
168
  'text-[color:var(--ods-system-greys-white)] hover:bg-[var(--ods-system-greys-black-hover)] active:bg-[var(--ods-system-greys-black-action)]';
154
169
 
155
- const hasCta = Boolean(announcement.cta_enabled && announcement.cta_url);
170
+ const hasCta = Boolean(displayAnnouncement.cta_enabled && displayAnnouncement.cta_url && displayAnnouncement.cta_text);
156
171
 
157
172
  return (
158
173
  <div
@@ -171,9 +186,11 @@ export function AnnouncementBar({
171
186
  compact CTA on the right, and a ghost-icon dismiss (design-system
172
187
  icon-sm: 32px target, >= the 24px WCAG 2.2 SC 2.5.8 AA floor).
173
188
  */}
174
- <div className={`min-h-0 overflow-hidden ${themeScope}`} style={{ backgroundColor: announcement.background_color }}>
189
+ <div className={`min-h-0 overflow-hidden ${themeScope}`} style={{ backgroundColor: displayAnnouncement.background_color }}>
175
190
  <div className="flex items-center w-full max-w-full min-h-11 text-[color:var(--ods-system-greys-white)]">
176
- {/* Mobile: Clickable content area, Desktop: Regular content */}
191
+ {/* Mobile: whole-bar tap target (touch-first by design; the CTA
192
+ Button below is the keyboard/AT path and is CSS-hidden < md —
193
+ known tradeoff carried from the original bar). */}
177
194
  <div
178
195
  className={`flex flex-row gap-2 md:gap-3 items-center pl-4 md:pl-6 py-1.5 flex-1 min-w-0 ${
179
196
  hasCta ? 'md:cursor-default cursor-pointer' : ''
@@ -190,9 +207,9 @@ export function AnnouncementBar({
190
207
  wins, else a library glyph by name (+ props), via <EntityIcon>. */}
191
208
  <EntityIcon
192
209
  icon={{
193
- name: announcement.icon_name || 'openframe-logo',
194
- url: announcement.icon_url,
195
- props: announcement.icon_props,
210
+ name: displayAnnouncement.icon_name || 'openframe-logo',
211
+ url: displayAnnouncement.icon_url,
212
+ props: displayAnnouncement.icon_props,
196
213
  }}
197
214
  size={24}
198
215
  className="relative shrink-0 w-5 h-5 md:w-6 md:h-6"
@@ -202,9 +219,9 @@ export function AnnouncementBar({
202
219
  truncating as one unit. Separator is a middot (house rule: no
203
220
  en/em dashes in copy). */}
204
221
  <p className="font-body flex-1 min-w-0 max-w-full text-[13px] md:text-sm leading-snug truncate mb-0">
205
- <span className="font-semibold">{announcement.title}</span>
206
- {announcement.description && (
207
- <span className="hidden sm:inline opacity-80"> · {announcement.description}</span>
222
+ <span className="font-semibold">{displayAnnouncement.title}</span>
223
+ {displayAnnouncement.description && (
224
+ <span className="hidden sm:inline opacity-80"> · {displayAnnouncement.description}</span>
208
225
  )}
209
226
  </p>
210
227
 
@@ -214,7 +231,7 @@ export function AnnouncementBar({
214
231
  admin color. The admin cta_button_* colors are NOT applied:
215
232
  they were designed for the legacy bespoke treatment. Hidden
216
233
  on mobile, where the whole bar is the tap target. */}
217
- {hasCta && announcement.cta_text && (
234
+ {hasCta && displayAnnouncement.cta_text && (
218
235
  <div className="hidden md:flex flex-shrink-0 ml-1">
219
236
  <Button
220
237
  onClick={handleCtaClick}
@@ -223,10 +240,10 @@ export function AnnouncementBar({
223
240
  className={barButtonClasses}
224
241
  tabIndex={expanded ? 0 : -1}
225
242
  leftIcon={
226
- announcement.cta_show_icon && announcement.cta_icon_name
243
+ displayAnnouncement.cta_show_icon && displayAnnouncement.cta_icon_name
227
244
  ? (
228
245
  <EntityIcon
229
- icon={{ name: announcement.cta_icon_name, props: announcement.cta_icon_props }}
246
+ icon={{ name: displayAnnouncement.cta_icon_name, props: displayAnnouncement.cta_icon_props }}
230
247
  size={14}
231
248
  className="w-3.5 h-3.5"
232
249
  />
@@ -234,7 +251,7 @@ export function AnnouncementBar({
234
251
  : undefined
235
252
  }
236
253
  >
237
- {announcement.cta_text}
254
+ {displayAnnouncement.cta_text}
238
255
  </Button>
239
256
  </div>
240
257
  )}
@@ -141,6 +141,13 @@ export interface QuickActionChipButtonProps {
141
141
  lozenge?: QuickActionChipLozenge
142
142
  /** `'primary'` = accent (yellow) chip, `'outline'` = bordered chip (default). */
143
143
  variant?: 'primary' | 'outline'
144
+ /** Active single-select state (Figma "Feature Item" active): renders the
145
+ * Tag's `selected` variant (pink border + pink-secondary fill), overriding
146
+ * `variant`. Used by chip groups acting as tabs (OpenFrame categories). */
147
+ selected?: boolean
148
+ /** Chip scale, forwarded to `Tag` — `'large'` is the Figma "Feature Item"
149
+ * 48px chip (h3 bold label, 24px icon box). Default `'default'` (32px). */
150
+ size?: 'default' | 'large'
144
151
  onSelect?: () => void
145
152
  /** Pointer/keyboard focus enters the chip — e.g. preview the full prompt. */
146
153
  onHoverStart?: () => void
@@ -164,6 +171,8 @@ export interface QuickActionChipSkeletonProps {
164
171
  icon?: boolean
165
172
  /** Reserve the leading lozenge affix slot. */
166
173
  lozenge?: boolean
174
+ /** Chip scale — MUST match the loaded chips' `size` or the swap jumps. */
175
+ size?: 'default' | 'large'
167
176
  className?: string
168
177
  }
169
178
 
@@ -182,12 +191,13 @@ function ChipSkelBar({ className, style }: { className?: string; style?: React.C
182
191
  * construction. Use anywhere quick actions stream in (chat empty states,
183
192
  * marketing walls, deck panels).
184
193
  */
185
- export function QuickActionChipSkeleton({ labelCh = 16, icon = true, lozenge = false, className }: QuickActionChipSkeletonProps) {
194
+ export function QuickActionChipSkeleton({ labelCh = 16, icon = true, lozenge = false, size = 'default', className }: QuickActionChipSkeletonProps) {
186
195
  return (
187
196
  <Tag
188
197
  variant="outline"
198
+ size={size}
189
199
  className={className}
190
- icon={icon ? <ChipSkelBar className="block size-4" /> : undefined}
200
+ icon={icon ? <ChipSkelBar className={size === 'large' ? 'block size-5' : 'block size-4'} /> : undefined}
191
201
  label={
192
202
  <>
193
203
  {lozenge && <ChipSkelBar className="mr-2 inline-block h-[16px] w-[26px] translate-y-[2px]" />}
@@ -215,6 +225,8 @@ export function QuickActionChipButton({
215
225
  icon,
216
226
  lozenge,
217
227
  variant = 'outline',
228
+ selected = false,
229
+ size = 'default',
218
230
  onSelect,
219
231
  onHoverStart,
220
232
  onHoverEnd,
@@ -223,8 +235,9 @@ export function QuickActionChipButton({
223
235
  }: QuickActionChipButtonProps) {
224
236
  const resolvedIcon = renderQuickActionIcon(icon)
225
237
  const resolvedLabel = composeChipLabel(label, lozenge)
238
+ const tagVariant = selected ? 'selected' : variant
226
239
  if (!interactive) {
227
- return <Tag variant={variant} icon={resolvedIcon} label={resolvedLabel} className={className} />
240
+ return <Tag variant={tagVariant} size={size} icon={resolvedIcon} label={resolvedLabel} className={className} />
228
241
  }
229
242
  return (
230
243
  <button
@@ -234,12 +247,13 @@ export function QuickActionChipButton({
234
247
  onMouseLeave={onHoverEnd}
235
248
  onFocus={onHoverStart}
236
249
  onBlur={onHoverEnd}
250
+ aria-pressed={selected || undefined}
237
251
  className={cn(
238
252
  'shrink-0 rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent',
239
253
  className,
240
254
  )}
241
255
  >
242
- <Tag variant={variant} icon={resolvedIcon} label={resolvedLabel} />
256
+ <Tag variant={tagVariant} size={size} icon={resolvedIcon} label={resolvedLabel} />
243
257
  </button>
244
258
  )
245
259
  }
@@ -448,8 +448,6 @@ export function RedditEmbedClient({ url, maxWidth = 700 }: RedditEmbedProps) {
448
448
  height: m.height,
449
449
  }));
450
450
 
451
- console.log('🎬 MediaCarousel will render with:', mediaContent.length, 'items', mediaContent);
452
-
453
451
  // Format time
454
452
  const formatTimeAgo = (timestamp: number) => {
455
453
  const now = Math.floor(Date.now() / 1000);
@@ -515,7 +513,6 @@ export function RedditEmbedClient({ url, maxWidth = 700 }: RedditEmbedProps) {
515
513
  <MediaCarousel
516
514
  media={carouselItems}
517
515
  aspectRatio="16/9"
518
- showThumbnails={carouselItems.length > 1}
519
516
  />
520
517
  )}
521
518
 
@@ -38,6 +38,11 @@ export * from './hero-image-uploader'
38
38
  export * from './icons-block'
39
39
  export * from './image-cropper'
40
40
  export * from './media-carousel'
41
+ // Explicit re-export disambiguates the star-export collision with the
42
+ // features barrel's gallery-manager MediaItem: from THIS barrel, `MediaItem`
43
+ // is the carousel item shape (the lib-wide SSOT the hub re-types against);
44
+ // the gallery-manager shape stays reachable via `./components/features`.
45
+ export type { MediaItem } from '../utils/media-carousel-utils-stub'
41
46
  export * from './metric-value'
42
47
  export * from './msp-display'
43
48
  export * from './open-source-features'