@orangecheck/design 0.15.0 → 0.17.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.
package/dist/chrome.mjs CHANGED
@@ -1,13 +1,14 @@
1
- import { Boxes, ChevronDown, Check, CornerDownLeft, Plus, Loader2, Copy } from 'lucide-react';
1
+ import { Boxes, ChevronDown, Check, CornerDownLeft, Plus, Loader2, Copy, X, Menu, Sun, Moon, Monitor } from 'lucide-react';
2
2
  import Link5 from 'next/link';
3
3
  import * as React from 'react';
4
- import { useState, useRef, useEffect, useId } from 'react';
4
+ import { createContext, useState, useRef, useEffect, useId, useContext } from 'react';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
  import { useRouter } from 'next/router';
7
7
  import * as Popover from '@radix-ui/react-popover';
8
8
  import { clsx } from 'clsx';
9
9
  import { twMerge } from 'tailwind-merge';
10
10
  import { useOcSession, fetchOcLinkedIdentities } from '@orangecheck/auth-client';
11
+ import { useTheme } from 'next-themes';
11
12
 
12
13
  // src/chrome/ecosystem-switcher.tsx
13
14
  var ENTRIES = [
@@ -751,6 +752,74 @@ function OcLogoDropdown({
751
752
  }
752
753
  );
753
754
  }
755
+ var OcSkinContext = createContext(null);
756
+ function useOcSkin() {
757
+ const ctx = useContext(OcSkinContext);
758
+ if (!ctx) {
759
+ throw new Error("useOcSkin must be used within <OcThemeProvider>");
760
+ }
761
+ return ctx;
762
+ }
763
+ var MODES = [
764
+ { id: "light", label: "light", Icon: Sun },
765
+ { id: "dark", label: "dark", Icon: Moon },
766
+ { id: "system", label: "system", Icon: Monitor }
767
+ ];
768
+ function AppearanceControls({ className }) {
769
+ const { skin, setSkin, themes } = useOcSkin();
770
+ const { theme, setTheme } = useTheme();
771
+ const [mounted, setMounted] = useState(false);
772
+ useEffect(() => setMounted(true), []);
773
+ const activeMode = mounted ? theme ?? "system" : null;
774
+ return /* @__PURE__ */ jsxs("div", { className, children: [
775
+ /* @__PURE__ */ jsx("div", { className: "label-mono text-muted-foreground px-3 pt-3 pb-2", children: "mode" }),
776
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 px-2 pb-2", children: MODES.map(({ id, label, Icon }) => {
777
+ const active = activeMode === id;
778
+ return /* @__PURE__ */ jsxs(
779
+ "button",
780
+ {
781
+ type: "button",
782
+ role: "menuitemradio",
783
+ "aria-checked": active,
784
+ onClick: () => setTheme(id),
785
+ className: cn(
786
+ "flex flex-col items-center gap-1 rounded-md border py-2 text-[11px] transition-colors",
787
+ active ? "border-primary text-foreground bg-accent" : "border-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground"
788
+ ),
789
+ children: [
790
+ /* @__PURE__ */ jsx(Icon, { className: "size-4", "aria-hidden": true }),
791
+ label
792
+ ]
793
+ },
794
+ id
795
+ );
796
+ }) }),
797
+ /* @__PURE__ */ jsx("div", { className: "label-mono text-muted-foreground border-t px-3 pt-3 pb-1", children: "theme" }),
798
+ /* @__PURE__ */ jsx("ul", { className: "pb-1", children: themes.map((t) => {
799
+ const active = t.id === skin;
800
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
801
+ "button",
802
+ {
803
+ type: "button",
804
+ role: "menuitemradio",
805
+ "aria-checked": active,
806
+ onClick: () => setSkin(t.id),
807
+ className: cn(
808
+ "hover:bg-accent hover:text-accent-foreground flex w-full items-start gap-2 px-3 py-2 text-left transition-colors",
809
+ active && "text-foreground"
810
+ ),
811
+ children: [
812
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 size-4 shrink-0", children: active && /* @__PURE__ */ jsx(Check, { className: "text-primary size-4", "aria-hidden": true }) }),
813
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
814
+ /* @__PURE__ */ jsx("span", { className: "block text-sm font-medium", children: t.label }),
815
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground block text-xs leading-snug", children: t.description })
816
+ ] })
817
+ ]
818
+ }
819
+ ) }, t.id);
820
+ }) })
821
+ ] });
822
+ }
754
823
  function obscureIdentity(value) {
755
824
  if (value.length <= 12) {
756
825
  return `${value.slice(0, 4)}\u2026${value.slice(-3)}`;
@@ -1001,6 +1070,92 @@ function OcAccountMenu(props) {
1001
1070
  }
1002
1071
  );
1003
1072
  }
