@consilioweb/payload-seo-analyzer 1.9.0 → 1.11.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/client.cjs CHANGED
@@ -1065,6 +1065,9 @@ var fr = {
1065
1065
  pagesAnalyzed: "pages analys\xE9es",
1066
1066
  markCornerstone: "Marquer pilier",
1067
1067
  unmarkCornerstone: "D\xE9marquer pilier",
1068
+ bulkOptimizeMeta: "Optimiser m\xE9ta (IA)",
1069
+ bulkOptimizing: "Optimisation\u2026",
1070
+ bulkConfirm: "Confirmer ?",
1068
1071
  searchPlaceholder: "Rechercher (titre, slug, keyword)...",
1069
1072
  allCollections: "Toutes les collections",
1070
1073
  allScores: "Tous les scores",
@@ -1657,6 +1660,9 @@ var en = {
1657
1660
  pagesAnalyzed: "pages analyzed",
1658
1661
  markCornerstone: "Mark as cornerstone",
1659
1662
  unmarkCornerstone: "Unmark cornerstone",
1663
+ bulkOptimizeMeta: "Optimize meta (AI)",
1664
+ bulkOptimizing: "Optimizing\u2026",
1665
+ bulkConfirm: "Confirm?",
1660
1666
  searchPlaceholder: "Search (title, slug, keyword)...",
1661
1667
  allCollections: "All collections",
1662
1668
  allScores: "All scores",
@@ -9201,8 +9207,11 @@ function BulkActionBar({
9201
9207
  onExportCsv,
9202
9208
  onMarkCornerstone,
9203
9209
  onUnmarkCornerstone,
9210
+ onOptimizeMeta,
9211
+ optimizing,
9204
9212
  t
9205
9213
  }) {
9214
+ const [confirmOptimize, setConfirmOptimize] = React4.useState(false);
9206
9215
  if (count === 0) return null;
9207
9216
  return /* @__PURE__ */ jsxRuntime.jsxs(
9208
9217
  "div",
@@ -9248,6 +9257,24 @@ function BulkActionBar({
9248
9257
  children: t.common.exportCsv
9249
9258
  }
9250
9259
  ),
9260
+ /* @__PURE__ */ jsxRuntime.jsx(
9261
+ "button",
9262
+ {
9263
+ onClick: () => {
9264
+ if (optimizing) return;
9265
+ if (confirmOptimize) {
9266
+ setConfirmOptimize(false);
9267
+ onOptimizeMeta();
9268
+ } else {
9269
+ setConfirmOptimize(true);
9270
+ setTimeout(() => setConfirmOptimize(false), 4e3);
9271
+ }
9272
+ },
9273
+ disabled: optimizing,
9274
+ style: { ...btnBase, backgroundColor: "#7c3aed", color: "#fff", opacity: optimizing ? 0.6 : 1 },
9275
+ children: optimizing ? t.seoView.bulkOptimizing : confirmOptimize ? t.seoView.bulkConfirm : `\u2728 ${t.seoView.bulkOptimizeMeta}`
9276
+ }
9277
+ ),
9251
9278
  /* @__PURE__ */ jsxRuntime.jsx(
9252
9279
  "button",
9253
9280
  {
@@ -9288,6 +9315,7 @@ function SeoView() {
9288
9315
  const [expandedId, setExpandedId] = React4.useState(null);
9289
9316
  const [saving, setSaving] = React4.useState(false);
9290
9317
  const [saveError, setSaveError] = React4.useState(null);
9318
+ const [bulkOptimizing, setBulkOptimizing] = React4.useState(false);
9291
9319
  const PAGE_SIZE = 50;
9292
9320
  const fetchAudit = React4.useCallback(async (forceRefresh = false) => {
9293
9321
  setLoading(true);
@@ -9508,6 +9536,45 @@ function SeoView() {
9508
9536
  },
9509
9537
  [selectedIds, fetchAudit]
9510
9538
  );
9539
+ const handleBulkOptimizeMeta = React4.useCallback(async () => {
9540
+ const keys = Array.from(selectedIds);
9541
+ if (keys.length === 0) return;
9542
+ setBulkOptimizing(true);
9543
+ for (const key of keys) {
9544
+ const [collection, id] = key.split("::");
9545
+ if (!collection || !id || collection.startsWith("global:")) continue;
9546
+ try {
9547
+ const res = await fetch("/api/seo-plugin/ai-optimize", {
9548
+ method: "POST",
9549
+ headers: { "Content-Type": "application/json" },
9550
+ credentials: "include",
9551
+ body: JSON.stringify({ collection, id })
9552
+ });
9553
+ if (!res.ok) continue;
9554
+ const data = await res.json();
9555
+ const sug = data.suggestions || {};
9556
+ const patch = {};
9557
+ if (sug.metaTitle || sug.metaDescription) {
9558
+ patch.meta = { title: sug.metaTitle, description: sug.metaDescription };
9559
+ }
9560
+ if (sug.focusKeyword && sug.focusKeyword !== data.current?.focusKeyword) {
9561
+ patch.focusKeyword = sug.focusKeyword;
9562
+ }
9563
+ if (Object.keys(patch).length > 0) {
9564
+ await fetch(`/api/${collection}/${id}`, {
9565
+ method: "PATCH",
9566
+ headers: { "Content-Type": "application/json" },
9567
+ credentials: "include",
9568
+ body: JSON.stringify(patch)
9569
+ });
9570
+ }
9571
+ } catch {
9572
+ }
9573
+ }
9574
+ setBulkOptimizing(false);
9575
+ setSelectedIds(/* @__PURE__ */ new Set());
9576
+ fetchAudit();
9577
+ }, [selectedIds, fetchAudit]);
9511
9578
  const handleInlineSave = React4.useCallback(
9512
9579
  async (item, metaTitle, metaDescription) => {
9513
9580
  setSaving(true);
@@ -10256,6 +10323,8 @@ function SeoView() {
10256
10323
  onExportCsv: handleBulkExportCsv,
10257
10324
  onMarkCornerstone: () => handleBulkCornerstone(true),
10258
10325
  onUnmarkCornerstone: () => handleBulkCornerstone(false),
10326
+ onOptimizeMeta: handleBulkOptimizeMeta,
10327
+ optimizing: bulkOptimizing,
10259
10328
  t
10260
10329
  }
10261
10330
  )
@@ -15910,7 +15979,7 @@ function getSchemaTypes(t) {
15910
15979
  }
15911
15980
  };
15912
15981
  }
15913
- function buildJsonLd(type, values) {
15982
+ function buildJsonLd2(type, values) {
15914
15983
  switch (type) {
15915
15984
  case "LocalBusiness": {
15916
15985
  const result = {
@@ -16191,7 +16260,7 @@ function SchemaBuilderView() {
16191
16260
  [arrayName]: (prev[arrayName] || []).filter((_, i) => i !== index)
16192
16261
  }));
16193
16262
  }, []);
16194
- const jsonLd = React4.useMemo(() => buildJsonLd(selectedType, values), [selectedType, values]);
16263
+ const jsonLd = React4.useMemo(() => buildJsonLd2(selectedType, values), [selectedType, values]);
16195
16264
  const jsonString = React4.useMemo(() => JSON.stringify(jsonLd, null, 2), [jsonLd]);
16196
16265
  const scriptTag = React4.useMemo(
16197
16266
  () => `<script type="application/ld+json">
@@ -16968,6 +17037,573 @@ function GscPanel({ locale }) {
16968
17037
  ] })
16969
17038
  ] });
16970
17039
  }
17040
+ var C6 = {
17041
+ text: "var(--theme-text, #1a1a1a)",
17042
+ sub: "var(--theme-elevation-600, #6b7280)",
17043
+ card: "var(--theme-elevation-50, #f9fafb)",
17044
+ border: "var(--theme-elevation-200, #e5e7eb)",
17045
+ green: "#22c55e",
17046
+ red: "#ef4444",
17047
+ blue: "#3b82f6"
17048
+ };
17049
+ var S3 = {
17050
+ fr: {
17051
+ title: "Suivi de positions (rank tracking)",
17052
+ subtitle: "Historique quotidien des positions Google (via Search Console) et mouvements dans le temps.",
17053
+ needGsc: "Connectez Google Search Console ci-dessus pour activer le suivi de positions.",
17054
+ snapshot: "Relever maintenant",
17055
+ snapshotting: "Relev\xE9 en cours\u2026",
17056
+ noData: "Pas encore de donn\xE9es. Le relev\xE9 tourne automatiquement chaque jour ; cliquez \xAB Relever maintenant \xBB pour d\xE9marrer.",
17057
+ lastSnapshot: "Dernier relev\xE9",
17058
+ query: "Requ\xEAte",
17059
+ position: "Position",
17060
+ change: "\xC9volution",
17061
+ clicks: "Clics",
17062
+ impressions: "Impr.",
17063
+ stable: "stable",
17064
+ newQ: "nouveau",
17065
+ countLabel: "requ\xEAtes suivies"
17066
+ },
17067
+ en: {
17068
+ title: "Rank tracking",
17069
+ subtitle: "Daily Google position history (via Search Console) and movement over time.",
17070
+ needGsc: "Connect Google Search Console above to enable rank tracking.",
17071
+ snapshot: "Snapshot now",
17072
+ snapshotting: "Snapshotting\u2026",
17073
+ noData: 'No data yet. The snapshot runs automatically every day; click "Snapshot now" to start.',
17074
+ lastSnapshot: "Last snapshot",
17075
+ query: "Query",
17076
+ position: "Position",
17077
+ change: "Change",
17078
+ clicks: "Clicks",
17079
+ impressions: "Impr.",
17080
+ stable: "stable",
17081
+ newQ: "new",
17082
+ countLabel: "tracked queries"
17083
+ }
17084
+ };
17085
+ function RankTrackingPanel({ locale }) {
17086
+ const s = S3[locale] ?? S3.fr;
17087
+ const [movers, setMovers] = React4.useState(null);
17088
+ const [lastSnapshot, setLastSnapshot] = React4.useState(null);
17089
+ const [loading, setLoading] = React4.useState(true);
17090
+ const [busy, setBusy] = React4.useState(false);
17091
+ const [error, setError] = React4.useState(null);
17092
+ const [notConnected, setNotConnected] = React4.useState(false);
17093
+ const load = React4.useCallback(async () => {
17094
+ setLoading(true);
17095
+ setError(null);
17096
+ try {
17097
+ const res = await fetch("/api/seo-plugin/rank-history", { credentials: "include", cache: "no-store" });
17098
+ if (res.status === 403 || res.status === 409) {
17099
+ setNotConnected(true);
17100
+ setMovers(null);
17101
+ return;
17102
+ }
17103
+ const json = await res.json();
17104
+ if (!res.ok) {
17105
+ setError(json.error || `Error ${res.status}`);
17106
+ return;
17107
+ }
17108
+ setMovers(json.movers || []);
17109
+ setLastSnapshot(json.lastSnapshot || null);
17110
+ } catch (e) {
17111
+ setError(e instanceof Error ? e.message : "Network error");
17112
+ } finally {
17113
+ setLoading(false);
17114
+ }
17115
+ }, []);
17116
+ React4.useEffect(() => {
17117
+ void load();
17118
+ }, [load]);
17119
+ const snapshotNow = async () => {
17120
+ setBusy(true);
17121
+ setError(null);
17122
+ try {
17123
+ const res = await fetch("/api/seo-plugin/rank-snapshot", { method: "POST", credentials: "include" });
17124
+ const json = await res.json();
17125
+ if (res.status === 409) {
17126
+ setNotConnected(true);
17127
+ return;
17128
+ }
17129
+ if (!res.ok) {
17130
+ setError(json.error || json.reason || `Error ${res.status}`);
17131
+ return;
17132
+ }
17133
+ await load();
17134
+ } catch (e) {
17135
+ setError(e instanceof Error ? e.message : "Network error");
17136
+ } finally {
17137
+ setBusy(false);
17138
+ }
17139
+ };
17140
+ const card = {
17141
+ padding: 16,
17142
+ borderRadius: 12,
17143
+ border: `1px solid ${C6.border}`,
17144
+ backgroundColor: C6.card,
17145
+ marginBottom: 20
17146
+ };
17147
+ const btn = {
17148
+ padding: "8px 12px",
17149
+ borderRadius: 8,
17150
+ border: `1px solid ${C6.blue}`,
17151
+ backgroundColor: C6.blue,
17152
+ color: "#fff",
17153
+ fontSize: 12,
17154
+ fontWeight: 700,
17155
+ cursor: busy ? "wait" : "pointer",
17156
+ opacity: busy ? 0.6 : 1
17157
+ };
17158
+ const renderDelta = (m) => {
17159
+ if (m.previousPosition === null) {
17160
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C6.sub, fontSize: 11 }, children: s.newQ });
17161
+ }
17162
+ if (Math.abs(m.delta) < 0.1) {
17163
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C6.sub, fontSize: 11 }, children: [
17164
+ "\u2014 ",
17165
+ s.stable
17166
+ ] });
17167
+ }
17168
+ const up = m.delta > 0;
17169
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: up ? C6.green : C6.red, fontWeight: 700, fontSize: 12 }, children: [
17170
+ up ? "\u25B2" : "\u25BC",
17171
+ " ",
17172
+ Math.abs(m.delta).toFixed(1)
17173
+ ] });
17174
+ };
17175
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
17176
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17178
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C6.text }, children: s.title }),
17179
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C6.sub, marginTop: 2 }, children: s.subtitle })
17180
+ ] }),
17181
+ !notConnected && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: snapshotNow, disabled: busy, style: btn, children: busy ? s.snapshotting : s.snapshot })
17182
+ ] }),
17183
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C6.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
17184
+ notConnected && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C6.sub }, children: s.needGsc }),
17185
+ !notConnected && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
17186
+ lastSnapshot && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 11, color: C6.sub, marginBottom: 8 }, children: [
17187
+ s.lastSnapshot,
17188
+ ": ",
17189
+ new Date(lastSnapshot).toLocaleString(locale),
17190
+ movers ? ` \xB7 ${movers.length} ${s.countLabel}` : ""
17191
+ ] }),
17192
+ loading && !movers && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C6.sub }, children: "\u2026" }),
17193
+ movers && movers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C6.sub }, children: s.noData }),
17194
+ movers && movers.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 12 }, children: [
17195
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { textAlign: "left", color: C6.sub }, children: [
17196
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px" }, children: s.query }),
17197
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.position }),
17198
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.change }),
17199
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.clicks }),
17200
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.impressions })
17201
+ ] }) }),
17202
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: movers.slice(0, 100).map((m, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { borderTop: `1px solid ${C6.border}`, color: C6.text }, children: [
17203
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: m.query }),
17204
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right", fontWeight: 700 }, children: m.position.toFixed(1) }),
17205
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: renderDelta(m) }),
17206
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.clicks }),
17207
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.impressions })
17208
+ ] }, i)) })
17209
+ ] }) })
17210
+ ] })
17211
+ ] });
17212
+ }
17213
+ var C7 = {
17214
+ text: "var(--theme-text, #1a1a1a)",
17215
+ sub: "var(--theme-elevation-600, #6b7280)",
17216
+ card: "var(--theme-elevation-50, #f9fafb)",
17217
+ border: "var(--theme-elevation-200, #e5e7eb)",
17218
+ green: "#22c55e",
17219
+ red: "#ef4444",
17220
+ amber: "#f59e0b",
17221
+ blue: "#3b82f6"
17222
+ };
17223
+ var S4 = {
17224
+ fr: {
17225
+ title: "Monitoring & alertes",
17226
+ subtitle: "Digest p\xE9riodique : r\xE9gressions de score, nouveaux 404, chutes de position (webhook / email).",
17227
+ notConfigured: "Aucun canal configur\xE9. D\xE9finissez SEO_ALERT_WEBHOOK_URL et/ou SEO_ALERT_EMAIL c\xF4t\xE9 serveur, puis activez features.alerts.",
17228
+ webhook: "Webhook",
17229
+ email: "Email",
17230
+ configured: "configur\xE9",
17231
+ missing: "absent",
17232
+ preview: "Aper\xE7u",
17233
+ sendNow: "Envoyer maintenant",
17234
+ sending: "Envoi\u2026",
17235
+ loading: "Chargement\u2026",
17236
+ noIssues: "Aucun probl\xE8me d\xE9tect\xE9 sur la p\xE9riode. \u{1F389}",
17237
+ scoreReg: "R\xE9gressions de score",
17238
+ notFound: "Nouveaux 404",
17239
+ rankDrops: "Chutes de position",
17240
+ sent: "Digest envoy\xE9",
17241
+ nothingToSend: "Rien \xE0 envoyer (aucun probl\xE8me).",
17242
+ issues: "probl\xE8me(s)"
17243
+ },
17244
+ en: {
17245
+ title: "Monitoring & alerts",
17246
+ subtitle: "Periodic digest: score regressions, new 404s, ranking drops (webhook / email).",
17247
+ notConfigured: "No channel configured. Set SEO_ALERT_WEBHOOK_URL and/or SEO_ALERT_EMAIL on the server, then enable features.alerts.",
17248
+ webhook: "Webhook",
17249
+ email: "Email",
17250
+ configured: "configured",
17251
+ missing: "missing",
17252
+ preview: "Preview",
17253
+ sendNow: "Send now",
17254
+ sending: "Sending\u2026",
17255
+ loading: "Loading\u2026",
17256
+ noIssues: "No issues for the period. \u{1F389}",
17257
+ scoreReg: "Score regressions",
17258
+ notFound: "New 404s",
17259
+ rankDrops: "Ranking drops",
17260
+ sent: "Digest sent",
17261
+ nothingToSend: "Nothing to send (no issues).",
17262
+ issues: "issue(s)"
17263
+ }
17264
+ };
17265
+ function AlertsPanel({ locale }) {
17266
+ const s = S4[locale] ?? S4.fr;
17267
+ const [digest, setDigest] = React4.useState(null);
17268
+ const [config, setConfig] = React4.useState(null);
17269
+ const [loading, setLoading] = React4.useState(true);
17270
+ const [busy, setBusy] = React4.useState(false);
17271
+ const [error, setError] = React4.useState(null);
17272
+ const [notice, setNotice] = React4.useState(null);
17273
+ const load = React4.useCallback(async () => {
17274
+ setLoading(true);
17275
+ setError(null);
17276
+ try {
17277
+ const res = await fetch("/api/seo-plugin/alerts-digest", { credentials: "include", cache: "no-store" });
17278
+ if (res.status === 404 || res.status === 403) {
17279
+ setConfig({ webhookConfigured: false, emailConfigured: false, scoreDrop: 0, positionDrop: 0, windowHours: 0 });
17280
+ setDigest(null);
17281
+ return;
17282
+ }
17283
+ const json = await res.json();
17284
+ if (!res.ok) {
17285
+ setError(json.error || `Error ${res.status}`);
17286
+ return;
17287
+ }
17288
+ setDigest(json.digest);
17289
+ setConfig(json.config);
17290
+ } catch (e) {
17291
+ setError(e instanceof Error ? e.message : "Network error");
17292
+ } finally {
17293
+ setLoading(false);
17294
+ }
17295
+ }, []);
17296
+ React4.useEffect(() => {
17297
+ void load();
17298
+ }, [load]);
17299
+ const sendNow = async () => {
17300
+ setBusy(true);
17301
+ setError(null);
17302
+ setNotice(null);
17303
+ try {
17304
+ const res = await fetch("/api/seo-plugin/alerts-run", { method: "POST", credentials: "include" });
17305
+ const json = await res.json();
17306
+ if (!res.ok) {
17307
+ setError(json.error || `Error ${res.status}`);
17308
+ return;
17309
+ }
17310
+ setNotice(json.delivery?.sent ? s.sent : s.nothingToSend);
17311
+ if (json.digest) setDigest(json.digest);
17312
+ } catch (e) {
17313
+ setError(e instanceof Error ? e.message : "Network error");
17314
+ } finally {
17315
+ setBusy(false);
17316
+ }
17317
+ };
17318
+ const card = {
17319
+ padding: 16,
17320
+ borderRadius: 12,
17321
+ border: `1px solid ${C7.border}`,
17322
+ backgroundColor: C7.card,
17323
+ marginBottom: 20
17324
+ };
17325
+ const btn = {
17326
+ padding: "8px 12px",
17327
+ borderRadius: 8,
17328
+ border: `1px solid ${C7.blue}`,
17329
+ backgroundColor: C7.blue,
17330
+ color: "#fff",
17331
+ fontSize: 12,
17332
+ fontWeight: 700,
17333
+ cursor: busy ? "wait" : "pointer",
17334
+ opacity: busy ? 0.6 : 1
17335
+ };
17336
+ const chip = (ok, label) => ({
17337
+ fontSize: 11,
17338
+ fontWeight: 700,
17339
+ padding: "3px 8px",
17340
+ borderRadius: 999,
17341
+ color: "#fff",
17342
+ backgroundColor: ok ? C7.green : C7.sub,
17343
+ marginRight: 6
17344
+ });
17345
+ const hasChannel = config && (config.webhookConfigured || config.emailConfigured);
17346
+ const list = (title, rows) => rows.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 10 }, children: [
17347
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, fontWeight: 700, color: C7.text, marginBottom: 4 }, children: [
17348
+ title,
17349
+ " ",
17350
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C7.amber }, children: [
17351
+ "(",
17352
+ rows.length,
17353
+ ")"
17354
+ ] })
17355
+ ] }),
17356
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 12, color: C7.sub, lineHeight: 1.6 }, children: rows.slice(0, 8).map((r, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: r }, i)) })
17357
+ ] }) : null;
17358
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
17359
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17360
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17361
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C7.text }, children: s.title }),
17362
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C7.sub, marginTop: 2 }, children: s.subtitle })
17363
+ ] }),
17364
+ hasChannel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: sendNow, disabled: busy, style: btn, children: busy ? s.sending : s.sendNow })
17365
+ ] }),
17366
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C7.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
17367
+ notice && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C7.green, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: notice }),
17368
+ config && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
17369
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: chip(config.webhookConfigured, s.webhook), children: [
17370
+ s.webhook,
17371
+ ": ",
17372
+ config.webhookConfigured ? s.configured : s.missing
17373
+ ] }),
17374
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: chip(config.emailConfigured, s.email), children: [
17375
+ s.email,
17376
+ ": ",
17377
+ config.emailConfigured ? s.configured : s.missing
17378
+ ] })
17379
+ ] }),
17380
+ !loading && !hasChannel && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.notConfigured }),
17381
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.loading }),
17382
+ digest && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 8 }, children: [
17383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: C7.sub, marginTop: 6 }, children: [
17384
+ digest.totalIssues,
17385
+ " ",
17386
+ s.issues
17387
+ ] }),
17388
+ digest.totalIssues === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 8, fontSize: 13, color: C7.sub }, children: s.noIssues }),
17389
+ list(
17390
+ s.scoreReg,
17391
+ digest.scoreRegressions.map((r) => `${r.collection}/${r.documentId} \u2014 ${r.from} \u2192 ${r.to} (\u2212${r.drop})`)
17392
+ ),
17393
+ list(s.notFound, digest.newNotFound.map((n) => `${n.url} \u2014 ${n.count}\xD7`)),
17394
+ list(s.rankDrops, digest.rankDrops.map((d) => `\u201C${d.query}\u201D \u2014 #${d.from} \u2192 #${d.to} (\u25BC${d.drop})`))
17395
+ ] })
17396
+ ] });
17397
+ }
17398
+ var C8 = {
17399
+ text: "var(--theme-text, #1a1a1a)",
17400
+ sub: "var(--theme-elevation-600, #6b7280)",
17401
+ card: "var(--theme-elevation-50, #f9fafb)",
17402
+ bg: "var(--theme-elevation-0, #fff)",
17403
+ border: "var(--theme-elevation-200, #e5e7eb)",
17404
+ green: "#22c55e",
17405
+ red: "#ef4444",
17406
+ violet: "#7c3aed"
17407
+ };
17408
+ var S5 = {
17409
+ fr: {
17410
+ title: "Alt-text IA des images",
17411
+ subtitle: "G\xE9n\xE8re l'attribut alt des images qui n'en ont pas (Claude vision), pour l'accessibilit\xE9 et le SEO.",
17412
+ none: "Toutes les images ont un alt. \u{1F389}",
17413
+ forbidden: "R\xE9serv\xE9 aux administrateurs.",
17414
+ disabled: "Fonction IA d\xE9sactiv\xE9e (features.aiFeatures).",
17415
+ missing: "image(s) sans alt",
17416
+ generate: "G\xE9n\xE9rer",
17417
+ generating: "\u2026",
17418
+ apply: "Appliquer",
17419
+ applied: "Appliqu\xE9 \u2713",
17420
+ noKey: "Cl\xE9 API Claude requise (ANTHROPIC_API_KEY).",
17421
+ loading: "Chargement\u2026",
17422
+ refresh: "Rafra\xEEchir"
17423
+ },
17424
+ en: {
17425
+ title: "AI image alt-text",
17426
+ subtitle: "Generate alt text for images that lack one (Claude vision), for accessibility and SEO.",
17427
+ none: "All images have alt text. \u{1F389}",
17428
+ forbidden: "Admins only.",
17429
+ disabled: "AI feature disabled (features.aiFeatures).",
17430
+ missing: "image(s) without alt",
17431
+ generate: "Generate",
17432
+ generating: "\u2026",
17433
+ apply: "Apply",
17434
+ applied: "Applied \u2713",
17435
+ noKey: "Claude API key required (ANTHROPIC_API_KEY).",
17436
+ loading: "Loading\u2026",
17437
+ refresh: "Refresh"
17438
+ }
17439
+ };
17440
+ function AltTextPanel({ locale }) {
17441
+ const s = S5[locale] ?? S5.fr;
17442
+ const [items, setItems] = React4.useState(null);
17443
+ const [collection, setCollection] = React4.useState("media");
17444
+ const [missingCount, setMissingCount] = React4.useState(0);
17445
+ const [loading, setLoading] = React4.useState(true);
17446
+ const [state, setState] = React4.useState({});
17447
+ const [status, setStatus] = React4.useState("ok");
17448
+ const load = React4.useCallback(async () => {
17449
+ setLoading(true);
17450
+ try {
17451
+ const res = await fetch("/api/seo-plugin/alt-text-audit", { credentials: "include", cache: "no-store" });
17452
+ if (res.status === 404) {
17453
+ setStatus("disabled");
17454
+ return;
17455
+ }
17456
+ if (res.status === 403) {
17457
+ setStatus("forbidden");
17458
+ return;
17459
+ }
17460
+ const json = await res.json();
17461
+ setStatus("ok");
17462
+ setItems(json.items || []);
17463
+ setMissingCount(json.missingCount || 0);
17464
+ setCollection(json.collection || "media");
17465
+ } catch {
17466
+ setItems([]);
17467
+ } finally {
17468
+ setLoading(false);
17469
+ }
17470
+ }, []);
17471
+ React4.useEffect(() => {
17472
+ void load();
17473
+ }, [load]);
17474
+ const setRow = (id, patch) => setState((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }));
17475
+ const generate = async (item) => {
17476
+ setRow(item.id, { busy: true, error: void 0 });
17477
+ try {
17478
+ const res = await fetch("/api/seo-plugin/ai-alt-text", {
17479
+ method: "POST",
17480
+ credentials: "include",
17481
+ headers: { "Content-Type": "application/json" },
17482
+ body: JSON.stringify({ collection, id: item.id, apply: false })
17483
+ });
17484
+ const json = await res.json();
17485
+ if (!res.ok) {
17486
+ setRow(item.id, { busy: false, error: json.code === "no_api_key" ? s.noKey : json.error || `Error ${res.status}` });
17487
+ return;
17488
+ }
17489
+ setRow(item.id, { busy: false, alt: json.alt });
17490
+ } catch (e) {
17491
+ setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
17492
+ }
17493
+ };
17494
+ const apply = async (item) => {
17495
+ const alt = state[item.id]?.alt;
17496
+ if (!alt) return;
17497
+ setRow(item.id, { busy: true, error: void 0 });
17498
+ try {
17499
+ const res = await fetch("/api/seo-plugin/ai-alt-text", {
17500
+ method: "POST",
17501
+ credentials: "include",
17502
+ headers: { "Content-Type": "application/json" },
17503
+ body: JSON.stringify({ collection, id: item.id, apply: true, altText: alt })
17504
+ });
17505
+ const json = await res.json();
17506
+ if (!res.ok) {
17507
+ setRow(item.id, { busy: false, error: json.error || `Error ${res.status}` });
17508
+ return;
17509
+ }
17510
+ setRow(item.id, { busy: false, applied: true });
17511
+ } catch (e) {
17512
+ setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
17513
+ }
17514
+ };
17515
+ const card = {
17516
+ padding: 16,
17517
+ borderRadius: 12,
17518
+ border: `1px solid ${C8.border}`,
17519
+ backgroundColor: C8.card,
17520
+ marginBottom: 20
17521
+ };
17522
+ const btn = (bg) => ({
17523
+ padding: "6px 10px",
17524
+ borderRadius: 6,
17525
+ border: `1px solid ${bg}`,
17526
+ backgroundColor: bg,
17527
+ color: "#fff",
17528
+ fontSize: 11,
17529
+ fontWeight: 700,
17530
+ cursor: "pointer"
17531
+ });
17532
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
17533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17534
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17535
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C8.text }, children: s.title }),
17536
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 2 }, children: s.subtitle })
17537
+ ] }),
17538
+ status === "ok" && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void load(), style: btn(C8.sub), children: s.refresh })
17539
+ ] }),
17540
+ status === "forbidden" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.forbidden }),
17541
+ status === "disabled" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.disabled }),
17542
+ status === "ok" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
17543
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.loading }),
17544
+ !loading && items && items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.none }),
17545
+ !loading && items && items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17546
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: C8.sub, marginBottom: 10 }, children: [
17547
+ missingCount,
17548
+ " ",
17549
+ s.missing
17550
+ ] }),
17551
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: items.map((item) => {
17552
+ const rs = state[item.id] || {};
17553
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17554
+ "div",
17555
+ {
17556
+ style: {
17557
+ display: "flex",
17558
+ gap: 12,
17559
+ alignItems: "center",
17560
+ padding: 8,
17561
+ borderRadius: 8,
17562
+ border: `1px solid ${C8.border}`,
17563
+ backgroundColor: C8.bg
17564
+ },
17565
+ children: [
17566
+ /* @__PURE__ */ jsxRuntime.jsx(
17567
+ "img",
17568
+ {
17569
+ src: item.url,
17570
+ alt: "",
17571
+ style: { width: 48, height: 48, objectFit: "cover", borderRadius: 6, flexShrink: 0, border: `1px solid ${C8.border}` }
17572
+ }
17573
+ ),
17574
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
17575
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: C8.sub, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: item.filename }),
17576
+ rs.alt !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
17577
+ "input",
17578
+ {
17579
+ value: rs.alt,
17580
+ onChange: (e) => setRow(item.id, { alt: e.target.value }),
17581
+ disabled: rs.applied,
17582
+ maxLength: 125,
17583
+ style: {
17584
+ width: "100%",
17585
+ marginTop: 4,
17586
+ padding: "4px 8px",
17587
+ fontSize: 12,
17588
+ borderRadius: 6,
17589
+ border: `1px solid ${C8.border}`,
17590
+ backgroundColor: C8.bg,
17591
+ color: C8.text
17592
+ }
17593
+ }
17594
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 4, fontStyle: "italic" }, children: "\u2014" }),
17595
+ rs.error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: C8.red, marginTop: 2 }, children: rs.error })
17596
+ ] }),
17597
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: rs.applied ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, fontWeight: 700, color: C8.green }, children: s.applied }) : rs.alt !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void apply(item), disabled: rs.busy, style: btn(C8.green), children: rs.busy ? s.generating : s.apply }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void generate(item), disabled: rs.busy, style: btn(C8.violet), children: rs.busy ? s.generating : s.generate }) })
17598
+ ]
17599
+ },
17600
+ item.id
17601
+ );
17602
+ }) })
17603
+ ] })
17604
+ ] })
17605
+ ] });
17606
+ }
16971
17607
  var V8 = {
16972
17608
  text: "var(--theme-text, #1a1a1a)",
16973
17609
  textSecondary: "var(--theme-elevation-600, #6b7280)",
@@ -17382,6 +18018,9 @@ function PerformanceView() {
17382
18018
  ),
17383
18019
  /* @__PURE__ */ jsxRuntime.jsx(CoreWebVitalsPanel, { locale }),
17384
18020
  /* @__PURE__ */ jsxRuntime.jsx(GscPanel, { locale }),
18021
+ /* @__PURE__ */ jsxRuntime.jsx(RankTrackingPanel, { locale }),
18022
+ /* @__PURE__ */ jsxRuntime.jsx(AlertsPanel, { locale }),
18023
+ /* @__PURE__ */ jsxRuntime.jsx(AltTextPanel, { locale }),
17385
18024
  showImport && /* @__PURE__ */ jsxRuntime.jsxs(
17386
18025
  "div",
17387
18026
  {
@@ -17905,6 +18544,183 @@ function PerformanceView() {
17905
18544
  }
17906
18545
  );
17907
18546
  }
18547
+ var C9 = {
18548
+ text: "var(--theme-text, #1a1a1a)",
18549
+ sub: "var(--theme-elevation-600, #6b7280)",
18550
+ card: "var(--theme-elevation-50, #f9fafb)",
18551
+ bg: "var(--theme-elevation-0, #fff)",
18552
+ border: "var(--theme-elevation-200, #e5e7eb)",
18553
+ violet: "#7c3aed",
18554
+ red: "#ef4444",
18555
+ blue: "#3b82f6"
18556
+ };
18557
+ var S6 = {
18558
+ fr: {
18559
+ title: "Brief de contenu IA",
18560
+ subtitle: "G\xE9n\xE8re un plan r\xE9dactionnel optimis\xE9 pour un mot-cl\xE9 (plan, entit\xE9s, questions, longueur cible).",
18561
+ placeholder: "Mot-cl\xE9 cible (ex : plombier paris)",
18562
+ generate: "G\xE9n\xE9rer le brief",
18563
+ generating: "G\xE9n\xE9ration\u2026",
18564
+ outline: "Plan sugg\xE9r\xE9",
18565
+ entities: "Entit\xE9s / termes \xE0 couvrir",
18566
+ questions: "Questions \xE0 traiter",
18567
+ links: "Id\xE9es de liens internes",
18568
+ words: "Longueur recommand\xE9e",
18569
+ wordsUnit: "mots",
18570
+ notes: "Conseils",
18571
+ noKey: "Cl\xE9 API Claude requise (ANTHROPIC_API_KEY).",
18572
+ disabled: "Fonction IA d\xE9sactiv\xE9e (features.aiFeatures)."
18573
+ },
18574
+ en: {
18575
+ title: "AI content brief",
18576
+ subtitle: "Generate an optimized writing brief for a keyword (outline, entities, questions, target length).",
18577
+ placeholder: "Target keyword (e.g. paris plumber)",
18578
+ generate: "Generate brief",
18579
+ generating: "Generating\u2026",
18580
+ outline: "Suggested outline",
18581
+ entities: "Entities / terms to cover",
18582
+ questions: "Questions to answer",
18583
+ links: "Internal link ideas",
18584
+ words: "Recommended length",
18585
+ wordsUnit: "words",
18586
+ notes: "Tips",
18587
+ noKey: "Claude API key required (ANTHROPIC_API_KEY).",
18588
+ disabled: "AI feature disabled (features.aiFeatures)."
18589
+ }
18590
+ };
18591
+ function ContentBriefPanel({ locale }) {
18592
+ const s = S6[locale] ?? S6.fr;
18593
+ const [keyword, setKeyword] = React4.useState("");
18594
+ const [brief, setBrief] = React4.useState(null);
18595
+ const [busy, setBusy] = React4.useState(false);
18596
+ const [error, setError] = React4.useState(null);
18597
+ const generate = async () => {
18598
+ if (!keyword.trim()) return;
18599
+ setBusy(true);
18600
+ setError(null);
18601
+ setBrief(null);
18602
+ try {
18603
+ const res = await fetch("/api/seo-plugin/ai-content-brief", {
18604
+ method: "POST",
18605
+ credentials: "include",
18606
+ headers: { "Content-Type": "application/json" },
18607
+ body: JSON.stringify({ keyword: keyword.trim() })
18608
+ });
18609
+ if (res.status === 404) {
18610
+ setError(s.disabled);
18611
+ return;
18612
+ }
18613
+ const json = await res.json();
18614
+ if (!res.ok) {
18615
+ setError(json.code === "no_api_key" ? s.noKey : json.error || `Error ${res.status}`);
18616
+ return;
18617
+ }
18618
+ setBrief(json.brief);
18619
+ } catch (e) {
18620
+ setError(e instanceof Error ? e.message : "Network error");
18621
+ } finally {
18622
+ setBusy(false);
18623
+ }
18624
+ };
18625
+ const card = {
18626
+ padding: 16,
18627
+ borderRadius: 12,
18628
+ border: `1px solid ${C9.border}`,
18629
+ backgroundColor: C9.card,
18630
+ marginBottom: 20
18631
+ };
18632
+ const chip = {
18633
+ display: "inline-block",
18634
+ fontSize: 11,
18635
+ padding: "3px 8px",
18636
+ borderRadius: 999,
18637
+ backgroundColor: "rgba(59,130,246,0.12)",
18638
+ color: C9.blue,
18639
+ border: `1px solid ${C9.border}`,
18640
+ margin: "0 6px 6px 0"
18641
+ };
18642
+ const h4 = { fontSize: 12, fontWeight: 800, color: C9.text, margin: "14px 0 6px", textTransform: "uppercase" };
18643
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
18644
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C9.text }, children: s.title }),
18645
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C9.sub, marginTop: 2, marginBottom: 12 }, children: s.subtitle }),
18646
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
18647
+ /* @__PURE__ */ jsxRuntime.jsx(
18648
+ "input",
18649
+ {
18650
+ value: keyword,
18651
+ onChange: (e) => setKeyword(e.target.value),
18652
+ onKeyDown: (e) => {
18653
+ if (e.key === "Enter") void generate();
18654
+ },
18655
+ placeholder: s.placeholder,
18656
+ style: {
18657
+ flex: 1,
18658
+ minWidth: 220,
18659
+ padding: "8px 12px",
18660
+ fontSize: 13,
18661
+ borderRadius: 8,
18662
+ border: `1px solid ${C9.border}`,
18663
+ backgroundColor: C9.bg,
18664
+ color: C9.text
18665
+ }
18666
+ }
18667
+ ),
18668
+ /* @__PURE__ */ jsxRuntime.jsx(
18669
+ "button",
18670
+ {
18671
+ type: "button",
18672
+ onClick: () => void generate(),
18673
+ disabled: busy || !keyword.trim(),
18674
+ style: {
18675
+ padding: "8px 14px",
18676
+ borderRadius: 8,
18677
+ border: `1px solid ${C9.violet}`,
18678
+ backgroundColor: C9.violet,
18679
+ color: "#fff",
18680
+ fontSize: 12,
18681
+ fontWeight: 700,
18682
+ cursor: busy || !keyword.trim() ? "not-allowed" : "pointer",
18683
+ opacity: busy || !keyword.trim() ? 0.6 : 1
18684
+ },
18685
+ children: busy ? s.generating : `\u2728 ${s.generate}`
18686
+ }
18687
+ )
18688
+ ] }),
18689
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C9.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
18690
+ brief && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 8 }, children: [
18691
+ brief.recommendedWordCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: C9.sub, marginTop: 10 }, children: [
18692
+ s.words,
18693
+ ": ",
18694
+ /* @__PURE__ */ jsxRuntime.jsxs("b", { style: { color: C9.text }, children: [
18695
+ "~",
18696
+ brief.recommendedWordCount,
18697
+ " ",
18698
+ s.wordsUnit
18699
+ ] })
18700
+ ] }),
18701
+ brief.outline.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18702
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: h4, children: s.outline }),
18703
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 13, color: C9.text, lineHeight: 1.6 }, children: brief.outline.map((o, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginLeft: o.level === "h3" ? 18 : 0, color: o.level === "h3" ? C9.sub : C9.text, fontWeight: o.level === "h2" ? 700 : 400 }, children: o.text }, i)) })
18704
+ ] }),
18705
+ brief.entities.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18706
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: h4, children: s.entities }),
18707
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: brief.entities.map((e, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: chip, children: e }, i)) })
18708
+ ] }),
18709
+ brief.questions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18710
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: h4, children: s.questions }),
18711
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 13, color: C9.text, lineHeight: 1.6 }, children: brief.questions.map((q, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: q }, i)) })
18712
+ ] }),
18713
+ brief.internalLinkIdeas.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18714
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: h4, children: s.links }),
18715
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: brief.internalLinkIdeas.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: chip, children: l }, i)) })
18716
+ ] }),
18717
+ brief.notes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18718
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: h4, children: s.notes }),
18719
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 12, color: C9.sub, lineHeight: 1.6 }, children: brief.notes.map((n, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: n }, i)) })
18720
+ ] })
18721
+ ] })
18722
+ ] });
18723
+ }
17908
18724
  var V9 = {
17909
18725
  text: "var(--theme-text, #1a1a1a)",
17910
18726
  textSecondary: "var(--theme-elevation-600, #6b7280)",
@@ -18267,6 +19083,7 @@ function KeywordResearchView() {
18267
19083
  ]
18268
19084
  }
