@opengeni/react 1.2.1-canary.37222177070001 → 1.3.0

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.
@@ -0,0 +1,386 @@
1
+ import { ArrowLeftIcon, CheckIcon, ChevronRightIcon, LoaderCircleIcon } from "lucide-react";
2
+ import { useEffect, useId, useRef, useState } from "react";
3
+ import type { ToolActionReview, ToolReviewDetailsPage, ToolReviewStatus } from "@opengeni/sdk";
4
+
5
+ export type ToolReviewDetailsLoader = (
6
+ review: ToolActionReview,
7
+ path: string,
8
+ offset: number,
9
+ ) => Promise<ToolReviewDetailsPage>;
10
+ const statusText: Record<ToolReviewStatus, string> = {
11
+ pending: "Needs your approval",
12
+ approved: "Approved · waiting to run",
13
+ executing: "In progress",
14
+ completed: "Completed",
15
+ partial: "Partially completed",
16
+ unknown: "Outcome uncertain",
17
+ rejected: "Declined",
18
+ cancelled: "Cancelled",
19
+ expired: "Review expired",
20
+ revoked: "Access unavailable",
21
+ stale: "Action changed",
22
+ failed: "Action failed",
23
+ unavailable: "Details unavailable",
24
+ };
25
+ const statusDetail: Partial<Record<ToolReviewStatus, string>> = {
26
+ unknown: "Execution may have happened. Check the result before trying again.",
27
+ rejected: "This action was not run.",
28
+ cancelled: "This action will not run.",
29
+ expired: "Prepare a new action to continue.",
30
+ revoked: "Restore access before preparing a new action.",
31
+ stale: "The tool or account changed. A new review is needed.",
32
+ partial: "Some work completed. Review the results before continuing.",
33
+ };
34
+
35
+ /** One host-neutral review. All callbacks refer to the immutable action; none can edit it. */
36
+ export function ToolActionReviewCard({
37
+ review,
38
+ onApprove,
39
+ onReject,
40
+ submitting,
41
+ disabled,
42
+ onViewDetails,
43
+ pendingLabel,
44
+ rejectLabel,
45
+ }: {
46
+ review: ToolActionReview;
47
+ onApprove?: (() => void) | undefined;
48
+ onReject?: (() => void) | undefined;
49
+ submitting?: "approve" | "reject" | null | undefined;
50
+ disabled?: boolean | undefined;
51
+ onViewDetails?: ((path: string) => void) | undefined;
52
+ pendingLabel?: string | undefined;
53
+ rejectLabel?: string | undefined;
54
+ }) {
55
+ const titleId = useId();
56
+ const actionable = review.status === "pending" && review.availableActions.includes("approve");
57
+ const quiet =
58
+ review.status === "completed" || review.status === "rejected" || review.status === "cancelled";
59
+ const busy = Boolean(disabled || submitting);
60
+ const selection =
61
+ review.selectionCount === undefined
62
+ ? undefined
63
+ : review.fields.find(
64
+ (field) =>
65
+ field.path === "/messageIds" ||
66
+ field.path === "/messageId" ||
67
+ field.path === "/threadId",
68
+ );
69
+ const fields = selection
70
+ ? review.fields.filter(
71
+ (field) =>
72
+ ![selection.path, "/addLabelIds", "/removeLabelIds", "/labelIds"].includes(field.path),
73
+ )
74
+ : review.fields;
75
+ const extraEffects = review.effects.filter((effect) => effect !== review.approveLabel);
76
+ return (
77
+ <article
78
+ aria-labelledby={titleId}
79
+ aria-busy={Boolean(submitting)}
80
+ className="min-w-0 py-4"
81
+ data-og-tool-review=""
82
+ data-review-status={review.status}
83
+ >
84
+ <div className="flex min-w-0 items-center gap-2 text-og-xs text-og-fg-muted" role="status">
85
+ {review.status === "completed" ? (
86
+ <CheckIcon className="size-3.5" aria-hidden="true" />
87
+ ) : (
88
+ <span className="size-1.5 shrink-0 rounded-full bg-current" aria-hidden="true" />
89
+ )}
90
+ <span>
91
+ {submitting
92
+ ? submitting === "approve"
93
+ ? "Approving…"
94
+ : "Declining…"
95
+ : review.status === "pending"
96
+ ? (pendingLabel ?? statusText.pending)
97
+ : statusText[review.status]}
98
+ </span>
99
+ </div>
100
+ <h3
101
+ tabIndex={-1}
102
+ id={titleId}
103
+ className="m-0 mt-1.5 outline-hidden break-words text-og-md font-semibold leading-snug text-og-fg"
104
+ >
105
+ {review.title}
106
+ </h3>
107
+ {review.accountLabel && (
108
+ <p className="m-0 mt-1 break-words text-og-sm text-og-fg-muted">{review.accountLabel}</p>
109
+ )}
110
+ {(statusDetail[review.status] || review.consequence) && (
111
+ <p className="m-0 mt-3 text-og-sm leading-relaxed text-og-fg-muted">
112
+ {statusDetail[review.status] ?? review.consequence}
113
+ </p>
114
+ )}
115
+ {!quiet && (
116
+ <>
117
+ {extraEffects.length > 0 && (
118
+ <ul className="m-0 mt-3 list-none space-y-1 p-0 text-og-sm text-og-fg">
119
+ {extraEffects.map((effect) => (
120
+ <li key={effect}>{effect}</li>
121
+ ))}
122
+ </ul>
123
+ )}
124
+ {selection && (
125
+ <div className="mt-4">
126
+ {review.samples && review.samples.length > 0 && (
127
+ <>
128
+ <p className="m-0 mb-1 text-og-xs text-og-fg-muted">
129
+ Examples from this selection
130
+ </p>
131
+ <ul className="m-0 list-none divide-y divide-og-border p-0">
132
+ {review.samples.map((sample) => (
133
+ <li key={sample.id} className="py-2">
134
+ <p className="m-0 break-words text-og-sm text-og-fg">{sample.title}</p>
135
+ {sample.subtitle && (
136
+ <p className="m-0 mt-0.5 break-words text-og-xs text-og-fg-muted">
137
+ {sample.subtitle}
138
+ </p>
139
+ )}
140
+ </li>
141
+ ))}
142
+ </ul>
143
+ </>
144
+ )}
145
+ {onViewDetails && review.detailsAvailable && (
146
+ <button
147
+ type="button"
148
+ className="inline-flex min-h-11 items-center gap-1 text-og-sm text-og-fg underline decoration-og-border-strong underline-offset-4 hover:decoration-current"
149
+ data-review-path={selection.path}
150
+ onClick={() => onViewDetails(selection.path)}
151
+ >
152
+ View all {review.selectionCount?.toLocaleString()}{" "}
153
+ {review.selectionKind ?? "messages"}
154
+ <ChevronRightIcon className="size-3.5" aria-hidden="true" />
155
+ </button>
156
+ )}
157
+ </div>
158
+ )}
159
+ <dl className="m-0 mt-3 divide-y divide-og-border text-og-sm">
160
+ {fields.map((field) => (
161
+ <div
162
+ key={field.path}
163
+ className="grid min-w-0 grid-cols-[minmax(0,1fr)_minmax(0,2fr)] gap-x-4 py-2"
164
+ >
165
+ <dt className="m-0 break-words text-og-fg-muted">{field.label}</dt>
166
+ <dd className="m-0 min-w-0 whitespace-pre-wrap break-words text-og-fg [overflow-wrap:anywhere]">
167
+ {field.truncated &&
168
+ !field.protected &&
169
+ onViewDetails &&
170
+ review.detailsAvailable ? (
171
+ <button
172
+ type="button"
173
+ data-review-path={field.path}
174
+ onClick={() => onViewDetails(field.path)}
175
+ className="inline-flex min-h-8 max-w-full items-center gap-1 text-left underline decoration-og-border-strong underline-offset-4 hover:decoration-current [@media(pointer:coarse)]:min-h-11"
176
+ >
177
+ <span className="min-w-0 break-words">{field.preview}</span>
178
+ <ChevronRightIcon className="size-3.5 shrink-0" aria-hidden="true" />
179
+ </button>
180
+ ) : (
181
+ field.preview
182
+ )}
183
+ </dd>
184
+ </div>
185
+ ))}
186
+ </dl>
187
+ {review.moreFields > 0 && (
188
+ <p className="m-0 mt-2 text-og-xs text-og-fg-muted">
189
+ {review.moreFields} more fields in the full details
190
+ </p>
191
+ )}
192
+ </>
193
+ )}
194
+ {review.detailsAvailable && onViewDetails && (
195
+ <button
196
+ type="button"
197
+ className="mt-1 min-h-8 text-og-xs text-og-fg-muted underline underline-offset-4 hover:text-og-fg [@media(pointer:coarse)]:min-h-11"
198
+ data-review-path=""
199
+ onClick={() => onViewDetails("")}
200
+ >
201
+ View full details
202
+ </button>
203
+ )}
204
+ {actionable && (
205
+ <>
206
+ <p className="m-0 mt-3 text-og-xs leading-relaxed text-og-fg-muted">{review.reason}</p>
207
+ <div className="mt-4 flex flex-wrap items-center gap-2">
208
+ <button
209
+ type="button"
210
+ disabled={busy}
211
+ onClick={onApprove}
212
+ className="inline-flex min-h-9 items-center justify-center gap-2 rounded-og-md border border-og-primary-border bg-og-primary px-4 py-2 text-og-sm font-medium text-og-primary-fg transition-colors hover:bg-og-primary-hover disabled:opacity-60 [@media(pointer:coarse)]:min-h-11"
213
+ >
214
+ {submitting === "approve" && (
215
+ <LoaderCircleIcon className="size-3.5 animate-spin" aria-hidden="true" />
216
+ )}
217
+ {submitting === "approve" ? "Approving…" : review.approveLabel}
218
+ </button>
219
+ <button
220
+ type="button"
221
+ disabled={busy}
222
+ onClick={onReject}
223
+ className="min-h-9 rounded-og-md px-3 py-2 text-og-sm text-og-fg-muted transition-colors hover:bg-og-fg/5 hover:text-og-fg disabled:opacity-60 [@media(pointer:coarse)]:min-h-11"
224
+ >
225
+ {submitting === "reject" ? "Declining…" : (rejectLabel ?? "Decline")}
226
+ </button>
227
+ </div>
228
+ </>
229
+ )}
230
+ </article>
231
+ );
232
+ }
233
+
234
+ /** Full-page detail content: hosts choose navigation, never a nested scrolling panel. */
235
+ export function ToolActionReviewDetails({
236
+ review,
237
+ path: initialPath = "",
238
+ load,
239
+ onBack,
240
+ }: {
241
+ review: ToolActionReview;
242
+ path?: string;
243
+ load: ToolReviewDetailsLoader;
244
+ onBack: () => void;
245
+ }) {
246
+ const [path, setPath] = useState(initialPath);
247
+ const [offset, setOffset] = useState(0);
248
+ const [page, setPage] = useState<ToolReviewDetailsPage | null>(null);
249
+ const [error, setError] = useState(false);
250
+ const [retry, setRetry] = useState(0);
251
+ const heading = useRef<HTMLHeadingElement>(null);
252
+ useEffect(() => {
253
+ if (page) {
254
+ heading.current?.focus({ preventScroll: true });
255
+ heading.current?.scrollIntoView({ block: "start" });
256
+ }
257
+ }, [page]);
258
+ useEffect(() => {
259
+ let active = true;
260
+ setPage(null);
261
+ setError(false);
262
+ void load(review, path, offset).then(
263
+ (value) => {
264
+ if (!active) return;
265
+ if (
266
+ value.actionDigest !== review.actionDigest ||
267
+ value.id !== review.id ||
268
+ value.path !== path
269
+ ) {
270
+ setError(true);
271
+ return;
272
+ }
273
+ setPage(value);
274
+ },
275
+ () => {
276
+ if (active) setError(true);
277
+ },
278
+ );
279
+ return () => {
280
+ active = false;
281
+ };
282
+ }, [review, path, offset, load, retry]);
283
+ return (
284
+ <section className="og-root mx-auto w-full max-w-3xl p-6 text-og-fg" data-og-review-details="">
285
+ <button
286
+ type="button"
287
+ onClick={onBack}
288
+ className="mb-5 inline-flex min-h-11 items-center gap-2 text-og-sm text-og-fg-muted hover:text-og-fg"
289
+ >
290
+ <ArrowLeftIcon className="size-4" aria-hidden="true" />
291
+ Back to review
292
+ </button>
293
+ <h2
294
+ ref={heading}
295
+ tabIndex={-1}
296
+ className="m-0 break-words text-og-lg font-semibold outline-hidden"
297
+ >
298
+ {review.title}
299
+ </h2>
300
+ {review.accountLabel && <p className="text-og-sm text-og-fg-muted">{review.accountLabel}</p>}
301
+ <p className="text-og-sm text-og-fg-muted">
302
+ Exact saved selection and values. Protected credentials stay hidden.
303
+ </p>
304
+ {path !== initialPath && (
305
+ <button
306
+ type="button"
307
+ className="min-h-11 text-og-sm underline"
308
+ onClick={() => {
309
+ setPath(initialPath);
310
+ setOffset(0);
311
+ }}
312
+ >
313
+ Back to all fields
314
+ </button>
315
+ )}
316
+ {error ? (
317
+ <div role="alert" className="py-6 text-og-sm">
318
+ Details could not be loaded.{" "}
319
+ <button
320
+ type="button"
321
+ onClick={() => setRetry((value) => value + 1)}
322
+ className="min-h-11 underline"
323
+ >
324
+ Try again
325
+ </button>
326
+ </div>
327
+ ) : !page ? (
328
+ <p role="status" className="py-6 text-og-sm text-og-fg-muted">
329
+ Loading details…
330
+ </p>
331
+ ) : (
332
+ <>
333
+ <dl className="m-0 divide-y divide-og-border">
334
+ {page.items.map((item) => (
335
+ <div key={`${page.path}:${item.label}`} className="py-4">
336
+ <dt className="m-0 text-og-xs text-og-fg-muted">{item.label}</dt>
337
+ <dd className="m-0 mt-1 whitespace-pre-wrap break-words text-og-sm leading-relaxed [overflow-wrap:anywhere]">
338
+ {item.value}
339
+ {item.truncated && item.path && (
340
+ <button
341
+ type="button"
342
+ aria-label={`Open complete ${item.label}`}
343
+ className="mt-2 block min-h-11 text-og-sm underline underline-offset-4"
344
+ onClick={() => {
345
+ setPath(item.path!);
346
+ setOffset(0);
347
+ }}
348
+ >
349
+ Open complete field
350
+ </button>
351
+ )}
352
+ </dd>
353
+ </div>
354
+ ))}
355
+ </dl>
356
+ <nav
357
+ aria-label="Review detail pages"
358
+ className="mt-6 flex flex-wrap items-center justify-between gap-3 border-t border-og-border pt-4 text-og-sm"
359
+ >
360
+ <button
361
+ type="button"
362
+ disabled={offset === 0}
363
+ onClick={() => setOffset(Math.max(0, offset - 25))}
364
+ className="min-h-11 rounded-og-md border border-og-border px-3 disabled:opacity-40"
365
+ >
366
+ Previous
367
+ </button>
368
+ <span className="text-og-fg-muted">
369
+ {page.total === 0
370
+ ? "No items"
371
+ : `${offset + 1}–${offset + page.items.length} of ${page.total.toLocaleString()}`}
372
+ </span>
373
+ <button
374
+ type="button"
375
+ disabled={page.nextOffset === null}
376
+ onClick={() => setOffset(page.nextOffset ?? offset)}
377
+ className="min-h-11 rounded-og-md border border-og-border px-3 disabled:opacity-40"
378
+ >
379
+ Next
380
+ </button>
381
+ </nav>
382
+ </>
383
+ )}
384
+ </section>
385
+ );
386
+ }
@@ -0,0 +1,113 @@
1
+ import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from "react";
2
+ import type { SessionEvent, ToolActionReview } from "@opengeni/sdk";
3
+ import { approvalsFromRequiresAction } from "../approvals";
4
+ import { ToolActionReviewCard } from "./tool-action-review";
5
+
6
+ type HistoryContext = {
7
+ approvalIds: ReadonlySet<string>;
8
+ revision: number;
9
+ load: (approvalId: string) => Promise<ToolActionReview>;
10
+ onViewDetails: (review: ToolActionReview, path: string) => void;
11
+ };
12
+ const History = createContext<HistoryContext | null>(null);
13
+
14
+ /** Opt-in, authenticated history for the exact reviewed calls in the visible event window. */
15
+ export function ToolReviewHistoryProvider({
16
+ events,
17
+ load,
18
+ onViewDetails,
19
+ children,
20
+ }: {
21
+ events: readonly SessionEvent[];
22
+ load: HistoryContext["load"];
23
+ onViewDetails: HistoryContext["onViewDetails"];
24
+ children: ReactNode;
25
+ }) {
26
+ const value = useMemo<HistoryContext>(
27
+ () => ({
28
+ approvalIds: new Set(
29
+ events.flatMap((event) =>
30
+ event.type === "session.requiresAction"
31
+ ? approvalsFromRequiresAction(event.payload).map((approval) => approval.id)
32
+ : [],
33
+ ),
34
+ ),
35
+ revision:
36
+ [...events]
37
+ .reverse()
38
+ .find(
39
+ (event) =>
40
+ event.type === "session.requiresAction" ||
41
+ event.type === "agent.toolCall.output" ||
42
+ event.type.startsWith("turn.") ||
43
+ event.type === "user.approvalDecision" ||
44
+ event.type.startsWith("session.control."),
45
+ )?.sequence ?? 0,
46
+ load,
47
+ onViewDetails,
48
+ }),
49
+ [events, load, onViewDetails],
50
+ );
51
+ return <History.Provider value={value}>{children}</History.Provider>;
52
+ }
53
+ export function useHasToolReview(approvalId: string | null): boolean {
54
+ const history = useContext(History);
55
+ return Boolean(approvalId && history?.approvalIds.has(approvalId));
56
+ }
57
+
58
+ /** Recorded calls have details, never another decision button. */
59
+ export function ToolReviewHistoryReceipt({ approvalId }: { approvalId: string }) {
60
+ const history = useContext(History);
61
+ const [review, setReview] = useState<ToolActionReview | null>(null);
62
+ const [failed, setFailed] = useState(false);
63
+ const [retry, setRetry] = useState(0);
64
+ const load = history?.load;
65
+ const revision = history?.revision;
66
+ useEffect(() => {
67
+ if (!load) return;
68
+ let active = true;
69
+ setFailed(false);
70
+ void load(approvalId).then(
71
+ (value) => {
72
+ if (active) {
73
+ if (value.id === approvalId) setReview(value);
74
+ else setFailed(true);
75
+ }
76
+ },
77
+ () => {
78
+ if (active) setFailed(true);
79
+ },
80
+ );
81
+ return () => {
82
+ active = false;
83
+ };
84
+ }, [approvalId, load, revision, retry]);
85
+ if (!history) return null;
86
+ if (failed)
87
+ return (
88
+ <p className="text-og-sm text-og-fg-muted" role="alert">
89
+ Review details unavailable.{" "}
90
+ <button
91
+ type="button"
92
+ className="min-h-11 underline"
93
+ onClick={() => setRetry((value) => value + 1)}
94
+ >
95
+ Try again
96
+ </button>
97
+ </p>
98
+ );
99
+ if (!review)
100
+ return (
101
+ <p role="status" className="text-og-sm text-og-fg-muted">
102
+ Loading reviewed action…
103
+ </p>
104
+ );
105
+ return (
106
+ <div data-approval-id={approvalId} data-review-origin="history">
107
+ <ToolActionReviewCard
108
+ review={{ ...review, availableActions: [] }}
109
+ onViewDetails={(path) => history.onViewDetails(review, path)}
110
+ />
111
+ </div>
112
+ );
113
+ }
package/src/index.ts CHANGED
@@ -328,6 +328,8 @@ export type {
328
328
  export { approvalsFromRequiresAction, projectPendingApprovals } from "./approvals";
329
329
  export type { PendingApproval } from "./approvals";
330
330
  export { ApprovalSurface, defaultApprovalSurfaceMessages } from "./components/approval-surface";
331
+ export { ToolActionReviewCard, ToolActionReviewDetails } from "./components/tool-action-review";
332
+ export type { ToolReviewDetailsLoader } from "./components/tool-action-review";
331
333
  export type { ApprovalSurfaceMessages, ApprovalSurfaceProps } from "./components/approval-surface";
332
334
 
333
335
  // Structured human input: event projection, authoritative hook, and styled form.
@@ -491,7 +493,11 @@ export { SessionConversation } from "./components/session-conversation";
491
493
  export { SessionList } from "./components/session-list";
492
494
  export type { SessionListLabels, SessionListProps } from "./components/session-list";
493
495
  export { OpenGeniChat } from "./components/open-geni-chat";
494
- export type { OpenGeniChatLabels, OpenGeniChatProps } from "./components/open-geni-chat";
496
+ export type {
497
+ OpenGeniChatCreateOptions,
498
+ OpenGeniChatLabels,
499
+ OpenGeniChatProps,
500
+ } from "./components/open-geni-chat";
495
501
  export type {
496
502
  SessionConversationLabels,
497
503
  SessionConversationProps,
@@ -714,3 +720,5 @@ export { ClaudeMark } from "./components/claude-mark";
714
720
  export { AnthropicMark } from "./components/anthropic-mark";
715
721
  export { OpenRouterMark } from "./components/openrouter-mark";
716
722
  export { GrokMark } from "./components/grok-mark";
723
+
724
+ export { ToolReviewHistoryProvider } from "./components/tool-review-history";
package/src/session-ui.ts CHANGED
@@ -9,6 +9,8 @@ export type {
9
9
  } from "./components/human-input-form";
10
10
  export { HumanInputSurface } from "./components/human-input-surface";
11
11
  export { ApprovalSurface } from "./components/approval-surface";
12
+ export { ToolActionReviewCard, ToolActionReviewDetails } from "./components/tool-action-review";
13
+ export type { ToolReviewDetailsLoader } from "./components/tool-action-review";
12
14
  export type { ApprovalSurfaceProps, ApprovalSurfaceMessages } from "./components/approval-surface";
13
15
  export type { HumanInputSurfaceProps } from "./components/human-input-surface";
14
16
  export { MessageTimeline, TimelineRow } from "./components/message-timeline";
@@ -69,7 +71,11 @@ export { SessionConversation } from "./components/session-conversation";
69
71
  export { SessionList } from "./components/session-list";
70
72
  export type { SessionListLabels, SessionListProps } from "./components/session-list";
71
73
  export { OpenGeniChat } from "./components/open-geni-chat";
72
- export type { OpenGeniChatLabels, OpenGeniChatProps } from "./components/open-geni-chat";
74
+ export type {
75
+ OpenGeniChatCreateOptions,
76
+ OpenGeniChatLabels,
77
+ OpenGeniChatProps,
78
+ } from "./components/open-geni-chat";
73
79
  export type {
74
80
  SessionConversationLabels,
75
81
  SessionConversationProps,
@@ -95,3 +101,5 @@ export type { KnowledgeActivityActions } from "./timeline/knowledge-receipt";
95
101
  export { StartupTimings } from "./timeline/startup-timings";
96
102
  export { useStartupDetails, setStartupDetails } from "./timeline/startup-preference";
97
103
  export type { GenieLoadingOptions } from "./timeline/genie-loading";
104
+
105
+ export { ToolReviewHistoryProvider } from "./components/tool-review-history";
@@ -1,3 +1,4 @@
1
+ import { useHasToolReview, ToolReviewHistoryReceipt } from "../components/tool-review-history";
1
2
  import { KnowledgeReceiptRow } from "./knowledge-receipt";
2
3
  import { defaultUrlTransform } from "react-markdown";
3
4
  import { isRetainedImageContentType, useRetainedImageObjectUrl } from "./retained-image";
@@ -2333,6 +2334,12 @@ function RunOnRenderer({ item }: ToolRendererProps) {
2333
2334
  * JSON stays in the expandable body only.
2334
2335
  */
2335
2336
  function GenericRenderer({ item }: ToolRendererProps) {
2337
+ const reviewed = useHasToolReview(item.callId);
2338
+ if (reviewed && item.callId) return <ToolReviewHistoryReceipt approvalId={item.callId} />;
2339
+ return <UnreviewedGenericRenderer item={item} />;
2340
+ }
2341
+
2342
+ function UnreviewedGenericRenderer({ item }: ToolRendererProps) {
2336
2343
  const running = item.status === "running";
2337
2344
  const args = parseToolArgs(item.arguments);
2338
2345
  const display = toolDisplayName(item.name, item.display);
@@ -1786,6 +1786,9 @@
1786
1786
  :where(.og-root).mt-5,:where(.og-root) .mt-5 {
1787
1787
  margin-top: calc(var(--spacing) * 5);
1788
1788
  }
1789
+ :where(.og-root).mt-6,:where(.og-root) .mt-6 {
1790
+ margin-top: calc(var(--spacing) * 6);
1791
+ }
1789
1792
  :where(.og-root).mt-auto,:where(.og-root) .mt-auto {
1790
1793
  margin-top: auto;
1791
1794
  }
@@ -1828,6 +1831,9 @@
1828
1831
  :where(.og-root).mb-3,:where(.og-root) .mb-3 {
1829
1832
  margin-bottom: calc(var(--spacing) * 3);
1830
1833
  }
1834
+ :where(.og-root).mb-5,:where(.og-root) .mb-5 {
1835
+ margin-bottom: calc(var(--spacing) * 5);
1836
+ }
1831
1837
  :where(.og-root).ml-0\.5,:where(.og-root) .ml-0\.5 {
1832
1838
  margin-left: calc(var(--spacing) * 0.5);
1833
1839
  }
@@ -2065,9 +2071,6 @@
2065
2071
  :where(.og-root).max-h-40,:where(.og-root) .max-h-40 {
2066
2072
  max-height: calc(var(--spacing) * 40);
2067
2073
  }
2068
- :where(.og-root).max-h-48,:where(.og-root) .max-h-48 {
2069
- max-height: calc(var(--spacing) * 48);
2070
- }
2071
2074
  :where(.og-root).max-h-56,:where(.og-root) .max-h-56 {
2072
2075
  max-height: calc(var(--spacing) * 56);
2073
2076
  }
@@ -2554,8 +2557,8 @@
2554
2557
  :where(.og-root).grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\],:where(.og-root) .grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\] {
2555
2558
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
2556
2559
  }
2557
- :where(.og-root).grid-cols-\[minmax\(5\.5rem\,max-content\)_minmax\(0\,1fr\)\],:where(.og-root) .grid-cols-\[minmax\(5\.5rem\,max-content\)_minmax\(0\,1fr\)\] {
2558
- grid-template-columns: minmax(5.5rem,max-content) minmax(0,1fr);
2560
+ :where(.og-root).grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,2fr\)\],:where(.og-root) .grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,2fr\)\] {
2561
+ grid-template-columns: minmax(0,1fr) minmax(0,2fr);
2559
2562
  }