1073
+ function MobileMenu({
1074
+ primary,
1075
+ secondary
1076
+ }) {
1077
+ const [open, setOpen] = useState(false);
1078
+ const ref = useRef(null);
1079
+ useEffect(() => {
1080
+ if (!open) return;
1081
+ const onClick = (e) => {
1082
+ if (ref.current && !ref.current.contains(e.target)) setOpen(false);
1083
+ };
1084
+ const onKey = (e) => {
1085
+ if (e.key === "Escape") setOpen(false);
1086
+ };
1087
+ document.addEventListener("mousedown", onClick);
1088
+ document.addEventListener("keydown", onKey);
1089
+ return () => {
1090
+ document.removeEventListener("mousedown", onClick);
1091
+ document.removeEventListener("keydown", onKey);
1092
+ };
1093
+ }, [open]);
1094
+ const links = [...primary ?? [], ...secondary ?? []];
1095
+ const rowCls = "font-display flex items-center gap-2 px-3 py-2 text-[12px] font-semibold tracking-wider uppercase text-muted-foreground hover:text-foreground hover:bg-accent transition-colors";
1096
+ return /* @__PURE__ */ jsxs("div", { ref, className: "relative md:hidden", "data-oc-account-mobile-menu": "", children: [
1097
+ /* @__PURE__ */ jsx(
1098
+ "button",
1099
+ {
1100
+ type: "button",
1101
+ onClick: () => setOpen((v) => !v),
1102
+ "aria-haspopup": "menu",
1103
+ "aria-expanded": open,
1104
+ "aria-label": "menu",
1105
+ className: "border-input bg-background hover:bg-accent text-muted-foreground inline-flex size-8 items-center justify-center rounded-md border transition-colors",
1106
+ "data-oc-account-mobile-toggle": "",
1107
+ children: open ? /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true }) : /* @__PURE__ */ jsx(Menu, { className: "size-4", "aria-hidden": true })
1108
+ }
1109
+ ),
1110
+ open && /* @__PURE__ */ jsxs(
1111
+ "div",
1112
+ {
1113
+ role: "menu",
1114
+ "aria-label": "menu",
1115
+ className: "border-border bg-popover text-popover-foreground absolute top-[calc(100%+6px)] right-0 z-50 w-[min(16rem,calc(100vw-1rem))] overflow-hidden border shadow-xl",
1116
+ "data-oc-account-mobile-popover": "",
1117
+ children: [
1118
+ links.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-b p-1", children: [
1119
+ /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/60 px-3 pt-2 pb-1 font-mono text-[10px] tracking-widest uppercase", children: "\xA7 navigate" }),
1120
+ links.map(
1121
+ (l) => l.external ? /* @__PURE__ */ jsxs(
1122
+ "a",
1123
+ {
1124
+ href: l.href,
1125
+ target: "_blank",
1126
+ rel: "noreferrer",
1127
+ role: "menuitem",
1128
+ onClick: () => setOpen(false),
1129
+ className: rowCls,
1130
+ children: [
1131
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1132
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: l.label }),
1133
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70 text-[10px]", "aria-hidden": true, children: "\u2197" })
1134
+ ]
1135
+ },
1136
+ l.href
1137
+ ) : /* @__PURE__ */ jsxs(
1138
+ Link5,
1139
+ {
1140
+ href: l.href,
1141
+ role: "menuitem",
1142
+ onClick: () => setOpen(false),
1143
+ className: rowCls,
1144
+ children: [
1145
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1146
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: l.label })
1147
+ ]
1148
+ },
1149
+ l.href
1150
+ )
1151
+ )
1152
+ ] }),
1153
+ /* @__PURE__ */ jsx(AppearanceControls, {})
1154
+ ]
1155
+ }
1156
+ )
1157
+ ] });
1158
+ }
1004
1159
  function OcAccountMenuView({
1005
1160
  current,
1006
1161
  signInUrl = "/signin",
@@ -1073,220 +1228,220 @@ function OcAccountMenuView({
1073
1228
  children: signInLabel
1074
1229
  }
1075
1230
  );
1231
+ const hasNav = (primaryNavLinks?.length ?? 0) + (secondaryNavLinks?.length ?? 0) > 0;
1232
+ const wrap = (identity) => /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", className), "data-oc-account-menu": "", children: [
1233
+ hasNav ? /* @__PURE__ */ jsx(MobileMenu, { primary: primaryNavLinks, secondary: secondaryNavLinks }) : null,
1234
+ identity
1235
+ ] });
1076
1236
  if (!hydrated || status === "loading") {
1077
- return signInTrigger;
1237
+ return wrap(signInTrigger);
1078
1238
  }