18269
19085
  ),
19086
+ /* @__PURE__ */ jsxRuntime.jsx(ContentBriefPanel, { locale }),
18270
19087
  /* @__PURE__ */ jsxRuntime.jsx(
18271
19088
  "div",
18272
19089
  {
@@ -19041,7 +19858,7 @@ var controlBtnStyle = {
19041
19858
  cursor: "pointer",
19042
19859
  lineHeight: 1.4
19043
19860
  };
19044
- var C6 = {
19861
+ var C10 = {
19045
19862
  cyan: "#00E5FF",
19046
19863
  black: "#000",
19047
19864
  green: "#22c55e",
@@ -19056,10 +19873,10 @@ var C6 = {
19056
19873
  var TITLE_MIN = 30;
19057
19874
  var TITLE_MAX = 60;
19058
19875
  function getCharColor(len) {
19059
- if (len === 0) return C6.textSecondary;
19060
- if (len >= TITLE_MIN && len <= TITLE_MAX) return C6.green;
19061
- if (len > 0 && len < TITLE_MIN) return C6.orange;
19062
- return C6.red;
19876
+ if (len === 0) return C10.textSecondary;
19877
+ if (len >= TITLE_MIN && len <= TITLE_MAX) return C10.green;
19878
+ if (len > 0 && len < TITLE_MIN) return C10.orange;
19879
+ return C10.red;
19063
19880
  }
19064
19881
  function getProgressPercent(len) {
19065
19882
  if (len === 0) return 0;
@@ -19067,9 +19884,9 @@ function getProgressPercent(len) {
19067
19884
  }
19068
19885
  function getProgressColor(len) {
19069
19886
  if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
19070
- if (len >= TITLE_MIN && len <= TITLE_MAX) return C6.green;
19071
- if (len < TITLE_MIN) return C6.orange;
19072
- return C6.red;
19887
+ if (len >= TITLE_MIN && len <= TITLE_MAX) return C10.green;
19888
+ if (len < TITLE_MIN) return C10.orange;
19889
+ return C10.red;
19073
19890
  }
19074
19891
  function MetaTitleField({
19075
19892
  path,
@@ -19140,7 +19957,7 @@ function MetaTitleField({
19140
19957
  style: {
19141
19958
  fontSize: 13,
19142
19959
  fontWeight: 700,
19143
- color: C6.textPrimary
19960
+ color: C10.textPrimary
19144
19961
  },
19145
19962
  children: t.metaTitle.label
19146
19963
  }
@@ -19180,9 +19997,9 @@ function MetaTitleField({
19180
19997
  fontSize: 14,
19181
19998
  fontFamily: "inherit",
19182
19999
  borderRadius: 8,
19183
- border: `2px solid ${C6.border}`,
19184
- backgroundColor: C6.surfaceBg,
19185
- color: C6.textPrimary,
20000
+ border: `2px solid ${C10.border}`,
20001
+ backgroundColor: C10.surfaceBg,
20002
+ color: C10.textPrimary,
19186
20003
  outline: "none",
19187
20004
  boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
19188
20005
  }
@@ -19200,9 +20017,9 @@ function MetaTitleField({
19200
20017
  gap: 5,
19201
20018
  padding: "8px 14px",
19202
20019
  borderRadius: 8,
19203
- border: `2px solid ${C6.border}`,
19204
- backgroundColor: loading ? C6.surface50 : C6.cyan,
19205
- color: loading ? C6.textSecondary : C6.black,
20020
+ border: `2px solid ${C10.border}`,
20021
+ backgroundColor: loading ? C10.surface50 : C10.cyan,
20022
+ color: loading ? C10.textSecondary : C10.black,
19206
20023
  fontWeight: 800,
19207
20024
  fontSize: 11,
19208
20025
  textTransform: "uppercase",
@@ -19249,7 +20066,7 @@ function MetaTitleField({
19249
20066
  justifyContent: "space-between",
19250
20067
  marginTop: 4,
19251
20068
  fontSize: 10,
19252
- color: C6.textSecondary
20069
+ color: C10.textSecondary
19253
20070
  },
19254
20071
  children: [
19255
20072
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
@@ -19283,9 +20100,9 @@ function MetaTitleField({
19283
20100
  borderRadius: 6,
19284
20101
  fontSize: 11,
19285
20102
  fontWeight: 600,
19286
- color: C6.red,
20103
+ color: C10.red,
19287
20104
  backgroundColor: "rgba(239,68,68,0.08)",
19288
- border: `1px solid ${C6.red}`
20105
+ border: `1px solid ${C10.red}`
19289
20106
  },
19290
20107
  children: error
19291
20108
  }
@@ -19294,7 +20111,7 @@ function MetaTitleField({
19294
20111
  }
19295
20112
  );
19296
20113
  }
19297
- var C7 = {
20114
+ var C11 = {
19298
20115
  cyan: "#00E5FF",
19299
20116
  black: "#000",
19300
20117
  green: "#22c55e",
@@ -19309,10 +20126,10 @@ var C7 = {
19309
20126
  var DESC_MIN = 120;
19310
20127
  var DESC_MAX = 160;
19311
20128
  function getCharColor2(len) {
19312
- if (len === 0) return C7.textSecondary;
19313
- if (len >= DESC_MIN && len <= DESC_MAX) return C7.green;
19314
- if (len > 0 && len < DESC_MIN) return C7.orange;
19315
- return C7.red;
20129
+ if (len === 0) return C11.textSecondary;
20130
+ if (len >= DESC_MIN && len <= DESC_MAX) return C11.green;
20131
+ if (len > 0 && len < DESC_MIN) return C11.orange;
20132
+ return C11.red;
19316
20133
  }
19317
20134
  function getProgressPercent2(len) {
19318
20135
  if (len === 0) return 0;
@@ -19320,9 +20137,9 @@ function getProgressPercent2(len) {
19320
20137
  }
19321
20138
  function getProgressColor2(len) {
19322
20139
  if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
19323
- if (len >= DESC_MIN && len <= DESC_MAX) return C7.green;
19324
- if (len < DESC_MIN) return C7.orange;
19325
- return C7.red;
20140
+ if (len >= DESC_MIN && len <= DESC_MAX) return C11.green;
20141
+ if (len < DESC_MIN) return C11.orange;
20142
+ return C11.red;
19326
20143
  }
19327
20144
  function MetaDescriptionField({
19328
20145
  path,
@@ -19393,7 +20210,7 @@ function MetaDescriptionField({
19393
20210
  style: {
19394
20211
  fontSize: 13,
19395
20212
  fontWeight: 700,
19396
- color: C7.textPrimary
20213
+ color: C11.textPrimary
19397
20214
  },
19398
20215
  children: t.metaDescription.label
19399
20216
  }
@@ -19433,9 +20250,9 @@ function MetaDescriptionField({
19433
20250
  fontSize: 14,
19434
20251
  fontFamily: "inherit",
19435
20252
  borderRadius: 8,
19436
- border: `2px solid ${C7.border}`,
19437
- backgroundColor: C7.surfaceBg,
19438
- color: C7.textPrimary,
20253
+ border: `2px solid ${C11.border}`,
20254
+ backgroundColor: C11.surfaceBg,
20255
+ color: C11.textPrimary,
19439
20256
  outline: "none",
19440
20257
  resize: "vertical",
19441
20258
  lineHeight: 1.5,
@@ -19455,9 +20272,9 @@ function MetaDescriptionField({
19455
20272
  gap: 5,
19456
20273
  padding: "8px 14px",
19457
20274
  borderRadius: 8,
19458
- border: `2px solid ${C7.border}`,
19459
- backgroundColor: loading ? C7.surface50 : C7.cyan,
19460
- color: loading ? C7.textSecondary : C7.black,
20275
+ border: `2px solid ${C11.border}`,
20276
+ backgroundColor: loading ? C11.surface50 : C11.cyan,
20277
+ color: loading ? C11.textSecondary : C11.black,
19461
20278
  fontWeight: 800,
19462
20279
  fontSize: 11,
19463
20280
  textTransform: "uppercase",
@@ -19505,7 +20322,7 @@ function MetaDescriptionField({
19505
20322
  justifyContent: "space-between",
19506
20323
  marginTop: 4,
19507
20324
  fontSize: 10,
19508
- color: C7.textSecondary
20325
+ color: C11.textSecondary
19509
20326
  },
19510
20327
  children: [
19511
20328
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
@@ -19539,9 +20356,9 @@ function MetaDescriptionField({
19539
20356
  borderRadius: 6,
19540
20357
  fontSize: 11,
19541
20358
  fontWeight: 600,
19542
- color: C7.red,
20359
+ color: C11.red,
19543
20360
  backgroundColor: "rgba(239,68,68,0.08)",
19544
- border: `1px solid ${C7.red}`
20361
+ border: `1px solid ${C11.red}`
19545
20362
  },
19546
20363
  children: error
19547
20364
  }
@@ -19550,7 +20367,7 @@ function MetaDescriptionField({
19550
20367
  }
19551
20368
  );
19552
20369
  }
19553
- var C8 = {
20370
+ var C12 = {
19554
20371
  cyan: "#00E5FF",
19555
20372
  black: "#000",
19556
20373
  white: "#fff",
@@ -19627,8 +20444,8 @@ function MetaImageField({
19627
20444
  gap: 10,
19628
20445
  padding: "10px 14px",
19629
20446
  borderRadius: 8,
19630
- border: `2px solid ${C8.border}`,
19631
- backgroundColor: C8.surfaceBg,
20447
+ border: `2px solid ${C12.border}`,
20448
+ backgroundColor: C12.surfaceBg,
19632
20449
  boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
19633
20450
  },
19634
20451
  children: [
@@ -19647,7 +20464,7 @@ function MetaImageField({
19647
20464
  fontWeight: 900,
19648
20465
  backgroundColor: hasImage ? "rgba(34,197,94,0.15)" : "rgba(255,138,0,0.15)",
19649
20466
  color: hasImage ? "#16a34a" : "#d97706",
19650
- border: `1px solid ${hasImage ? C8.green : C8.orange}`
20467
+ border: `1px solid ${hasImage ? C12.green : C12.orange}`
19651
20468
  },
19652
20469
  children: hasImage ? "\u2713" : "!"
19653
20470
  }
@@ -19659,7 +20476,7 @@ function MetaImageField({
19659
20476
  style: {
19660
20477
  fontSize: 12,
19661
20478
  fontWeight: 700,
19662
- color: C8.textPrimary
20479
+ color: C12.textPrimary
19663
20480
  },
19664
20481
  children: t.metaImage.label
19665
20482
  }
@@ -19669,7 +20486,7 @@ function MetaImageField({
19669
20486
  {
19670
20487
  style: {
19671
20488
  fontSize: 10,
19672
- color: C8.textSecondary,
20489
+ color: C12.textSecondary,
19673
20490
  lineHeight: 1.4
19674
20491
  },
19675
20492
  children: hasImage ? t.metaImage.imageSet : t.metaImage.noImage
@@ -19689,9 +20506,9 @@ function MetaImageField({
19689
20506
  gap: 5,
19690
20507
  padding: "8px 14px",
19691
20508
  borderRadius: 8,
19692
- border: `2px solid ${C8.border}`,
19693
- backgroundColor: loading ? C8.surface50 : success ? C8.green : C8.cyan,
19694
- color: loading ? C8.textSecondary : success ? C8.white : C8.black,
20509
+ border: `2px solid ${C12.border}`,
20510
+ backgroundColor: loading ? C12.surface50 : success ? C12.green : C12.cyan,
20511
+ color: loading ? C12.textSecondary : success ? C12.white : C12.black,
19695
20512
  fontWeight: 800,
19696
20513
  fontSize: 11,
19697
20514
  textTransform: "uppercase",
@@ -19718,9 +20535,9 @@ function MetaImageField({
19718
20535
  borderRadius: 6,
19719
20536
  fontSize: 11,
19720
20537
  fontWeight: 600,
19721
- color: C8.red,
20538
+ color: C12.red,
19722
20539
  backgroundColor: "rgba(239,68,68,0.08)",
19723
- border: `1px solid ${C8.red}`
20540
+ border: `1px solid ${C12.red}`
19724
20541
  },
19725
20542
  children: error
19726
20543
  }
@@ -19729,7 +20546,7 @@ function MetaImageField({
19729
20546
  }
19730
20547
  );
19731
20548
  }
19732
- var C9 = {
20549
+ var C13 = {
19733
20550
  black: "#000",
19734
20551
  white: "#fff",
19735
20552
  green: "#22c55e",
@@ -19743,15 +20560,15 @@ var C9 = {
19743
20560
  function getCompletenessColor(count) {
19744
20561
  switch (count) {
19745
20562
  case 0:
19746
- return C9.red;
20563
+ return C13.red;
19747
20564
  case 1:
19748
- return C9.orange;
20565
+ return C13.orange;
19749
20566
  case 2:
19750
- return C9.yellow;
20567
+ return C13.yellow;
19751
20568
  case 3:
19752
- return C9.green;
20569
+ return C13.green;
19753
20570
  default:
19754
- return C9.textSecondary;
20571
+ return C13.textSecondary;
19755
20572
  }
19756
20573
  }
19757
20574
  function getCompletenessLabel(count, ov) {
@@ -19809,8 +20626,8 @@ function OverviewField({
19809
20626
  fontFamily: "var(--font-body, Inter, system-ui, sans-serif)",
19810
20627
  padding: "12px 14px",
19811
20628
  borderRadius: 10,
19812
- border: `2px solid ${C9.border}`,
19813
- backgroundColor: C9.surfaceBg,
20629
+ border: `2px solid ${C13.border}`,
20630
+ backgroundColor: C13.surfaceBg,
19814
20631
  boxShadow: "3px 3px 0 0 var(--theme-border-color, rgba(0,0,0,1))",
19815
20632
  marginBottom: 12
19816
20633
  },
@@ -19833,7 +20650,7 @@ function OverviewField({
19833
20650
  fontWeight: 800,
19834
20651
  textTransform: "uppercase",
19835
20652
  letterSpacing: "0.04em",
19836
- color: C9.textPrimary
20653
+ color: C13.textPrimary
19837
20654
  },
19838
20655
  children: t.overview.metaCompleteness
19839
20656
  }
@@ -19848,8 +20665,8 @@ function OverviewField({
19848
20665
  fontSize: 11,
19849
20666
  fontWeight: 800,
19850
20667
  backgroundColor: completenessColor,
19851
- color: completenessColor === C9.yellow ? C9.black : C9.white,
19852
- border: `2px solid ${C9.border}`,
20668
+ color: completenessColor === C13.yellow ? C13.black : C13.white,
20669
+ border: `2px solid ${C13.border}`,
19853
20670
  textTransform: "uppercase",
19854
20671
  letterSpacing: "0.03em"
19855
20672
  },
@@ -19947,7 +20764,7 @@ function OverviewField({
19947
20764
  style: {
19948
20765
  fontSize: 12,
19949
20766
  fontWeight: 600,
19950
- color: item.filled ? C9.textPrimary : C9.textSecondary
20767
+ color: item.filled ? C13.textPrimary : C13.textSecondary
19951
20768
  },
19952
20769
  children: item.label
19953
20770
  }
@@ -19959,7 +20776,7 @@ function OverviewField({
19959
20776
  marginLeft: "auto",
19960
20777
  fontSize: 10,
19961
20778
  fontWeight: 700,
19962
- color: item.filled ? C9.green : C9.red,
20779
+ color: item.filled ? C13.green : C13.red,
19963
20780
  textTransform: "uppercase",
19964
20781
  letterSpacing: "0.03em"
19965
20782
  },
@@ -19976,7 +20793,7 @@ function OverviewField({
19976
20793
  }
19977
20794
  );
19978
20795
  }
19979
- var C10 = {
20796
+ var C14 = {
19980
20797
  cyan: "#00E5FF",
19981
20798
  black: "#000",
19982
20799
  white: "#fff",
@@ -19995,10 +20812,10 @@ var G = {
19995
20812
  descGrey: "#4d5156",
19996
20813
  faviconBg: "#e8eaed"};
19997
20814
  function charCountColor2(len, min, max) {
19998
- if (len >= min && len <= max) return C10.green;
19999
- if (len > 0 && len < min) return C10.orange;
20000
- if (len > max) return C10.red;
20001
- return C10.textSecondary;
20815
+ if (len >= min && len <= max) return C14.green;
20816
+ if (len > 0 && len < min) return C14.orange;
20817
+ if (len > max) return C14.red;
20818
+ return C14.textSecondary;
20002
20819
  }
20003
20820
  function truncateText(text, maxChars) {
20004
20821
  if (text.length <= maxChars) return text;
@@ -20053,8 +20870,8 @@ function SerpPreview({
20053
20870
  padding: "10px 12px",
20054
20871
  cursor: "pointer",
20055
20872
  borderRadius: 8,
20056
- border: `2px solid ${C10.border}`,
20057
- backgroundColor: C10.surface50,
20873
+ border: `2px solid ${C14.border}`,
20874
+ backgroundColor: C14.surface50,
20058
20875
  userSelect: "none"
20059
20876
  },
20060
20877
  children: [
@@ -20069,7 +20886,7 @@ function SerpPreview({
20069
20886
  fontWeight: 800,
20070
20887
  textTransform: "uppercase",
20071
20888
  letterSpacing: "0.04em",
20072
- color: C10.textPrimary
20889
+ color: C14.textPrimary
20073
20890
  },
20074
20891
  children: [
20075
20892
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -20101,7 +20918,7 @@ function SerpPreview({
20101
20918
  transition: "transform 0.2s",
20102
20919
  display: "inline-block",
20103
20920
  transform: open ? "rotate(90deg)" : "none",
20104
- color: C10.textSecondary
20921
+ color: C14.textSecondary
20105
20922
  },
20106
20923
  children: "\u25B6"
20107
20924
  }
@@ -20134,10 +20951,10 @@ function SerpPreview({
20134
20951
  "div",
20135
20952
  {
20136
20953
  style: {
20137
- backgroundColor: C10.white,
20138
- border: `2px solid ${C10.border}`,
20954
+ backgroundColor: C14.white,
20955
+ border: `2px solid ${C14.border}`,
20139
20956
  borderRadius: 12,
20140
- boxShadow: `3px 3px 0 0 ${C10.border}`,
20957
+ boxShadow: `3px 3px 0 0 ${C14.border}`,
20141
20958
  padding: isDesktop ? 20 : 14,
20142
20959
  maxWidth: isDesktop ? 650 : 380,
20143
20960
  overflow: "hidden"
@@ -20200,7 +21017,7 @@ function SerpPreview({
20200
21017
  style: {
20201
21018
  fontSize: 14,
20202
21019
  fontWeight: 400,
20203
- color: C10.black,
21020
+ color: C14.black,
20204
21021
  lineHeight: 1.3,
20205
21022
  whiteSpace: "nowrap",
20206
21023
  overflow: "hidden",
@@ -20264,7 +21081,7 @@ function SerpPreview({
20264
21081
  "span",
20265
21082
  {
20266
21083
  style: {
20267
- color: C10.textSecondary,
21084
+ color: C14.textSecondary,
20268
21085
  fontStyle: "italic",
20269
21086
  fontSize: titleFontSize - 2
20270
21087
  },
@@ -20293,7 +21110,7 @@ function SerpPreview({
20293
21110
  "span",
20294
21111
  {
20295
21112
  style: {
20296
- color: C10.textSecondary,
21113
+ color: C14.textSecondary,
20297
21114
  fontStyle: "italic",
20298
21115
  fontSize: descFontSize - 1
20299
21116
  },
@@ -20326,7 +21143,7 @@ function SerpPreview({
20326
21143
  fontSize: 11
20327
21144
  },
20328
21145
  children: [
20329
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewTitle }),
21146
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C14.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewTitle }),
20330
21147
  /* @__PURE__ */ jsxRuntime.jsxs(
20331
21148
  "span",
20332
21149
  {
@@ -20355,7 +21172,7 @@ function SerpPreview({
20355
21172
  fontSize: 11
20356
21173
  },
20357
21174
  children: [
20358
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewDescription }),
21175
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C14.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewDescription }),
20359
21176
  /* @__PURE__ */ jsxRuntime.jsxs(
20360
21177
  "span",
20361
21178
  {
@@ -20384,14 +21201,14 @@ function SerpPreview({
20384
21201
  fontSize: 11
20385
21202
  },
20386
21203
  children: [
20387
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.url }),
21204
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C14.textSecondary, fontWeight: 600 }, children: t.serpPreview.url }),
20388
21205
  /* @__PURE__ */ jsxRuntime.jsxs(
20389
21206
  "span",
20390
21207
  {
20391
21208
  style: {
20392
21209
  fontWeight: 700,
20393
21210
  fontVariantNumeric: "tabular-nums",
20394
- color: fullUrl.length <= 75 ? C10.green : C10.red
21211
+ color: fullUrl.length <= 75 ? C14.green : C14.red
20395
21212
  },
20396
21213
  children: [
20397
21214
  fullUrl.length,
@@ -20426,13 +21243,13 @@ function DeviceButton({
20426
21243
  gap: 5,
20427
21244
  padding: "4px 12px",
20428
21245
  borderRadius: 6,
20429
- border: `2px solid ${C10.border}`,
21246
+ border: `2px solid ${C14.border}`,
20430
21247
  fontSize: 11,
20431
21248
  fontWeight: 700,
20432
21249
  cursor: "pointer",
20433
- backgroundColor: active ? C10.cyan : C10.surfaceBg,
20434
- color: active ? C10.black : C10.textPrimary,
20435
- boxShadow: active ? `2px 2px 0 0 ${C10.border}` : "none",
21250
+ backgroundColor: active ? C14.cyan : C14.surfaceBg,
21251
+ color: active ? C14.black : C14.textPrimary,
21252
+ boxShadow: active ? `2px 2px 0 0 ${C14.border}` : "none",
20436
21253
  transition: "background-color 0.15s"
20437
21254
  },
20438
21255
  children: [