2560
2563
  :where(.og-root).flex-col,:where(.og-root) .flex-col {
2561
2564
  flex-direction: column;
@@ -2731,14 +2734,6 @@
2731
2734
  }
2732
2735
  }
2733
2736
  }
2734
- :where(.og-root).divide-og-status-waiting\/20,:where(.og-root) .divide-og-status-waiting\/20 {
2735
- :where(& > :not(:last-child)) {
2736
- border-color: var(--og-color-status-waiting);
2737
- @supports (color: color-mix(in lab, red, red)) {
2738
- border-color: color-mix(in oklab, var(--og-color-status-waiting) 20%, transparent);
2739
- }
2740
- }
2741
- }
2742
2737
  :where(.og-root).self-center,:where(.og-root) .self-center {
2743
2738
  align-self: center;
2744
2739
  }
@@ -3744,6 +3739,9 @@
3744
3739
  :where(.og-root).pt-3,:where(.og-root) .pt-3 {
3745
3740
  padding-top: calc(var(--spacing) * 3);
3746
3741
  }
3742
+ :where(.og-root).pt-4,:where(.og-root) .pt-4 {
3743
+ padding-top: calc(var(--spacing) * 4);
3744
+ }
3747
3745
  :where(.og-root).pt-16,:where(.og-root) .pt-16 {
3748
3746
  padding-top: calc(var(--spacing) * 16);
3749
3747
  }
