@anthusai/papyrus 5.43.0-next.14 → 5.43.0-next.16
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.
- package/amplify/data/resource.js +6 -0
- package/amplify/data/resource.ts +7 -0
- package/amplify/data/schema.js +6 -0
- package/amplify/data/schema.ts +7 -0
- package/amplify/functions/content-actions/handler.py +8 -0
- package/bin/papyrus-app.mjs +12 -1
- package/components/news-desk-client-provider.tsx +2 -2
- package/components/newsroom-ops-overview.tsx +63 -60
- package/components/newsroom-ops-shell.tsx +3 -1
- package/components/newsroom-organizer.css +1 -2
- package/components/notification-cards.tsx +364 -0
- package/components/notification-center.tsx +319 -331
- package/components/reference-feed.tsx +11 -11
- package/components/references-prefetch.ts +5 -0
- package/components/review-rating-grid.tsx +19 -9
- package/components/topic-steering-workspace.tsx +10 -2
- package/lib/category-repository.ts +2 -0
- package/lib/local-preview-feed-fixture.ts +20 -0
- package/lib/newsroom-nav.ts +1 -1
- package/lib/newsroom-organizer-nav.ts +1 -1
- package/lib/notification-feed.ts +250 -0
- package/lib/reference-feed-cache.ts +37 -0
- package/lib/review-drafts.ts +8 -3
- package/lib/site-brand.ts +2 -0
- package/package.json +3 -1
- package/routes.manifest.json +1 -1
package/amplify/data/resource.js
CHANGED
|
@@ -603,6 +603,12 @@ const schema = a.schema({
|
|
|
603
603
|
.returns(a.json())
|
|
604
604
|
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
605
605
|
.handler(functionHandler("contentActions", contentActions)),
|
|
606
|
+
correctReferenceCapture: a
|
|
607
|
+
.mutation()
|
|
608
|
+
.arguments({ input: a.json().required() })
|
|
609
|
+
.returns(a.json())
|
|
610
|
+
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
611
|
+
.handler(functionHandler("contentActions", contentActions)),
|
|
606
612
|
saveItemDraft: a
|
|
607
613
|
.mutation()
|
|
608
614
|
.arguments({ input: a.json().required() })
|
package/amplify/data/resource.ts
CHANGED
|
@@ -657,6 +657,13 @@ const schema = a.schema({
|
|
|
657
657
|
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
658
658
|
.handler(functionHandler("contentActions", contentActions)),
|
|
659
659
|
|
|
660
|
+
correctReferenceCapture: a
|
|
661
|
+
.mutation()
|
|
662
|
+
.arguments({ input: a.json().required() })
|
|
663
|
+
.returns(a.json())
|
|
664
|
+
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
665
|
+
.handler(functionHandler("contentActions", contentActions)),
|
|
666
|
+
|
|
660
667
|
saveItemDraft: a
|
|
661
668
|
.mutation()
|
|
662
669
|
.arguments({ input: a.json().required() })
|
package/amplify/data/schema.js
CHANGED
|
@@ -530,6 +530,12 @@ function buildBaseDefinitions(includeEditions) {
|
|
|
530
530
|
.returns(a.json())
|
|
531
531
|
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
532
532
|
.handler(functionHandler("contentActions", contentActions)),
|
|
533
|
+
correctReferenceCapture: a
|
|
534
|
+
.mutation()
|
|
535
|
+
.arguments({ input: a.json().required() })
|
|
536
|
+
.returns(a.json())
|
|
537
|
+
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
538
|
+
.handler(functionHandler("contentActions", contentActions)),
|
|
533
539
|
saveItemDraft: a
|
|
534
540
|
.mutation()
|
|
535
541
|
.arguments({ input: a.json().required() })
|
package/amplify/data/schema.ts
CHANGED
|
@@ -582,6 +582,13 @@ const definitions = {
|
|
|
582
582
|
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
583
583
|
.handler(functionHandler("contentActions", contentActions)),
|
|
584
584
|
|
|
585
|
+
correctReferenceCapture: a
|
|
586
|
+
.mutation()
|
|
587
|
+
.arguments({ input: a.json().required() })
|
|
588
|
+
.returns(a.json())
|
|
589
|
+
.authorization((allow) => [allow.groups(contentWriteGroups)])
|
|
590
|
+
.handler(functionHandler("contentActions", contentActions)),
|
|
591
|
+
|
|
585
592
|
saveItemDraft: a
|
|
586
593
|
.mutation()
|
|
587
594
|
.arguments({ input: a.json().required() })
|
|
@@ -365,6 +365,14 @@ def handler(event, context):
|
|
|
365
365
|
client, arguments, event.get("identity") or {}, receipt_store=receipt_store)
|
|
366
366
|
except IntakeError as error:
|
|
367
367
|
return {"ok": False, "errors": [{"code": "intake-rejected", "message": str(error)}]}
|
|
368
|
+
if field == "correctReferenceCapture":
|
|
369
|
+
from papyrus_content.reference_curation_store import CurationError, correct_reference_capture
|
|
370
|
+
|
|
371
|
+
client, _claims = create_authoring_client()
|
|
372
|
+
try:
|
|
373
|
+
return correct_reference_capture(client, arguments, event.get("identity") or {})
|
|
374
|
+
except CurationError as error:
|
|
375
|
+
return {"ok": False, "errors": [{"code": "correction-rejected", "message": str(error)}]}
|
|
368
376
|
if field == "deriveMarkus":
|
|
369
377
|
return derive_markus_action(arguments)
|
|
370
378
|
if field == "saveItemDraft":
|
package/bin/papyrus-app.mjs
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { sync } from "../src/sync.mjs";
|
|
3
4
|
|
|
4
5
|
const [command, ...rest] = process.argv.slice(2);
|
|
5
6
|
if (command === "sync") {
|
|
6
7
|
sync();
|
|
8
|
+
} else if (command === "brand" && rest[0] === "diff") {
|
|
9
|
+
const { brandDiff } = await import("../src/brand.mjs");
|
|
10
|
+
const flag = rest.indexOf("--papyrus");
|
|
11
|
+
const checkout = flag === -1 ? undefined : rest[flag + 1];
|
|
12
|
+
try {
|
|
13
|
+
process.exit(brandDiff({ id: rest[1], checkout: checkout && path.resolve(checkout) }).drifted ? 1 : 0);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error(error.message);
|
|
16
|
+
process.exit(2);
|
|
17
|
+
}
|
|
7
18
|
} else if (command === "videoml-bundle") {
|
|
8
19
|
const preview = rest.includes("--preview");
|
|
9
20
|
const { buildBrowserBundle } = await import("../scripts/videoml/build-browser-bundle.mjs");
|
|
@@ -15,6 +26,6 @@ if (command === "sync") {
|
|
|
15
26
|
process.exit(1);
|
|
16
27
|
}
|
|
17
28
|
} else {
|
|
18
|
-
console.error("Usage: papyrus-app sync | papyrus-app videoml-bundle [--preview]");
|
|
29
|
+
console.error("Usage: papyrus-app sync | papyrus-app brand diff <brand-id> [--papyrus <checkout>] | papyrus-app videoml-bundle [--preview]");
|
|
19
30
|
process.exit(command ? 1 : 0);
|
|
20
31
|
}
|
|
@@ -6,7 +6,7 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, use
|
|
|
6
6
|
import type { DevSandboxEditorAuth } from "../lib/dev-sandbox-editor-auth";
|
|
7
7
|
import type { CategorySteeringDashboard } from "../lib/category-repository";
|
|
8
8
|
import { ensureDevSandboxEditorSession } from "./dev-sandbox-editor-sign-in";
|
|
9
|
-
import { discardReferencesHeadStart, prefetchReferencesFeed } from "./references-prefetch";
|
|
9
|
+
import { discardReferencesHeadStart, prefetchReferencesFeed, wantsReferencesHeadStart } from "./references-prefetch";
|
|
10
10
|
import { SITE_BRAND } from "../lib/site-brand";
|
|
11
11
|
import { clearSavedNewsroomDisplay, loadSessionDisplay, saveSessionDisplay } from "../lib/reference-feed-cache";
|
|
12
12
|
import {
|
|
@@ -113,7 +113,7 @@ export function NewsDeskClientProvider({
|
|
|
113
113
|
saveSessionDisplay(SITE_BRAND.id, { label: access.auth.label, isAdmin: access.isAdmin });
|
|
114
114
|
setShell((current) => beginDeskLoad(current, access.auth));
|
|
115
115
|
// The References reads do not depend on the summary dashboard: start them now, side by side with it.
|
|
116
|
-
if (typeof window !== "undefined" &&
|
|
116
|
+
if (typeof window !== "undefined" && wantsReferencesHeadStart(window.location.pathname)) prefetchReferencesFeed();
|
|
117
117
|
|
|
118
118
|
try {
|
|
119
119
|
const dashboard = await loadEditorNewsDeskDashboard({ isAdmin: access.isAdmin });
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import Link from "next/link";
|
|
4
|
-
import { usePathname } from "next/navigation";
|
|
5
|
-
import { useMemo } from "react";
|
|
4
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
5
|
+
import { useCallback, useMemo } from "react";
|
|
6
6
|
import { Badge } from "./ui/badge";
|
|
7
7
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card";
|
|
8
|
-
import type { AssignmentRecord, NewsroomSectionRecord, ReferenceRecord } from "../lib/category-repository";
|
|
8
|
+
import type { AssignmentRecord, NewsroomSectionRecord, ReferenceAttachmentRecord, ReferenceRecord } from "../lib/category-repository";
|
|
9
9
|
import { getNewsroomNavHref } from "../lib/newsroom-nav";
|
|
10
|
-
import {
|
|
11
|
-
filterReferencesByStatus,
|
|
12
|
-
formatReferenceListDate,
|
|
13
|
-
referenceDisplayTitle,
|
|
14
|
-
referenceLineageId,
|
|
15
|
-
selectCanonicalReferenceRecords,
|
|
16
|
-
} from "../lib/newsroom-references";
|
|
10
|
+
import { referenceLineageId, selectCanonicalReferenceRecords, type ReferenceCurationAction } from "../lib/newsroom-references";
|
|
17
11
|
import {
|
|
18
12
|
buildNewsroomSectionHref,
|
|
19
13
|
displayNewsroomSectionShortTitle,
|
|
@@ -23,8 +17,11 @@ import {
|
|
|
23
17
|
} from "../lib/newsroom-sections";
|
|
24
18
|
import { newsroomInboxRowClassName } from "../lib/newsroom-list-selection";
|
|
25
19
|
import type { RelevanceDecisionView } from "../lib/relevance-decisions";
|
|
20
|
+
import type { ReferenceRejectionReasonCode } from "../lib/reference-policy";
|
|
21
|
+
import { referencePreviewsByLineage, type ReferencePreview } from "../lib/reference-preview";
|
|
22
|
+
import type { NotificationFixture } from "./notification-center";
|
|
26
23
|
import { NotificationCenter } from "./notification-center";
|
|
27
|
-
import {
|
|
24
|
+
import type { ReviewChoice } from "./reference-review-card";
|
|
28
25
|
|
|
29
26
|
type NewsroomOpsOverviewProps = {
|
|
30
27
|
assignments: AssignmentRecord[];
|
|
@@ -34,26 +31,58 @@ type NewsroomOpsOverviewProps = {
|
|
|
34
31
|
humanCuratedReferenceLineageIds?: ReadonlySet<string>;
|
|
35
32
|
newsroomSections: NewsroomSectionRecord[];
|
|
36
33
|
references: ReferenceRecord[];
|
|
34
|
+
referenceAttachments?: ReferenceAttachmentRecord[];
|
|
35
|
+
/** True until the References have been read; a saved copy of the last view fills the page meanwhile. */
|
|
36
|
+
loading?: boolean;
|
|
37
|
+
savedCopy?: { references: ReferenceRecord[]; previews: Array<[string, ReferencePreview]>; decisions: Array<[string, RelevanceDecisionView]> } | null;
|
|
38
|
+
predictionState?: "loading" | "ready" | "error";
|
|
39
|
+
/** Words for why a rating cannot be saved right now, or null. */
|
|
40
|
+
disabledReason?: string | null;
|
|
41
|
+
onReview?: (reference: ReferenceRecord, action: ReferenceCurationAction, options?: { reasonCode?: ReferenceRejectionReasonCode | null; decisionRelationId?: string; shareable?: boolean }) => Promise<void> | void;
|
|
42
|
+
/** Local real-data preview of the Notification Center (scripts/export-notification-center-fixture.py). */
|
|
43
|
+
notificationFixture?: NotificationFixture | null;
|
|
37
44
|
};
|
|
38
45
|
|
|
39
46
|
const NO_DECISIONS: ReadonlyMap<string, RelevanceDecisionView> = new Map();
|
|
40
|
-
const NO_IDS: ReadonlySet<string> = new Set();
|
|
41
47
|
|
|
42
48
|
export function NewsroomOpsOverview({
|
|
43
49
|
actorLabel = "",
|
|
44
50
|
assignments,
|
|
45
51
|
decisions = NO_DECISIONS,
|
|
46
52
|
demo = false,
|
|
47
|
-
humanCuratedReferenceLineageIds
|
|
53
|
+
humanCuratedReferenceLineageIds,
|
|
54
|
+
disabledReason = null,
|
|
55
|
+
loading = false,
|
|
48
56
|
newsroomSections,
|
|
57
|
+
notificationFixture = null,
|
|
58
|
+
onReview,
|
|
59
|
+
predictionState = "ready",
|
|
60
|
+
referenceAttachments = [],
|
|
49
61
|
references,
|
|
62
|
+
savedCopy = null,
|
|
50
63
|
}: NewsroomOpsOverviewProps) {
|
|
51
64
|
const pathname = usePathname();
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
const router = useRouter();
|
|
66
|
+
const liveReferences = useMemo(() => selectCanonicalReferenceRecords(references), [references]);
|
|
67
|
+
// Until the live read arrives, a saved copy of the last view fills the page. It is display only.
|
|
68
|
+
const showingSavedCopy = loading && !liveReferences.length && Boolean(savedCopy?.references.length);
|
|
69
|
+
const canonicalReferences = showingSavedCopy ? savedCopy!.references : liveReferences;
|
|
70
|
+
const shownDecisions = useMemo(() => (showingSavedCopy && !decisions.size ? new Map(savedCopy!.decisions) : decisions), [decisions, savedCopy, showingSavedCopy]);
|
|
71
|
+
const previews = useMemo(() => {
|
|
72
|
+
const live = referencePreviewsByLineage(referenceAttachments);
|
|
73
|
+
return showingSavedCopy && !live.size ? new Map(savedCopy!.previews) : live;
|
|
74
|
+
}, [referenceAttachments, savedCopy, showingSavedCopy]);
|
|
75
|
+
const openReference = useCallback(
|
|
76
|
+
(lineageId: string) => router.push(getNewsroomNavHref(`/newsroom/references/${encodeURIComponent(lineageId)}`, demo)),
|
|
77
|
+
[demo, router],
|
|
56
78
|
);
|
|
79
|
+
const rateReference = useCallback(async (reference: ReferenceRecord, choice: ReviewChoice, reasonCode: ReferenceRejectionReasonCode | null) => {
|
|
80
|
+
const decision = shownDecisions.get(referenceLineageId(reference));
|
|
81
|
+
await onReview?.(reference, choice, {
|
|
82
|
+
reasonCode: choice === "reject" ? reasonCode : null,
|
|
83
|
+
...(decision ? { decisionRelationId: decision.decisionRelationId, shareable: false } : {}),
|
|
84
|
+
});
|
|
85
|
+
}, [onReview, shownDecisions]);
|
|
57
86
|
const attentionAssignments = useMemo(
|
|
58
87
|
() => assignments
|
|
59
88
|
.filter((assignment) => {
|
|
@@ -69,55 +98,35 @@ export function NewsroomOpsOverview({
|
|
|
69
98
|
);
|
|
70
99
|
const coreDesks = useMemo(() => desks.filter(desk => newsroomDeskKind(desk) === "core"), [desks]);
|
|
71
100
|
const rotatingDesks = useMemo(() => desks.filter(desk => newsroomDeskKind(desk) === "rotating"), [desks]);
|
|
101
|
+
const rateDisabled = disabledReason ?? (showingSavedCopy ? "Confirming your sign-in. You can answer in a moment." : null);
|
|
72
102
|
|
|
73
103
|
return (
|
|
74
104
|
<div
|
|
75
|
-
className="space-y-
|
|
105
|
+
className="space-y-12 font-sans"
|
|
76
106
|
data-news-desk-section="overview"
|
|
77
107
|
data-newsroom-ops-home="true"
|
|
78
108
|
>
|
|
79
|
-
<div className="space-y-
|
|
80
|
-
<div
|
|
109
|
+
<div className="space-y-12" data-newsroom-overview-feeds>
|
|
110
|
+
<div data-newsroom-overview-notifications>
|
|
81
111
|
<NotificationCenter
|
|
82
112
|
actorLabel={actorLabel}
|
|
83
|
-
decisions={
|
|
113
|
+
decisions={shownDecisions}
|
|
84
114
|
demo={demo}
|
|
115
|
+
fixture={notificationFixture}
|
|
85
116
|
humanCuratedReferenceLineageIds={humanCuratedReferenceLineageIds}
|
|
117
|
+
onOpenReference={openReference}
|
|
118
|
+
onRateReference={rateReference}
|
|
119
|
+
predictionLoading={predictionState === "loading"}
|
|
120
|
+
previews={previews}
|
|
121
|
+
referenceDisabledReason={rateDisabled}
|
|
86
122
|
references={canonicalReferences}
|
|
123
|
+
referencesLoading={loading && !canonicalReferences.length}
|
|
87
124
|
/>
|
|
88
125
|
</div>
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
126
|
+
{attentionAssignments.length ? (
|
|
127
|
+
<section aria-label="Open assignments" className="space-y-3">
|
|
128
|
+
<h2 className="text-sm font-medium text-muted-foreground">Open assignments</h2>
|
|
92
129
|
<div className="space-y-2">
|
|
93
|
-
{pendingReferences.map((reference) => {
|
|
94
|
-
const lineageId = referenceLineageId(reference);
|
|
95
|
-
const href = getNewsroomNavHref(`/newsroom/references/${encodeURIComponent(lineageId)}`, demo);
|
|
96
|
-
const active = pathname === href || pathname.startsWith(`${href}/`);
|
|
97
|
-
return (
|
|
98
|
-
<Link
|
|
99
|
-
aria-current={active ? "true" : undefined}
|
|
100
|
-
className={newsroomInboxRowClassName(active)}
|
|
101
|
-
data-newsroom-inbox-item="reference"
|
|
102
|
-
data-newsroom-list-row
|
|
103
|
-
data-selected={active || undefined}
|
|
104
|
-
data-newsroom-card
|
|
105
|
-
data-newsroom-card-id={lineageId}
|
|
106
|
-
href={href}
|
|
107
|
-
key={lineageId}
|
|
108
|
-
>
|
|
109
|
-
<div className="min-w-0 flex-1 space-y-1">
|
|
110
|
-
<p className="truncate text-sm font-medium text-foreground">{referenceDisplayTitle(reference)}</p>
|
|
111
|
-
<p className="text-xs text-muted-foreground">Review source intake · {formatReferenceListDate(reference)}</p>
|
|
112
|
-
<div data-needs-attention-suggestion={lineageId}>
|
|
113
|
-
<CyclotronRow prediction={decisions.get(lineageId) ? predictionFromDecision(decisions.get(lineageId)!) : { state: "none" }} />
|
|
114
|
-
</div>
|
|
115
|
-
<p className="text-xs font-medium text-foreground">Open it to Accept or Reject in the review queue</p>
|
|
116
|
-
</div>
|
|
117
|
-
<Badge className="mt-0.5 shrink-0" variant="outline">Pending</Badge>
|
|
118
|
-
</Link>
|
|
119
|
-
);
|
|
120
|
-
})}
|
|
121
130
|
{attentionAssignments.map((assignment) => {
|
|
122
131
|
const href = getNewsroomNavHref(`/newsroom/assignments/${encodeURIComponent(assignment.id)}`, demo);
|
|
123
132
|
const active = pathname === href || pathname.startsWith(`${href}/`);
|
|
@@ -140,14 +149,8 @@ export function NewsroomOpsOverview({
|
|
|
140
149
|
);
|
|
141
150
|
})}
|
|
142
151
|
</div>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
<CardContent className="p-4 text-sm text-muted-foreground">
|
|
146
|
-
No pending references or open assignments. Check those destinations for other work.
|
|
147
|
-
</CardContent>
|
|
148
|
-
</Card>
|
|
149
|
-
)}
|
|
150
|
-
</section>
|
|
152
|
+
</section>
|
|
153
|
+
) : null}
|
|
151
154
|
|
|
152
155
|
{desks.length ? (
|
|
153
156
|
<section aria-label="Sections" className="space-y-3" data-newsroom-ops-desks>
|
|
@@ -143,6 +143,8 @@ export function NewsroomOpsShell({ activeTab, appTitle, backHref = "/", backLabe
|
|
|
143
143
|
media.addEventListener("change", change);
|
|
144
144
|
return () => { document.removeEventListener("focusin", remember); media.removeEventListener("change", change); cancelAnimationFrame(frame); };
|
|
145
145
|
}, []);
|
|
146
|
+
// The mobile top bar prefers the brand's compact mark, then scales the full logo; the serif title is the no-logo fallback.
|
|
147
|
+
const MastheadLogo = SITE_BRAND.components?.NewsroomLogoCompact ?? SITE_BRAND.components?.NewsroomLogo;
|
|
146
148
|
const activePath = browserPathToInternalNewsroomPath(pathname ?? "/newsroom");
|
|
147
149
|
const sidebarToggleLabel = collapsed ? "Expand sidebar" : "Collapse sidebar";
|
|
148
150
|
const sidebarToggle = <button type="button" className="organizer-toggle" title={sidebarToggleLabel}
|
|
@@ -162,7 +164,7 @@ export function NewsroomOpsShell({ activeTab, appTitle, backHref = "/", backLabe
|
|
|
162
164
|
<div className="organizer-workspace">
|
|
163
165
|
<header className="organizer-topbar" data-newsroom-ops-topbar>
|
|
164
166
|
{showNavigation && collapsed && sidebarToggle}
|
|
165
|
-
<Link className="organizer-masthead" href={backHref} title={backLabel}>{appTitle}</Link>
|
|
167
|
+
<Link className="organizer-masthead" href={backHref} title={backLabel}>{MastheadLogo ? <MastheadLogo className="organizer-masthead-logo" /> : appTitle}</Link>
|
|
166
168
|
<h1 data-newsroom-ops-title>{pageTitle}</h1><OrganizerSearch demo={demo} /><div className="organizer-header-actions">{headerActions}</div><Account placement="header" />
|
|
167
169
|
</header>
|
|
168
170
|
<main className="organizer-main">{demo && !session?.shell.dashboard?.realDataPreview && <p className="organizer-demo-notice">Demo workspace · synthetic examples</p>}{children}</main>
|
|
@@ -18,13 +18,12 @@ body:has(.newsroom-organizer)>[data-staging-banner]{flex-shrink:0}
|
|
|
18
18
|
.organizer-workspace{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden;padding:0 16px}
|
|
19
19
|
.organizer-topbar{height:48px;min-height:48px;display:flex;align-items:center;gap:16px;border-bottom:1px solid var(--org-line)}
|
|
20
20
|
.organizer-masthead{font:900 28px var(--font-wordmark),Georgia,serif;white-space:nowrap;max-width:30vw;overflow:hidden;text-overflow:ellipsis}
|
|
21
|
+
.organizer-masthead-logo{display:block;height:24px;width:auto;max-width:36vw;overflow:visible}
|
|
21
22
|
.organizer-topbar h1{font:400 12px var(--kb-theme-ui-font);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}
|
|
22
23
|
.organizer-toggle{display:flex;align-items:center;justify-content:center;width:36px;min-height:36px;padding:0;border:1px solid var(--org-line);flex-shrink:0}
|
|
23
24
|
.organizer-sidebar-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.organizer-sidebar-head .organizer-brand{flex:1;min-width:0}
|
|
24
25
|
.organizer-header-actions{display:flex;align-items:center;gap:8px;min-width:0;max-width:45%;overflow-x:auto}
|
|
25
26
|
.organizer-main{min-width:0;min-height:0;overflow:auto;overscroll-behavior:contain;flex:1;padding:16px 0}
|
|
26
|
-
.newsroom-overview-feed-frame{height:auto}
|
|
27
|
-
@media(min-width:640px){.newsroom-overview-feed-frame{height:38rem;overflow-y:auto}}
|
|
28
27
|
.organizer-main>[data-category-steering]{min-height:0}.organizer-demo-notice{font-size:11px;color:var(--org-muted);margin-bottom:12px}
|
|
29
28
|
.organizer-account{display:flex;align-items:center;gap:10px;min-height:44px;flex-shrink:0;border:1px solid var(--org-line);padding:8px;text-align:left;border-radius:3px}
|
|
30
29
|
.organizer-account span{min-width:0}.organizer-account strong{display:block;font:600 11px var(--kb-theme-ui-font);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.organizer-account small{display:block;font-size:9px;color:var(--org-muted);margin-top:2px}
|