1079
1239
  if (status !== "authenticated" || !account) {
1080
- return signInTrigger;
1240
+ return wrap(signInTrigger);
1081
1241
  }
1082
1242
  const displayName = account.displayName ?? null;
1083
1243
  const label = displayName ?? obscureIdentity(account.displayIdentity.value);
1084
- return /* @__PURE__ */ jsxs(
1085
- "div",
1086
- {
1087
- ref: wrapRef,
1088
- className: "relative inline-block " + (className ?? ""),
1089
- "data-oc-account-menu": "",
1090
- children: [
1091
- /* @__PURE__ */ jsxs(
1092
- "button",
1093
- {
1094
- type: "button",
1095
- onClick: () => setOpen((v) => !v),
1096
- "aria-haspopup": "menu",
1097
- "aria-expanded": open,
1098
- "aria-label": `Signed in as ${account.didOc}. Open account menu.`,
1099
- className: triggerClassName ?? "border-primary/40 bg-card hover:bg-accent inline-flex h-8 items-center gap-1.5 rounded-md border px-3 font-mono text-[11px] tracking-wide transition-colors",
1100
- "data-oc-account-menu-trigger": "",
1101
- children: [
1102
- /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block size-1.5 rounded-full", "aria-hidden": true }),
1103
- /* @__PURE__ */ jsx("span", { className: "text-foreground", children: label }),
1104
- /* @__PURE__ */ jsx(
1105
- "svg",
1106
- {
1107
- width: "9",
1108
- height: "9",
1109
- viewBox: "0 0 10 10",
1110
- "aria-hidden": true,
1111
- className: "opacity-60 transition-transform " + (open ? "rotate-180" : "rotate-0"),
1112
- children: /* @__PURE__ */ jsx(
1113
- "path",
1114
- {
1115
- d: "M2 4 L5 7 L8 4",
1116
- stroke: "currentColor",
1117
- strokeWidth: "1.5",
1118
- fill: "none",
1119
- strokeLinecap: "round"
1120
- }
1121
- )
1122
- }
1123
- )
1124
- ]
1125
- }
1126
- ),
1127
- open && /* @__PURE__ */ jsxs(
1128
- "div",
1129
- {
1130
- role: "menu",
1131
- "aria-label": "Account menu",
1132
- className: popoverClassName ?? "border-border bg-popover text-popover-foreground absolute top-[calc(100%+6px)] right-0 z-50 w-[min(20rem,calc(100vw-1rem))] border shadow-xl",
1133
- "data-oc-account-menu-popover": "",
1134
- children: [
1135
- /* @__PURE__ */ jsxs("div", { className: "border-border border-b p-3", children: [
1136
- /* @__PURE__ */ jsxs("div", { className: "text-primary mb-1 font-mono text-[10px] tracking-widest uppercase", children: [
1137
- "\xA7 signed in \xB7 ",
1138
- hostname,
1139
- tabPinned ? /* @__PURE__ */ jsxs(
1244
+ return wrap(
1245
+ /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: "relative inline-block", children: [
1246
+ /* @__PURE__ */ jsxs(
1247
+ "button",
1248
+ {
1249
+ type: "button",
1250
+ onClick: () => setOpen((v) => !v),
1251
+ "aria-haspopup": "menu",
1252
+ "aria-expanded": open,
1253
+ "aria-label": `Signed in as ${account.didOc}. Open account menu.`,
1254
+ className: triggerClassName ?? "border-primary/40 bg-card hover:bg-accent inline-flex h-8 items-center gap-1.5 rounded-md border px-2 font-mono text-[11px] tracking-wide transition-colors sm:px-3",
1255
+ "data-oc-account-menu-trigger": "",
1256
+ children: [
1257
+ /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block size-1.5 shrink-0 rounded-full", "aria-hidden": true }),
1258
+ /* @__PURE__ */ jsx("span", { className: "text-foreground hidden max-w-[16ch] truncate sm:inline", children: label }),
1259
+ /* @__PURE__ */ jsx(
1260
+ "svg",
1261
+ {
1262
+ width: "9",
1263
+ height: "9",
1264
+ viewBox: "0 0 10 10",
1265
+ "aria-hidden": true,
1266
+ className: "opacity-60 transition-transform " + (open ? "rotate-180" : "rotate-0"),
1267
+ children: /* @__PURE__ */ jsx(
1268
+ "path",
1269
+ {
1270
+ d: "M2 4 L5 7 L8 4",
1271
+ stroke: "currentColor",
1272
+ strokeWidth: "1.5",
1273
+ fill: "none",
1274
+ strokeLinecap: "round"
1275
+ }
1276
+ )
1277
+ }
1278
+ )
1279
+ ]
1280
+ }
1281
+ ),
1282
+ open && /* @__PURE__ */ jsxs(
1283
+ "div",
1284
+ {
1285
+ role: "menu",
1286
+ "aria-label": "Account menu",
1287
+ className: popoverClassName ?? "border-border bg-popover text-popover-foreground absolute top-[calc(100%+6px)] right-0 z-50 w-[min(20rem,calc(100vw-1rem))] border shadow-xl",
1288
+ "data-oc-account-menu-popover": "",
1289
+ children: [
1290
+ /* @__PURE__ */ jsxs("div", { className: "border-border border-b p-3", children: [
1291
+ /* @__PURE__ */ jsxs("div", { className: "text-primary mb-1 font-mono text-[10px] tracking-widest uppercase", children: [
1292
+ "\xA7 signed in \xB7 ",
1293
+ hostname,
1294
+ tabPinned ? /* @__PURE__ */ jsxs(
1295
+ "span",
1296
+ {
1297
+ className: "text-muted-foreground/70 normal-case",
1298
+ "data-oc-account-menu-tab-pin": "",
1299
+ title: "This tab keeps this account even if you switch accounts in another tab",
1300
+ children: [
1301
+ " ",
1302
+ "\xB7 this tab"
1303
+ ]
1304
+ }
1305
+ ) : null
1306
+ ] }),
1307
+ /* @__PURE__ */ jsx(CopyableDid, { did: account.didOc }),
1308
+ displayName ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/80 mt-1 font-mono text-[10px] tracking-wide", children: displayName }) : null
1309
+ ] }),
1310
+ /* @__PURE__ */ jsx(
1311
+ IdentityPromoteSection,
1312
+ {
1313
+ didOc: account.didOc,
1314
+ nostrNpub: account.nostrNpub ?? null,
1315
+ current: account.displayIdentity,
1316
+ open,
1317
+ setDisplayIdentity
1318
+ }
1319
+ ),
1320
+ /* @__PURE__ */ jsx(
1321
+ AccountsSection,
1322
+ {
1323
+ roster: roster ?? [],
1324
+ switchAccount,
1325
+ addAccountUrl,
1326
+ signOut,
1327
+ onActionStart: () => setOpen(false)
1328
+ }
1329
+ ),
1330
+ primaryNavLinks && primaryNavLinks.length > 0 ? /* @__PURE__ */ jsx(
1331
+ PopoverSection,
1332
+ {
1333
+ label: "navigate",
1334
+ items: primaryNavLinks,
1335
+ onItemClick: () => setOpen(false),
1336
+ className: "hidden md:block"
1337
+ }
1338
+ ) : null,
1339
+ /* @__PURE__ */ jsxs("div", { className: "p-1", "data-oc-account-menu-section": "account", children: [
1340
+ menuItems?.map((item) => {
1341
+ const onClick = () => setOpen(false);
1342
+ const cls = "hover:bg-accent flex items-center gap-2 px-3 py-2 font-mono text-[11px] tracking-wide transition-colors";
1343
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
1344
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1345
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
1346
+ item.external ? /* @__PURE__ */ jsx(
1140
1347
  "span",
1141
1348
  {
1142
- className: "text-muted-foreground/70 normal-case",
1143
- "data-oc-account-menu-tab-pin": "",
1144
- title: "This tab keeps this account even if you switch accounts in another tab",
1145
- children: [
1146
- " ",
1147
- "\xB7 this tab"
1148
- ]
1349
+ className: "text-muted-foreground/70 text-[10px]",
1350
+ "aria-hidden": true,
1351
+ children: "\u2197"
1149
1352
  }
1150
1353
  ) : null
1151
- ] }),
1152
- /* @__PURE__ */ jsx(CopyableDid, { did: account.didOc }),
1153
- displayName ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/80 mt-1 font-mono text-[10px] tracking-wide", children: displayName }) : null
1154
- ] }),
1155
- /* @__PURE__ */ jsx(
1156
- IdentityPromoteSection,
1157
- {
1158
- didOc: account.didOc,
1159
- nostrNpub: account.nostrNpub ?? null,
1160
- current: account.displayIdentity,
1161
- open,
1162
- setDisplayIdentity
1163
- }
1164
- ),
1165
- /* @__PURE__ */ jsx(
1166
- AccountsSection,
1167
- {
1168
- roster: roster ?? [],
1169
- switchAccount,
1170
- addAccountUrl,
1171
- signOut,
1172
- onActionStart: () => setOpen(false)
1173
- }
1174
- ),
1175
- primaryNavLinks && primaryNavLinks.length > 0 ? /* @__PURE__ */ jsx(
1176
- PopoverSection,
1177
- {
1178
- label: "navigate",
1179
- items: primaryNavLinks,
1180
- onItemClick: () => setOpen(false)
1181
- }
1182
- ) : null,
1183
- /* @__PURE__ */ jsxs("div", { className: "p-1", "data-oc-account-menu-section": "account", children: [
1184
- primaryNavLinks && primaryNavLinks.length > 0 ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/60 px-3 pb-1 pt-2 font-mono text-[10px] tracking-widest uppercase", children: "\xA7 account" }) : null,
1185
- menuItems?.map((item) => {
1186
- const onClick = () => setOpen(false);
1187
- const cls = "hover:bg-accent flex items-center gap-2 px-3 py-2 font-mono text-[11px] tracking-wide transition-colors";
1188
- const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
1189
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1190
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
1191
- item.external ? /* @__PURE__ */ jsx(
1192
- "span",
1193
- {
1194
- className: "text-muted-foreground/70 text-[10px]",
1195
- "aria-hidden": true,
1196
- children: "\u2197"
1197
- }
1198
- ) : null
1199
- ] });
1200
- return item.external ? /* @__PURE__ */ jsx(
1201
- "a",
1202
- {
1203
- href: item.href,
1204
- target: "_blank",
1205
- rel: "noreferrer",
1206
- onClick,
1207
- role: "menuitem",
1208
- className: cls,
1209
- "data-oc-account-menu-item": "",
1210
- children: inner
1211
- },
1212
- item.href
1213
- ) : /* @__PURE__ */ jsx(
1214
- Link5,
1215
- {
1216
- href: item.href,
1217
- onClick,
1218
- role: "menuitem",
1219
- className: cls,
1220
- "data-oc-account-menu-item": "",
1221
- children: inner
1222
- },
1223
- item.href
1224
- );
1225
- }),
1226
- familyDashboardEnabled ? /* @__PURE__ */ jsxs(
1354
+ ] });
1355
+ return item.external ? /* @__PURE__ */ jsx(
1227
1356
  "a",
1228
1357
  {
1229
- href: "https://ochk.io/dashboard",
1358
+ href: item.href,
1230
1359
  target: "_blank",
1231
1360
  rel: "noreferrer",
1232
- onClick: () => setOpen(false),
1361
+ onClick,
1233
1362
  role: "menuitem",
1234
- className: "hover:bg-accent flex items-center gap-2 px-3 py-2 font-mono text-[11px] tracking-wide transition-colors",
1363
+ className: cls,
1235
1364
  "data-oc-account-menu-item": "",
1236
- "data-oc-account-menu-family-dashboard": "",
1237
- children: [
1238
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1239
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: "family dashboard" }),
1240
- /* @__PURE__ */ jsx(
1241
- "span",
1242
- {
1243
- className: "text-muted-foreground/70 text-[10px]",
1244
- "aria-hidden": true,
1245
- children: "\u2197"
1246
- }
1247
- )
1248
- ]
1249
- }
1250
- ) : null,
1251
- /* @__PURE__ */ jsxs(
1252
- "button",
1365
+ children: inner
1366
+ },
1367
+ item.href
1368
+ ) : /* @__PURE__ */ jsx(
1369
+ Link5,
1253
1370
  {
1254
- type: "button",
1371
+ href: item.href,
1372
+ onClick,
1255
1373
  role: "menuitem",
1256
- onClick: () => {
1257
- setOpen(false);
1258
- void (async () => {
1259
- await signOut();
1260
- if (typeof window !== "undefined") {
1261
- window.location.assign(signOutRedirect);
1262
- }
1263
- })();
1264
- },
1265
- className: "hover:bg-accent flex w-full items-center gap-2 px-3 py-2 text-left font-mono text-[11px] tracking-wide transition-colors",
1374
+ className: cls,
1266
1375
  "data-oc-account-menu-item": "",
1267
- "data-oc-account-menu-signout": "",
1268
- children: [
1269
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1270
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: "sign out" })
1271
- ]
1272
- }
1273
- )
1274
- ] }),
1275
- secondaryNavLinks && secondaryNavLinks.length > 0 ? /* @__PURE__ */ jsx(
1276
- PopoverSection,
1376
+ children: inner
1377
+ },
1378
+ item.href
1379
+ );
1380
+ }),
1381
+ familyDashboardEnabled ? /* @__PURE__ */ jsxs(
1382
+ "a",
1277
1383
  {
1278
- label: "more",
1279
- items: secondaryNavLinks,
1280
- onItemClick: () => setOpen(false),
1281
- bordered: true
1384
+ href: "https://ochk.io/dashboard",
1385
+ target: "_blank",
1386
+ rel: "noreferrer",
1387
+ onClick: () => setOpen(false),
1388
+ role: "menuitem",
1389
+ className: "hover:bg-accent flex items-center gap-2 px-3 py-2 font-mono text-[11px] tracking-wide transition-colors",
1390
+ "data-oc-account-menu-item": "",
1391
+ "data-oc-account-menu-family-dashboard": "",
1392
+ children: [
1393
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1394
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: "family dashboard" }),
1395
+ /* @__PURE__ */ jsx(
1396
+ "span",
1397
+ {
1398
+ className: "text-muted-foreground/70 text-[10px]",
1399
+ "aria-hidden": true,
1400
+ children: "\u2197"
1401
+ }
1402
+ )
1403
+ ]
1282
1404
  }
1283
1405
  ) : null,
1284
- build ? /* @__PURE__ */ jsx(BuildFooter, { hostname, build, state: siteState }) : null
1285
- ]
1286
- }
1287
- )
1288
- ]
1289
- }
1406
+ /* @__PURE__ */ jsxs(
1407
+ "button",
1408
+ {
1409
+ type: "button",
1410
+ role: "menuitem",
1411
+ onClick: () => {
1412
+ setOpen(false);
1413
+ void (async () => {
1414
+ await signOut();
1415
+ if (typeof window !== "undefined") {
1416
+ window.location.assign(signOutRedirect);
1417
+ }
1418
+ })();
1419
+ },
1420
+ className: "hover:bg-accent flex w-full items-center gap-2 px-3 py-2 text-left font-mono text-[11px] tracking-wide transition-colors",
1421
+ "data-oc-account-menu-item": "",
1422
+ "data-oc-account-menu-signout": "",
1423
+ children: [
1424
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1425
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: "sign out" })
1426
+ ]
1427
+ }
1428
+ )
1429
+ ] }),
1430
+ secondaryNavLinks && secondaryNavLinks.length > 0 ? /* @__PURE__ */ jsx(
1431
+ PopoverSection,
1432
+ {
1433
+ label: "more",
1434
+ items: secondaryNavLinks,
1435
+ onItemClick: () => setOpen(false),
1436
+ bordered: true,
1437
+ className: "hidden md:block"
1438
+ }
1439
+ ) : null,
1440
+ build ? /* @__PURE__ */ jsx(BuildFooter, { hostname, build, state: siteState }) : null
1441
+ ]
1442
+ }
1443
+ )
1444
+ ] })
1290
1445
  );