@@ -5055,6 +5053,16 @@
5055
5053
  }
5056
5054
  }
5057
5055
  }
5056
+ :where(.og-root).hover\:bg-og-fg\/5,:where(.og-root) .hover\:bg-og-fg\/5 {
5057
+ &:hover {
5058
+ @media (hover: hover) {
5059
+ background-color: var(--og-color-fg);
5060
+ @supports (color: color-mix(in lab, red, red)) {
5061
+ background-color: color-mix(in oklab, var(--og-color-fg) 5%, transparent);
5062
+ }
5063
+ }
5064
+ }
5065
+ }
5058
5066
  :where(.og-root).hover\:bg-og-hover,:where(.og-root) .hover\:bg-og-hover {
5059
5067
  &:hover {
5060
5068
  @media (hover: hover) {
@@ -5288,6 +5296,13 @@
5288
5296
  }
5289
5297
  }
5290
5298
  }
5299
+ :where(.og-root).hover\:decoration-current,:where(.og-root) .hover\:decoration-current {
5300
+ &:hover {
5301
+ @media (hover: hover) {
5302
+ text-decoration-color: currentcolor;
5303
+ }
5304
+ }
5305
+ }
5291
5306
  :where(.og-root).hover\:opacity-80,:where(.og-root) .hover\:opacity-80 {
5292
5307
  &:hover {
5293
5308
  @media (hover: hover) {
@@ -6525,6 +6540,11 @@
6525
6540
  margin-block: calc(var(--spacing) * 1);
6526
6541
  }
6527
6542
  }
6543
+ :where(.og-root).\[\@media\(pointer\:coarse\)\]\:min-h-11,:where(.og-root) .\[\@media\(pointer\:coarse\)\]\:min-h-11 {
6544
+ @media (pointer:coarse) {
6545
+ min-height: calc(var(--spacing) * 11);
6546
+ }
6547
+ }
6528
6548
  :where(.og-root).\[tr\:last-child\>\&\]\:border-b-0,:where(.og-root) .\[tr\:last-child\>\&\]\:border-b-0 {
6529
6549
  tr:last-child>& {
6530
6550
  border-bottom-style: var(--tw-border-style);