1291
1446
  }
1292
1447
  function AccountsSection({
@@ -1399,33 +1554,22 @@ function PopoverSection({
1399
1554
  label,
1400
1555
  items,
1401
1556
  onItemClick,
1402
- bordered
1557
+ bordered,
1558
+ className
1403
1559
  }) {
1404
1560
  const cls = "hover:bg-accent flex items-center gap-2 px-3 py-2 font-mono text-[11px] tracking-wide transition-colors";
1405
1561
  return /* @__PURE__ */ jsxs(
1406
1562
  "div",
1407
1563
  {
1408
- className: "p-1 " + (bordered ? "border-border border-t" : ""),
1564
+ className: cn("p-1", bordered && "border-border border-t", className),
1409
1565
  "data-oc-account-menu-section": label,
1410
1566
  children: [
1411
1567
  /* @__PURE__ */ jsxs("div", { className: "text-muted-foreground/60 px-3 pt-2 pb-1 font-mono text-[10px] tracking-widest uppercase", children: [
1412
1568
  "\xA7 ",
1413
1569
  label
1414
1570
  ] }),
1415
- items.map((item) => {
1416
- const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
1417
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1418
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
1419
- item.external ? /* @__PURE__ */ jsx(
1420
- "span",
1421
- {
1422
- className: "text-muted-foreground/70 text-[10px]",
1423
- "aria-hidden": true,
1424
- children: "\u2197"
1425
- }
1426
- ) : null
1427
- ] });
1428
- return item.external ? /* @__PURE__ */ jsx(
1571
+ items.map(
1572
+ (item) => item.external ? /* @__PURE__ */ jsxs(
1429
1573
  "a",
1430
1574
  {
1431
1575
  href: item.href,
@@ -1435,10 +1579,14 @@ function PopoverSection({
1435
1579
  role: "menuitem",
1436
1580
  className: cls,
1437
1581
  "data-oc-account-menu-item": "",
1438
- children: inner
1582
+ children: [
1583
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1584
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
1585
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70 text-[10px]", "aria-hidden": true, children: "\u2197" })
1586
+ ]
1439
1587
  },
1440
1588
  item.href
1441
- ) : /* @__PURE__ */ jsx(
1589
+ ) : /* @__PURE__ */ jsxs(
1442
1590
  Link5,
1443
1591
  {
1444
1592
  href: item.href,
@@ -1446,11 +1594,14 @@ function PopoverSection({
1446
1594
  role: "menuitem",
1447
1595
  className: cls,
1448
1596
  "data-oc-account-menu-item": "",
1449
- children: inner
1597
+ children: [
1598
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
1599
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label })
1600
+ ]
1450
1601
  },
1451
1602
  item.href
1452
- );
1453
- })
1603
+ )
1604
+ )
1454
1605
  ]
1455
1606
  }
1456
1607
  );
@@ -1511,11 +1662,11 @@ function OcPrimaryNav({
1511
1662
  "nav",
1512
1663
  {
1513
1664
  "aria-label": "primary",
1514
- className: "flex min-w-0 items-center justify-start overflow-x-auto gap-0.5 sm:gap-1 whitespace-nowrap [scrollbar-width:none] [&::-webkit-scrollbar]:hidden " + (className ?? ""),
1665
+ className: "hidden items-center gap-0.5 sm:gap-1 md:flex " + (className ?? ""),
1515
1666
  "data-oc-primary-nav": "",
1516
1667
  children: links.map((link) => {
1517
1668
  const active = isActive(activePath, link);
1518
- const className2 = "font-display shrink-0 px-2 py-1 sm:px-3 text-[11px] sm:text-[12px] font-semibold tracking-wider uppercase transition-colors " + (active ? "text-primary" : "text-muted-foreground hover:text-foreground");
1669
+ const cls = "font-display shrink-0 px-2 py-1 sm:px-3 text-[11px] sm:text-[12px] font-semibold tracking-wider uppercase transition-colors " + (active ? "text-primary" : "text-muted-foreground hover:text-foreground");
1519
1670
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1520
1671
  link.label,
1521
1672
  link.external ? /* @__PURE__ */ jsx(
@@ -1533,7 +1684,7 @@ function OcPrimaryNav({
1533
1684
  href: link.href,
1534
1685
  target: "_blank",
1535
1686
  rel: "noreferrer",
1536
- className: className2,
1687
+ className: cls,
1537
1688
  "data-oc-primary-nav-item": "",
1538
1689
  children: content
1539
1690
  },
@@ -1543,7 +1694,7 @@ function OcPrimaryNav({
1543
1694
  {
1544
1695
  href: link.href,
1545
1696
  "aria-current": active ? "page" : void 0,
1546
- className: className2,
1697
+ className: cls,
1547
1698
  "data-oc-primary-nav-item": active ? "active" : "sibling",
1548
1699
  children: content
1549
1700
  },
@@ -1846,13 +1997,19 @@ function LayoutSubHeader({
1846
1997
  noHeartbeat = false,
1847
1998
  className
1848
1999
  }) {
1849
- return /* @__PURE__ */ jsx("div", { className: cn("border-b", className), children: /* @__PURE__ */ jsxs("div", { className: "container flex flex-wrap items-center justify-between gap-x-6 gap-y-1 py-2 font-mono text-[11px]", children: [
1850
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1851
- !noHeartbeat && /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block h-1.5 w-1.5 animate-pulse rounded-full" }),
1852
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground tracking-widest uppercase", children: status }),
1853
- /* @__PURE__ */ jsx("span", { className: "text-foreground", children: product })
2000
+ return /* @__PURE__ */ jsx("div", { className: cn("oc-substrip border-b", className), children: /* @__PURE__ */ jsxs("div", { className: "container flex items-center justify-between gap-x-6 py-2 font-mono text-[11px]", children: [
2001
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
2002
+ !noHeartbeat && /* @__PURE__ */ jsx(
2003
+ "span",
2004
+ {
2005
+ className: "bg-primary inline-block size-1.5 shrink-0 animate-pulse rounded-full ring-2 ring-[color-mix(in_oklch,var(--primary),transparent_78%)]",
2006
+ "aria-hidden": true
2007
+ }
2008
+ ),
2009
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground hidden tracking-widest whitespace-nowrap uppercase sm:inline", children: status }),
2010
+ /* @__PURE__ */ jsx("span", { className: "text-foreground truncate", children: product })
1854
2011
  ] }),
1855
- tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground flex flex-wrap items-center gap-x-4 gap-y-1 tracking-widest uppercase", children: tags.map((tag, i) => /* @__PURE__ */ jsx("span", { className: tag.hideBelow ? HIDE[tag.hideBelow] : void 0, children: tag.label }, i)) })
2012
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/55 hidden shrink-0 items-center gap-x-3 tracking-wider whitespace-nowrap uppercase sm:flex", children: tags.map((tag, i) => /* @__PURE__ */ jsx("span", { className: tag.hideBelow ? HIDE[tag.hideBelow] : void 0, children: tag.label }, i)) })
1856
2013
  ] }) });
1857
2014
  }
1858
2015
  function OcAppBar({