@consilioweb/payload-seo-analyzer 1.8.1 → 1.10.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.js CHANGED
@@ -1052,6 +1052,8 @@ var fr = {
1052
1052
  },
1053
1053
  seoView: {
1054
1054
  loadingAudit: "Chargement de l'audit SEO...",
1055
+ buildingAudit: "G\xE9n\xE9ration de l'audit SEO en cours\u2026 (calcul\xE9 en arri\xE8re-plan pour ne pas surcharger le serveur, cela peut prendre un moment sur un gros site)",
1056
+ buildTimeout: "La g\xE9n\xE9ration de l'audit prend plus de temps que pr\xE9vu. R\xE9essayez dans quelques instants.",
1055
1057
  errorSaving: "Erreur lors de la sauvegarde",
1056
1058
  auditTitle: "Audit SEO",
1057
1059
  pagesAnalyzed: "pages analys\xE9es",
@@ -1494,7 +1496,19 @@ var fr = {
1494
1496
  generateMeta: "G\xE9n\xE9rer les meta",
1495
1497
  metaTitle: "Meta Title",
1496
1498
  metaDescription: "Meta Description",
1497
- emptyValue: "(vide)"
1499
+ emptyValue: "(vide)",
1500
+ optimizeWithAi: "Optimiser avec l'IA",
1501
+ optimizeIntro: "L'IA analyse la page et propose des meta optimis\xE9es (titre, description, mot-cl\xE9). V\xE9rifiez puis appliquez.",
1502
+ optimizeRunning: "Analyse en cours\u2026",
1503
+ applyAll: "Appliquer",
1504
+ applied: "Appliqu\xE9",
1505
+ whyChanges: "Pourquoi ces changements",
1506
+ labelCurrent: "Actuel",
1507
+ labelSuggested: "Sugg\xE9r\xE9",
1508
+ labelFocusKeyword: "Mot-cl\xE9 cible",
1509
+ heuristicNote: "Suggestions heuristiques (cl\xE9 API Claude non configur\xE9e).",
1510
+ applySaveHint: "Champs remplis \u2014 pensez \xE0 enregistrer le document.",
1511
+ noMetaChange: "Aucun changement propos\xE9."
1498
1512
  },
1499
1513
  scoreHistory: {
1500
1514
  loading: "Chargement de l'historique...",
@@ -1630,6 +1644,8 @@ var en = {
1630
1644
  },
1631
1645
  seoView: {
1632
1646
  loadingAudit: "Loading SEO audit...",
1647
+ buildingAudit: "Building the SEO audit\u2026 (computed in the background to avoid overloading the server \u2014 this can take a moment on a large site)",
1648
+ buildTimeout: "The audit is taking longer than expected. Please try again in a moment.",
1633
1649
  errorSaving: "Error during save",
1634
1650
  auditTitle: "SEO Audit",
1635
1651
  pagesAnalyzed: "pages analyzed",
@@ -2072,7 +2088,19 @@ var en = {
2072
2088
  generateMeta: "Generate meta",
2073
2089
  metaTitle: "Meta Title",
2074
2090
  metaDescription: "Meta Description",
2075
- emptyValue: "(empty)"
2091
+ emptyValue: "(empty)",
2092
+ optimizeWithAi: "Optimize with AI",
2093
+ optimizeIntro: "AI analyzes the page and proposes optimized meta tags (title, description, keyword). Review, then apply.",
2094
+ optimizeRunning: "Analyzing\u2026",
2095
+ applyAll: "Apply",
2096
+ applied: "Applied",
2097
+ whyChanges: "Why these changes",
2098
+ labelCurrent: "Current",
2099
+ labelSuggested: "Suggested",
2100
+ labelFocusKeyword: "Focus keyword",
2101
+ heuristicNote: "Heuristic suggestions (Claude API key not configured).",
2102
+ applySaveHint: "Fields filled \u2014 remember to save the document.",
2103
+ noMetaChange: "No changes proposed."
2076
2104
  },
2077
2105
  scoreHistory: {
2078
2106
  loading: "Loading history...",
@@ -6478,9 +6506,11 @@ var C2 = {
6478
6506
  white: "#fff",
6479
6507
  green: "#22c55e",
6480
6508
  red: "#ef4444",
6509
+ bg: "#fafafa",
6481
6510
  textPrimary: "var(--theme-text, #1a1a1a)",
6482
6511
  textSecondary: "var(--theme-elevation-600, #6b7280)",
6483
6512
  border: "var(--theme-border-color, #000)",
6513
+ inputBg: "var(--theme-input-bg, #fff)",
6484
6514
  surfaceBg: "var(--theme-elevation-0, #fff)",
6485
6515
  surface50: "var(--theme-elevation-50, #f9fafb)"
6486
6516
  };
@@ -6980,10 +7010,48 @@ function useInternalLinkSuggestions(documentId, collection, textContent) {
6980
7010
  }, [textContent, documentId, collection]);
6981
7011
  return { suggestions, loading };
6982
7012
  }
7013
+ function AiDiffRow({
7014
+ label,
7015
+ current,
7016
+ suggested,
7017
+ labelCurrent,
7018
+ labelSuggested,
7019
+ emptyValue,
7020
+ C: colors
7021
+ }) {
7022
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 10 }, children: [
7023
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 10, fontWeight: 700, color: colors.textSecondary, textTransform: "uppercase", marginBottom: 4 }, children: label }),
7024
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 11, color: colors.textSecondary, marginBottom: 3 }, children: [
7025
+ /* @__PURE__ */ jsxs("span", { style: { fontWeight: 700 }, children: [
7026
+ labelCurrent,
7027
+ ": "
7028
+ ] }),
7029
+ /* @__PURE__ */ jsx("span", { style: { textDecoration: current ? "line-through" : "none", opacity: 0.7 }, children: current || emptyValue })
7030
+ ] }),
7031
+ /* @__PURE__ */ jsxs(
7032
+ "div",
7033
+ {
7034
+ style: {
7035
+ padding: "6px 10px",
7036
+ borderRadius: 6,
7037
+ border: `1px solid var(--theme-elevation-200, #e5e7eb)`,
7038
+ backgroundColor: colors.surface50,
7039
+ fontSize: 12,
7040
+ color: colors.textPrimary,
7041
+ lineHeight: 1.5
7042
+ },
7043
+ children: [
7044
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 10, fontWeight: 700, color: colors.green, textTransform: "uppercase", marginRight: 6 }, children: labelSuggested }),
7045
+ suggested || emptyValue
7046
+ ]
7047
+ }
7048
+ )
7049
+ ] });
7050
+ }
6983
7051
  var SeoAnalyzer = () => {
6984
7052
  const locale = useSeoLocale();
6985
7053
  const t = getDashboardT(locale);
6986
- const [formFields] = useAllFormFields();
7054
+ const [formFields, dispatchFields] = useAllFormFields();
6987
7055
  const initialScoreRef = useRef(null);
6988
7056
  const [suggestionsOpen, setSuggestionsOpen] = useState(true);
6989
7057
  const [cannibalizationExpanded, setCannibalizationExpanded] = useState(false);
@@ -6992,6 +7060,10 @@ var SeoAnalyzer = () => {
6992
7060
  const [aiGenerating, setAiGenerating] = useState(false);
6993
7061
  const [aiResult, setAiResult] = useState(null);
6994
7062
  const [aiCopied, setAiCopied] = useState(null);
7063
+ const [aiOptimizing, setAiOptimizing] = useState(false);
7064
+ const [aiOptimizeResult, setAiOptimizeResult] = useState(null);
7065
+ const [aiOptimizeApplied, setAiOptimizeApplied] = useState(false);
7066
+ const [aiOptimizeError, setAiOptimizeError] = useState(false);
6995
7067
  const getFieldValue = useCallback(
6996
7068
  (path) => {
6997
7069
  if (!formFields) return void 0;
@@ -7719,6 +7791,145 @@ var SeoAnalyzer = () => {
7719
7791
  }
7720
7792
  )
7721
7793
  ] }),
7794
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
7795
+ /* @__PURE__ */ jsx(
7796
+ "button",
7797
+ {
7798
+ type: "button",
7799
+ disabled: aiOptimizing || !documentId,
7800
+ title: !documentId ? t.seoAnalyzer.applySaveHint : void 0,
7801
+ onClick: async () => {
7802
+ setAiOptimizing(true);
7803
+ setAiOptimizeResult(null);
7804
+ setAiOptimizeApplied(false);
7805
+ setAiOptimizeError(false);
7806
+ try {
7807
+ const res = await fetch("/api/seo-plugin/ai-optimize", {
7808
+ method: "POST",
7809
+ credentials: "include",
7810
+ headers: { "Content-Type": "application/json" },
7811
+ body: JSON.stringify({ collection: currentCollection, id: documentId })
7812
+ });
7813
+ if (res.ok) {
7814
+ setAiOptimizeResult(await res.json());
7815
+ } else {
7816
+ setAiOptimizeError(true);
7817
+ }
7818
+ } catch {
7819
+ setAiOptimizeError(true);
7820
+ }
7821
+ setAiOptimizing(false);
7822
+ },
7823
+ style: {
7824
+ display: "flex",
7825
+ alignItems: "center",
7826
+ gap: 6,
7827
+ width: "100%",
7828
+ padding: "10px 14px",
7829
+ borderRadius: 8,
7830
+ border: `2px solid ${C2.border}`,
7831
+ backgroundColor: "#7c3aed",
7832
+ color: "#fff",
7833
+ fontWeight: 800,
7834
+ fontSize: 12,
7835
+ cursor: aiOptimizing || !documentId ? "not-allowed" : "pointer",
7836
+ opacity: aiOptimizing || !documentId ? 0.6 : 1,
7837
+ textTransform: "uppercase",
7838
+ letterSpacing: "0.04em",
7839
+ justifyContent: "center",
7840
+ boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
7841
+ },
7842
+ children: aiOptimizing ? t.seoAnalyzer.optimizeRunning : `\u2728 ${t.seoAnalyzer.optimizeWithAi}`
7843
+ }
7844
+ ),
7845
+ aiOptimizeError && /* @__PURE__ */ jsx("div", { style: { marginTop: 8, padding: "8px 12px", borderRadius: 6, fontSize: 11, color: C2.white, backgroundColor: C2.red }, children: t.common.loadingError }),
7846
+ aiOptimizeResult && /* @__PURE__ */ jsxs(
7847
+ "div",
7848
+ {
7849
+ style: {
7850
+ marginTop: 8,
7851
+ padding: "12px 14px",
7852
+ borderRadius: 8,
7853
+ border: `2px solid ${C2.border}`,
7854
+ backgroundColor: C2.surfaceBg
7855
+ },
7856
+ children: [
7857
+ aiOptimizeResult.method === "heuristic" && /* @__PURE__ */ jsx("div", { style: { fontSize: 10, color: C2.textSecondary, marginBottom: 8, fontStyle: "italic" }, children: t.seoAnalyzer.heuristicNote }),
7858
+ /* @__PURE__ */ jsx(
7859
+ AiDiffRow,
7860
+ {
7861
+ label: t.seoAnalyzer.metaTitle,
7862
+ current: aiOptimizeResult.current.metaTitle,
7863
+ suggested: aiOptimizeResult.suggestions.metaTitle,
7864
+ labelCurrent: t.seoAnalyzer.labelCurrent,
7865
+ labelSuggested: t.seoAnalyzer.labelSuggested,
7866
+ emptyValue: t.seoAnalyzer.emptyValue,
7867
+ C: C2
7868
+ }
7869
+ ),
7870
+ /* @__PURE__ */ jsx(
7871
+ AiDiffRow,
7872
+ {
7873
+ label: t.seoAnalyzer.metaDescription,
7874
+ current: aiOptimizeResult.current.metaDescription,
7875
+ suggested: aiOptimizeResult.suggestions.metaDescription,
7876
+ labelCurrent: t.seoAnalyzer.labelCurrent,
7877
+ labelSuggested: t.seoAnalyzer.labelSuggested,
7878
+ emptyValue: t.seoAnalyzer.emptyValue,
7879
+ C: C2
7880
+ }
7881
+ ),
7882
+ aiOptimizeResult.suggestions.focusKeyword && aiOptimizeResult.suggestions.focusKeyword !== aiOptimizeResult.current.focusKeyword && /* @__PURE__ */ jsx(
7883
+ AiDiffRow,
7884
+ {
7885
+ label: t.seoAnalyzer.labelFocusKeyword,
7886
+ current: aiOptimizeResult.current.focusKeyword,
7887
+ suggested: aiOptimizeResult.suggestions.focusKeyword,
7888
+ labelCurrent: t.seoAnalyzer.labelCurrent,
7889
+ labelSuggested: t.seoAnalyzer.labelSuggested,
7890
+ emptyValue: t.seoAnalyzer.emptyValue,
7891
+ C: C2
7892
+ }
7893
+ ),
7894
+ aiOptimizeResult.suggestions.rationale.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: 4, marginBottom: 10 }, children: [
7895
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 10, fontWeight: 700, color: C2.textSecondary, textTransform: "uppercase", marginBottom: 4 }, children: t.seoAnalyzer.whyChanges }),
7896
+ /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: 16, fontSize: 11, color: C2.textPrimary, lineHeight: 1.5 }, children: aiOptimizeResult.suggestions.rationale.map((r, i) => /* @__PURE__ */ jsx("li", { children: r }, i)) })
7897
+ ] }),
7898
+ /* @__PURE__ */ jsx(
7899
+ "button",
7900
+ {
7901
+ type: "button",
7902
+ disabled: aiOptimizeApplied,
7903
+ onClick: () => {
7904
+ const sug = aiOptimizeResult.suggestions;
7905
+ if (sug.metaTitle) dispatchFields({ type: "UPDATE", path: "meta.title", value: sug.metaTitle });
7906
+ if (sug.metaDescription) dispatchFields({ type: "UPDATE", path: "meta.description", value: sug.metaDescription });
7907
+ if (sug.focusKeyword && sug.focusKeyword !== aiOptimizeResult.current.focusKeyword) {
7908
+ dispatchFields({ type: "UPDATE", path: "focusKeyword", value: sug.focusKeyword });
7909
+ }
7910
+ setAiOptimizeApplied(true);
7911
+ },
7912
+ style: {
7913
+ width: "100%",
7914
+ padding: "9px 14px",
7915
+ borderRadius: 6,
7916
+ border: `2px solid ${C2.border}`,
7917
+ backgroundColor: aiOptimizeApplied ? C2.green : C2.cyan,
7918
+ color: aiOptimizeApplied ? C2.white : C2.black,
7919
+ fontWeight: 800,
7920
+ fontSize: 11,
7921
+ textTransform: "uppercase",
7922
+ letterSpacing: "0.04em",
7923
+ cursor: aiOptimizeApplied ? "default" : "pointer"
7924
+ },
7925
+ children: aiOptimizeApplied ? `\u2713 ${t.seoAnalyzer.applied}` : t.seoAnalyzer.applyAll
7926
+ }
7927
+ ),
7928
+ aiOptimizeApplied && /* @__PURE__ */ jsx("div", { style: { marginTop: 6, fontSize: 10, color: C2.textSecondary, textAlign: "center" }, children: t.seoAnalyzer.applySaveHint })
7929
+ ]
7930
+ }
7931
+ )
7932
+ ] }),
7722
7933
  suggestions.length > 0 && /* @__PURE__ */ jsxs(
7723
7934
  "div",
7724
7935
  {
@@ -9058,6 +9269,7 @@ function SeoView() {
9058
9269
  const [items, setItems] = useState([]);
9059
9270
  const [stats, setStats] = useState(null);
9060
9271
  const [loading, setLoading] = useState(true);
9272
+ const [building, setBuilding] = useState(false);
9061
9273
  const [error, setError] = useState(null);
9062
9274
  const [filter, setFilter] = useState("all");
9063
9275
  const [scoreFilter, setScoreFilter] = useState("all");
@@ -9074,9 +9286,22 @@ function SeoView() {
9074
9286
  const fetchAudit = useCallback(async (forceRefresh = false) => {
9075
9287
  setLoading(true);
9076
9288
  setError(null);
9289
+ setBuilding(false);
9077
9290
  try {
9078
- const url = forceRefresh ? "/api/seo-plugin/audit?nocache=1" : "/api/seo-plugin/audit";
9079
- const res = await fetch(url, { credentials: "include", cache: "no-store" });
9291
+ const base = "/api/seo-plugin/audit";
9292
+ let res = await fetch(forceRefresh ? `${base}?nocache=1` : base, {
9293
+ credentials: "include",
9294
+ cache: "no-store"
9295
+ });
9296
+ let attempts = 0;
9297
+ const MAX_POLLS = 90;
9298
+ while (res.status === 202 && attempts < MAX_POLLS) {
9299
+ setBuilding(true);
9300
+ await new Promise((r) => setTimeout(r, 3e3));
9301
+ res = await fetch(base, { credentials: "include", cache: "no-store" });
9302
+ attempts++;
9303
+ }
9304
+ if (res.status === 202) throw new Error(t.seoView.buildTimeout);
9080
9305
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
9081
9306
  const data = await res.json();
9082
9307
  setItems(data.results || []);
@@ -9084,6 +9309,7 @@ function SeoView() {
9084
9309
  } catch (e) {
9085
9310
  setError(e instanceof Error ? e.message : t.common.loadingError);
9086
9311
  }
9312
+ setBuilding(false);
9087
9313
  setLoading(false);
9088
9314
  }, [t]);
9089
9315
  useEffect(() => {
@@ -9525,7 +9751,7 @@ function SeoView() {
9525
9751
  fontSize: 14,
9526
9752
  fontFamily: "var(--font-body, system-ui)"
9527
9753
  },
9528
- children: t.seoView.loadingAudit
9754
+ children: building ? t.seoView.buildingAudit : t.seoView.loadingAudit
9529
9755
  }
9530
9756
  );
9531
9757
  }
@@ -15678,7 +15904,7 @@ function getSchemaTypes(t) {
15678
15904
  }
15679
15905
  };
15680
15906
  }
15681
- function buildJsonLd(type, values) {
15907
+ function buildJsonLd2(type, values) {
15682
15908
  switch (type) {
15683
15909
  case "LocalBusiness": {
15684
15910
  const result = {
@@ -15959,7 +16185,7 @@ function SchemaBuilderView() {
15959
16185
  [arrayName]: (prev[arrayName] || []).filter((_, i) => i !== index)
15960
16186
  }));
15961
16187
  }, []);
15962
- const jsonLd = useMemo(() => buildJsonLd(selectedType, values), [selectedType, values]);
16188
+ const jsonLd = useMemo(() => buildJsonLd2(selectedType, values), [selectedType, values]);
15963
16189
  const jsonString = useMemo(() => JSON.stringify(jsonLd, null, 2), [jsonLd]);
15964
16190
  const scriptTag = useMemo(
15965
16191
  () => `<script type="application/ld+json">
@@ -16736,6 +16962,573 @@ function GscPanel({ locale }) {
16736
16962
  ] })
16737
16963
  ] });
16738
16964
  }
16965
+ var C6 = {
16966
+ text: "var(--theme-text, #1a1a1a)",
16967
+ sub: "var(--theme-elevation-600, #6b7280)",
16968
+ card: "var(--theme-elevation-50, #f9fafb)",
16969
+ border: "var(--theme-elevation-200, #e5e7eb)",
16970
+ green: "#22c55e",
16971
+ red: "#ef4444",
16972
+ blue: "#3b82f6"
16973
+ };
16974
+ var S3 = {
16975
+ fr: {
16976
+ title: "Suivi de positions (rank tracking)",
16977
+ subtitle: "Historique quotidien des positions Google (via Search Console) et mouvements dans le temps.",
16978
+ needGsc: "Connectez Google Search Console ci-dessus pour activer le suivi de positions.",
16979
+ snapshot: "Relever maintenant",
16980
+ snapshotting: "Relev\xE9 en cours\u2026",
16981
+ noData: "Pas encore de donn\xE9es. Le relev\xE9 tourne automatiquement chaque jour ; cliquez \xAB Relever maintenant \xBB pour d\xE9marrer.",
16982
+ lastSnapshot: "Dernier relev\xE9",
16983
+ query: "Requ\xEAte",
16984
+ position: "Position",
16985
+ change: "\xC9volution",
16986
+ clicks: "Clics",
16987
+ impressions: "Impr.",
16988
+ stable: "stable",
16989
+ newQ: "nouveau",
16990
+ countLabel: "requ\xEAtes suivies"
16991
+ },
16992
+ en: {
16993
+ title: "Rank tracking",
16994
+ subtitle: "Daily Google position history (via Search Console) and movement over time.",
16995
+ needGsc: "Connect Google Search Console above to enable rank tracking.",
16996
+ snapshot: "Snapshot now",
16997
+ snapshotting: "Snapshotting\u2026",
16998
+ noData: 'No data yet. The snapshot runs automatically every day; click "Snapshot now" to start.',
16999
+ lastSnapshot: "Last snapshot",
17000
+ query: "Query",
17001
+ position: "Position",
17002
+ change: "Change",
17003
+ clicks: "Clicks",
17004
+ impressions: "Impr.",
17005
+ stable: "stable",
17006
+ newQ: "new",
17007
+ countLabel: "tracked queries"
17008
+ }
17009
+ };
17010
+ function RankTrackingPanel({ locale }) {
17011
+ const s = S3[locale] ?? S3.fr;
17012
+ const [movers, setMovers] = useState(null);
17013
+ const [lastSnapshot, setLastSnapshot] = useState(null);
17014
+ const [loading, setLoading] = useState(true);
17015
+ const [busy, setBusy] = useState(false);
17016
+ const [error, setError] = useState(null);
17017
+ const [notConnected, setNotConnected] = useState(false);
17018
+ const load = useCallback(async () => {
17019
+ setLoading(true);
17020
+ setError(null);
17021
+ try {
17022
+ const res = await fetch("/api/seo-plugin/rank-history", { credentials: "include", cache: "no-store" });
17023
+ if (res.status === 403 || res.status === 409) {
17024
+ setNotConnected(true);
17025
+ setMovers(null);
17026
+ return;
17027
+ }
17028
+ const json = await res.json();
17029
+ if (!res.ok) {
17030
+ setError(json.error || `Error ${res.status}`);
17031
+ return;
17032
+ }
17033
+ setMovers(json.movers || []);
17034
+ setLastSnapshot(json.lastSnapshot || null);
17035
+ } catch (e) {
17036
+ setError(e instanceof Error ? e.message : "Network error");
17037
+ } finally {
17038
+ setLoading(false);
17039
+ }
17040
+ }, []);
17041
+ useEffect(() => {
17042
+ void load();
17043
+ }, [load]);
17044
+ const snapshotNow = async () => {
17045
+ setBusy(true);
17046
+ setError(null);
17047
+ try {
17048
+ const res = await fetch("/api/seo-plugin/rank-snapshot", { method: "POST", credentials: "include" });
17049
+ const json = await res.json();
17050
+ if (res.status === 409) {
17051
+ setNotConnected(true);
17052
+ return;
17053
+ }
17054
+ if (!res.ok) {
17055
+ setError(json.error || json.reason || `Error ${res.status}`);
17056
+ return;
17057
+ }
17058
+ await load();
17059
+ } catch (e) {
17060
+ setError(e instanceof Error ? e.message : "Network error");
17061
+ } finally {
17062
+ setBusy(false);
17063
+ }
17064
+ };
17065
+ const card = {
17066
+ padding: 16,
17067
+ borderRadius: 12,
17068
+ border: `1px solid ${C6.border}`,
17069
+ backgroundColor: C6.card,
17070
+ marginBottom: 20
17071
+ };
17072
+ const btn = {
17073
+ padding: "8px 12px",
17074
+ borderRadius: 8,
17075
+ border: `1px solid ${C6.blue}`,
17076
+ backgroundColor: C6.blue,
17077
+ color: "#fff",
17078
+ fontSize: 12,
17079
+ fontWeight: 700,
17080
+ cursor: busy ? "wait" : "pointer",
17081
+ opacity: busy ? 0.6 : 1
17082
+ };
17083
+ const renderDelta = (m) => {
17084
+ if (m.previousPosition === null) {
17085
+ return /* @__PURE__ */ jsx("span", { style: { color: C6.sub, fontSize: 11 }, children: s.newQ });
17086
+ }
17087
+ if (Math.abs(m.delta) < 0.1) {
17088
+ return /* @__PURE__ */ jsxs("span", { style: { color: C6.sub, fontSize: 11 }, children: [
17089
+ "\u2014 ",
17090
+ s.stable
17091
+ ] });
17092
+ }
17093
+ const up = m.delta > 0;
17094
+ return /* @__PURE__ */ jsxs("span", { style: { color: up ? C6.green : C6.red, fontWeight: 700, fontSize: 12 }, children: [
17095
+ up ? "\u25B2" : "\u25BC",
17096
+ " ",
17097
+ Math.abs(m.delta).toFixed(1)
17098
+ ] });
17099
+ };
17100
+ return /* @__PURE__ */ jsxs("div", { style: card, children: [
17101
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17102
+ /* @__PURE__ */ jsxs("div", { children: [
17103
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C6.text }, children: s.title }),
17104
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: C6.sub, marginTop: 2 }, children: s.subtitle })
17105
+ ] }),
17106
+ !notConnected && /* @__PURE__ */ jsx("button", { type: "button", onClick: snapshotNow, disabled: busy, style: btn, children: busy ? s.snapshotting : s.snapshot })
17107
+ ] }),
17108
+ error && /* @__PURE__ */ jsx("div", { style: { color: C6.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
17109
+ notConnected && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, fontSize: 13, color: C6.sub }, children: s.needGsc }),
17110
+ !notConnected && /* @__PURE__ */ jsxs("div", { style: { marginTop: 12 }, children: [
17111
+ lastSnapshot && /* @__PURE__ */ jsxs("div", { style: { fontSize: 11, color: C6.sub, marginBottom: 8 }, children: [
17112
+ s.lastSnapshot,
17113
+ ": ",
17114
+ new Date(lastSnapshot).toLocaleString(locale),
17115
+ movers ? ` \xB7 ${movers.length} ${s.countLabel}` : ""
17116
+ ] }),
17117
+ loading && !movers && /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: C6.sub }, children: "\u2026" }),
17118
+ movers && movers.length === 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: C6.sub }, children: s.noData }),
17119
+ movers && movers.length > 0 && /* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 12 }, children: [
17120
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { textAlign: "left", color: C6.sub }, children: [
17121
+ /* @__PURE__ */ jsx("th", { style: { padding: "6px 8px" }, children: s.query }),
17122
+ /* @__PURE__ */ jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.position }),
17123
+ /* @__PURE__ */ jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.change }),
17124
+ /* @__PURE__ */ jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.clicks }),
17125
+ /* @__PURE__ */ jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.impressions })
17126
+ ] }) }),
17127
+ /* @__PURE__ */ jsx("tbody", { children: movers.slice(0, 100).map((m, i) => /* @__PURE__ */ jsxs("tr", { style: { borderTop: `1px solid ${C6.border}`, color: C6.text }, children: [
17128
+ /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: m.query }),
17129
+ /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", textAlign: "right", fontWeight: 700 }, children: m.position.toFixed(1) }),
17130
+ /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: renderDelta(m) }),
17131
+ /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.clicks }),
17132
+ /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.impressions })
17133
+ ] }, i)) })
17134
+ ] }) })
17135
+ ] })
17136
+ ] });
17137
+ }
17138
+ var C7 = {
17139
+ text: "var(--theme-text, #1a1a1a)",
17140
+ sub: "var(--theme-elevation-600, #6b7280)",
17141
+ card: "var(--theme-elevation-50, #f9fafb)",
17142
+ border: "var(--theme-elevation-200, #e5e7eb)",
17143
+ green: "#22c55e",
17144
+ red: "#ef4444",
17145
+ amber: "#f59e0b",
17146
+ blue: "#3b82f6"
17147
+ };
17148
+ var S4 = {
17149
+ fr: {
17150
+ title: "Monitoring & alertes",
17151
+ subtitle: "Digest p\xE9riodique : r\xE9gressions de score, nouveaux 404, chutes de position (webhook / email).",
17152
+ notConfigured: "Aucun canal configur\xE9. D\xE9finissez SEO_ALERT_WEBHOOK_URL et/ou SEO_ALERT_EMAIL c\xF4t\xE9 serveur, puis activez features.alerts.",
17153
+ webhook: "Webhook",
17154
+ email: "Email",
17155
+ configured: "configur\xE9",
17156
+ missing: "absent",
17157
+ preview: "Aper\xE7u",
17158
+ sendNow: "Envoyer maintenant",
17159
+ sending: "Envoi\u2026",
17160
+ loading: "Chargement\u2026",
17161
+ noIssues: "Aucun probl\xE8me d\xE9tect\xE9 sur la p\xE9riode. \u{1F389}",
17162
+ scoreReg: "R\xE9gressions de score",
17163
+ notFound: "Nouveaux 404",
17164
+ rankDrops: "Chutes de position",
17165
+ sent: "Digest envoy\xE9",
17166
+ nothingToSend: "Rien \xE0 envoyer (aucun probl\xE8me).",
17167
+ issues: "probl\xE8me(s)"
17168
+ },
17169
+ en: {
17170
+ title: "Monitoring & alerts",
17171
+ subtitle: "Periodic digest: score regressions, new 404s, ranking drops (webhook / email).",
17172
+ notConfigured: "No channel configured. Set SEO_ALERT_WEBHOOK_URL and/or SEO_ALERT_EMAIL on the server, then enable features.alerts.",
17173
+ webhook: "Webhook",
17174
+ email: "Email",
17175
+ configured: "configured",
17176
+ missing: "missing",
17177
+ preview: "Preview",
17178
+ sendNow: "Send now",
17179
+ sending: "Sending\u2026",
17180
+ loading: "Loading\u2026",
17181
+ noIssues: "No issues for the period. \u{1F389}",
17182
+ scoreReg: "Score regressions",
17183
+ notFound: "New 404s",
17184
+ rankDrops: "Ranking drops",
17185
+ sent: "Digest sent",
17186
+ nothingToSend: "Nothing to send (no issues).",
17187
+ issues: "issue(s)"
17188
+ }
17189
+ };
17190
+ function AlertsPanel({ locale }) {
17191
+ const s = S4[locale] ?? S4.fr;
17192
+ const [digest, setDigest] = useState(null);
17193
+ const [config, setConfig] = useState(null);
17194
+ const [loading, setLoading] = useState(true);
17195
+ const [busy, setBusy] = useState(false);
17196
+ const [error, setError] = useState(null);
17197
+ const [notice, setNotice] = useState(null);
17198
+ const load = useCallback(async () => {
17199
+ setLoading(true);
17200
+ setError(null);
17201
+ try {
17202
+ const res = await fetch("/api/seo-plugin/alerts-digest", { credentials: "include", cache: "no-store" });
17203
+ if (res.status === 404 || res.status === 403) {
17204
+ setConfig({ webhookConfigured: false, emailConfigured: false, scoreDrop: 0, positionDrop: 0, windowHours: 0 });
17205
+ setDigest(null);
17206
+ return;
17207
+ }
17208
+ const json = await res.json();
17209
+ if (!res.ok) {
17210
+ setError(json.error || `Error ${res.status}`);
17211
+ return;
17212
+ }
17213
+ setDigest(json.digest);
17214
+ setConfig(json.config);
17215
+ } catch (e) {
17216
+ setError(e instanceof Error ? e.message : "Network error");
17217
+ } finally {
17218
+ setLoading(false);
17219
+ }
17220
+ }, []);
17221
+ useEffect(() => {
17222
+ void load();
17223
+ }, [load]);
17224
+ const sendNow = async () => {
17225
+ setBusy(true);
17226
+ setError(null);
17227
+ setNotice(null);
17228
+ try {
17229
+ const res = await fetch("/api/seo-plugin/alerts-run", { method: "POST", credentials: "include" });
17230
+ const json = await res.json();
17231
+ if (!res.ok) {
17232
+ setError(json.error || `Error ${res.status}`);
17233
+ return;
17234
+ }
17235
+ setNotice(json.delivery?.sent ? s.sent : s.nothingToSend);
17236
+ if (json.digest) setDigest(json.digest);
17237
+ } catch (e) {
17238
+ setError(e instanceof Error ? e.message : "Network error");
17239
+ } finally {
17240
+ setBusy(false);
17241
+ }
17242
+ };
17243
+ const card = {
17244
+ padding: 16,
17245
+ borderRadius: 12,
17246
+ border: `1px solid ${C7.border}`,
17247
+ backgroundColor: C7.card,
17248
+ marginBottom: 20
17249
+ };
17250
+ const btn = {
17251
+ padding: "8px 12px",
17252
+ borderRadius: 8,
17253
+ border: `1px solid ${C7.blue}`,
17254
+ backgroundColor: C7.blue,
17255
+ color: "#fff",
17256
+ fontSize: 12,
17257
+ fontWeight: 700,
17258
+ cursor: busy ? "wait" : "pointer",
17259
+ opacity: busy ? 0.6 : 1
17260
+ };
17261
+ const chip = (ok, label) => ({
17262
+ fontSize: 11,
17263
+ fontWeight: 700,
17264
+ padding: "3px 8px",
17265
+ borderRadius: 999,
17266
+ color: "#fff",
17267
+ backgroundColor: ok ? C7.green : C7.sub,
17268
+ marginRight: 6
17269
+ });
17270
+ const hasChannel = config && (config.webhookConfigured || config.emailConfigured);
17271
+ const list = (title, rows) => rows.length ? /* @__PURE__ */ jsxs("div", { style: { marginTop: 10 }, children: [
17272
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 12, fontWeight: 700, color: C7.text, marginBottom: 4 }, children: [
17273
+ title,
17274
+ " ",
17275
+ /* @__PURE__ */ jsxs("span", { style: { color: C7.amber }, children: [
17276
+ "(",
17277
+ rows.length,
17278
+ ")"
17279
+ ] })
17280
+ ] }),
17281
+ /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 12, color: C7.sub, lineHeight: 1.6 }, children: rows.slice(0, 8).map((r, i) => /* @__PURE__ */ jsx("li", { children: r }, i)) })
17282
+ ] }) : null;
17283
+ return /* @__PURE__ */ jsxs("div", { style: card, children: [
17284
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17285
+ /* @__PURE__ */ jsxs("div", { children: [
17286
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C7.text }, children: s.title }),
17287
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: C7.sub, marginTop: 2 }, children: s.subtitle })
17288
+ ] }),
17289
+ hasChannel && /* @__PURE__ */ jsx("button", { type: "button", onClick: sendNow, disabled: busy, style: btn, children: busy ? s.sending : s.sendNow })
17290
+ ] }),
17291
+ error && /* @__PURE__ */ jsx("div", { style: { color: C7.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
17292
+ notice && /* @__PURE__ */ jsx("div", { style: { color: C7.green, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: notice }),
17293
+ config && /* @__PURE__ */ jsxs("div", { style: { marginTop: 12 }, children: [
17294
+ /* @__PURE__ */ jsxs("span", { style: chip(config.webhookConfigured, s.webhook), children: [
17295
+ s.webhook,
17296
+ ": ",
17297
+ config.webhookConfigured ? s.configured : s.missing
17298
+ ] }),
17299
+ /* @__PURE__ */ jsxs("span", { style: chip(config.emailConfigured, s.email), children: [
17300
+ s.email,
17301
+ ": ",
17302
+ config.emailConfigured ? s.configured : s.missing
17303
+ ] })
17304
+ ] }),
17305
+ !loading && !hasChannel && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.notConfigured }),
17306
+ loading && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.loading }),
17307
+ digest && /* @__PURE__ */ jsxs("div", { style: { marginTop: 8 }, children: [
17308
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 12, color: C7.sub, marginTop: 6 }, children: [
17309
+ digest.totalIssues,
17310
+ " ",
17311
+ s.issues
17312
+ ] }),
17313
+ digest.totalIssues === 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 8, fontSize: 13, color: C7.sub }, children: s.noIssues }),
17314
+ list(
17315
+ s.scoreReg,
17316
+ digest.scoreRegressions.map((r) => `${r.collection}/${r.documentId} \u2014 ${r.from} \u2192 ${r.to} (\u2212${r.drop})`)
17317
+ ),
17318
+ list(s.notFound, digest.newNotFound.map((n) => `${n.url} \u2014 ${n.count}\xD7`)),
17319
+ list(s.rankDrops, digest.rankDrops.map((d) => `\u201C${d.query}\u201D \u2014 #${d.from} \u2192 #${d.to} (\u25BC${d.drop})`))
17320
+ ] })
17321
+ ] });
17322
+ }
17323
+ var C8 = {
17324
+ text: "var(--theme-text, #1a1a1a)",
17325
+ sub: "var(--theme-elevation-600, #6b7280)",
17326
+ card: "var(--theme-elevation-50, #f9fafb)",
17327
+ bg: "var(--theme-elevation-0, #fff)",
17328
+ border: "var(--theme-elevation-200, #e5e7eb)",
17329
+ green: "#22c55e",
17330
+ red: "#ef4444",
17331
+ violet: "#7c3aed"
17332
+ };
17333
+ var S5 = {
17334
+ fr: {
17335
+ title: "Alt-text IA des images",
17336
+ subtitle: "G\xE9n\xE8re l'attribut alt des images qui n'en ont pas (Claude vision), pour l'accessibilit\xE9 et le SEO.",
17337
+ none: "Toutes les images ont un alt. \u{1F389}",
17338
+ forbidden: "R\xE9serv\xE9 aux administrateurs.",
17339
+ disabled: "Fonction IA d\xE9sactiv\xE9e (features.aiFeatures).",
17340
+ missing: "image(s) sans alt",
17341
+ generate: "G\xE9n\xE9rer",
17342
+ generating: "\u2026",
17343
+ apply: "Appliquer",
17344
+ applied: "Appliqu\xE9 \u2713",
17345
+ noKey: "Cl\xE9 API Claude requise (ANTHROPIC_API_KEY).",
17346
+ loading: "Chargement\u2026",
17347
+ refresh: "Rafra\xEEchir"
17348
+ },
17349
+ en: {
17350
+ title: "AI image alt-text",
17351
+ subtitle: "Generate alt text for images that lack one (Claude vision), for accessibility and SEO.",
17352
+ none: "All images have alt text. \u{1F389}",
17353
+ forbidden: "Admins only.",
17354
+ disabled: "AI feature disabled (features.aiFeatures).",
17355
+ missing: "image(s) without alt",
17356
+ generate: "Generate",
17357
+ generating: "\u2026",
17358
+ apply: "Apply",
17359
+ applied: "Applied \u2713",
17360
+ noKey: "Claude API key required (ANTHROPIC_API_KEY).",
17361
+ loading: "Loading\u2026",
17362
+ refresh: "Refresh"
17363
+ }
17364
+ };
17365
+ function AltTextPanel({ locale }) {
17366
+ const s = S5[locale] ?? S5.fr;
17367
+ const [items, setItems] = useState(null);
17368
+ const [collection, setCollection] = useState("media");
17369
+ const [missingCount, setMissingCount] = useState(0);
17370
+ const [loading, setLoading] = useState(true);
17371
+ const [state, setState] = useState({});
17372
+ const [status, setStatus] = useState("ok");
17373
+ const load = useCallback(async () => {
17374
+ setLoading(true);
17375
+ try {
17376
+ const res = await fetch("/api/seo-plugin/alt-text-audit", { credentials: "include", cache: "no-store" });
17377
+ if (res.status === 404) {
17378
+ setStatus("disabled");
17379
+ return;
17380
+ }
17381
+ if (res.status === 403) {
17382
+ setStatus("forbidden");
17383
+ return;
17384
+ }
17385
+ const json = await res.json();
17386
+ setStatus("ok");
17387
+ setItems(json.items || []);
17388
+ setMissingCount(json.missingCount || 0);
17389
+ setCollection(json.collection || "media");
17390
+ } catch {
17391
+ setItems([]);
17392
+ } finally {
17393
+ setLoading(false);
17394
+ }
17395
+ }, []);
17396
+ useEffect(() => {
17397
+ void load();
17398
+ }, [load]);
17399
+ const setRow = (id, patch) => setState((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }));
17400
+ const generate = async (item) => {
17401
+ setRow(item.id, { busy: true, error: void 0 });
17402
+ try {
17403
+ const res = await fetch("/api/seo-plugin/ai-alt-text", {
17404
+ method: "POST",
17405
+ credentials: "include",
17406
+ headers: { "Content-Type": "application/json" },
17407
+ body: JSON.stringify({ collection, id: item.id, apply: false })
17408
+ });
17409
+ const json = await res.json();
17410
+ if (!res.ok) {
17411
+ setRow(item.id, { busy: false, error: json.code === "no_api_key" ? s.noKey : json.error || `Error ${res.status}` });
17412
+ return;
17413
+ }
17414
+ setRow(item.id, { busy: false, alt: json.alt });
17415
+ } catch (e) {
17416
+ setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
17417
+ }
17418
+ };
17419
+ const apply = async (item) => {
17420
+ const alt = state[item.id]?.alt;
17421
+ if (!alt) return;
17422
+ setRow(item.id, { busy: true, error: void 0 });
17423
+ try {
17424
+ const res = await fetch("/api/seo-plugin/ai-alt-text", {
17425
+ method: "POST",
17426
+ credentials: "include",
17427
+ headers: { "Content-Type": "application/json" },
17428
+ body: JSON.stringify({ collection, id: item.id, apply: true, altText: alt })
17429
+ });
17430
+ const json = await res.json();
17431
+ if (!res.ok) {
17432
+ setRow(item.id, { busy: false, error: json.error || `Error ${res.status}` });
17433
+ return;
17434
+ }
17435
+ setRow(item.id, { busy: false, applied: true });
17436
+ } catch (e) {
17437
+ setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
17438
+ }
17439
+ };
17440
+ const card = {
17441
+ padding: 16,
17442
+ borderRadius: 12,
17443
+ border: `1px solid ${C8.border}`,
17444
+ backgroundColor: C8.card,
17445
+ marginBottom: 20
17446
+ };
17447
+ const btn = (bg) => ({
17448
+ padding: "6px 10px",
17449
+ borderRadius: 6,
17450
+ border: `1px solid ${bg}`,
17451
+ backgroundColor: bg,
17452
+ color: "#fff",
17453
+ fontSize: 11,
17454
+ fontWeight: 700,
17455
+ cursor: "pointer"
17456
+ });
17457
+ return /* @__PURE__ */ jsxs("div", { style: card, children: [
17458
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
17459
+ /* @__PURE__ */ jsxs("div", { children: [
17460
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C8.text }, children: s.title }),
17461
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 2 }, children: s.subtitle })
17462
+ ] }),
17463
+ status === "ok" && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void load(), style: btn(C8.sub), children: s.refresh })
17464
+ ] }),
17465
+ status === "forbidden" && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.forbidden }),
17466
+ status === "disabled" && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.disabled }),
17467
+ status === "ok" && /* @__PURE__ */ jsxs("div", { style: { marginTop: 12 }, children: [
17468
+ loading && /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.loading }),
17469
+ !loading && items && items.length === 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.none }),
17470
+ !loading && items && items.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
17471
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 12, color: C8.sub, marginBottom: 10 }, children: [
17472
+ missingCount,
17473
+ " ",
17474
+ s.missing
17475
+ ] }),
17476
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: items.map((item) => {
17477
+ const rs = state[item.id] || {};
17478
+ return /* @__PURE__ */ jsxs(
17479
+ "div",
17480
+ {
17481
+ style: {
17482
+ display: "flex",
17483
+ gap: 12,
17484
+ alignItems: "center",
17485
+ padding: 8,
17486
+ borderRadius: 8,
17487
+ border: `1px solid ${C8.border}`,
17488
+ backgroundColor: C8.bg
17489
+ },
17490
+ children: [
17491
+ /* @__PURE__ */ jsx(
17492
+ "img",
17493
+ {
17494
+ src: item.url,
17495
+ alt: "",
17496
+ style: { width: 48, height: 48, objectFit: "cover", borderRadius: 6, flexShrink: 0, border: `1px solid ${C8.border}` }
17497
+ }
17498
+ ),
17499
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
17500
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: C8.sub, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: item.filename }),
17501
+ rs.alt !== void 0 ? /* @__PURE__ */ jsx(
17502
+ "input",
17503
+ {
17504
+ value: rs.alt,
17505
+ onChange: (e) => setRow(item.id, { alt: e.target.value }),
17506
+ disabled: rs.applied,
17507
+ maxLength: 125,
17508
+ style: {
17509
+ width: "100%",
17510
+ marginTop: 4,
17511
+ padding: "4px 8px",
17512
+ fontSize: 12,
17513
+ borderRadius: 6,
17514
+ border: `1px solid ${C8.border}`,
17515
+ backgroundColor: C8.bg,
17516
+ color: C8.text
17517
+ }
17518
+ }
17519
+ ) : /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 4, fontStyle: "italic" }, children: "\u2014" }),
17520
+ rs.error && /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: C8.red, marginTop: 2 }, children: rs.error })
17521
+ ] }),
17522
+ /* @__PURE__ */ jsx("div", { style: { flexShrink: 0 }, children: rs.applied ? /* @__PURE__ */ jsx("span", { style: { fontSize: 11, fontWeight: 700, color: C8.green }, children: s.applied }) : rs.alt !== void 0 ? /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void apply(item), disabled: rs.busy, style: btn(C8.green), children: rs.busy ? s.generating : s.apply }) : /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void generate(item), disabled: rs.busy, style: btn(C8.violet), children: rs.busy ? s.generating : s.generate }) })
17523
+ ]
17524
+ },
17525
+ item.id
17526
+ );
17527
+ }) })
17528
+ ] })
17529
+ ] })
17530
+ ] });
17531
+ }
16739
17532
  var V8 = {
16740
17533
  text: "var(--theme-text, #1a1a1a)",
16741
17534
  textSecondary: "var(--theme-elevation-600, #6b7280)",
@@ -17150,6 +17943,9 @@ function PerformanceView() {
17150
17943
  ),
17151
17944
  /* @__PURE__ */ jsx(CoreWebVitalsPanel, { locale }),
17152
17945
  /* @__PURE__ */ jsx(GscPanel, { locale }),
17946
+ /* @__PURE__ */ jsx(RankTrackingPanel, { locale }),
17947
+ /* @__PURE__ */ jsx(AlertsPanel, { locale }),
17948
+ /* @__PURE__ */ jsx(AltTextPanel, { locale }),
17153
17949
  showImport && /* @__PURE__ */ jsxs(
17154
17950
  "div",
17155
17951
  {
@@ -18809,7 +19605,7 @@ var controlBtnStyle = {
18809
19605
  cursor: "pointer",
18810
19606
  lineHeight: 1.4
18811
19607
  };
18812
- var C6 = {
19608
+ var C9 = {
18813
19609
  cyan: "#00E5FF",
18814
19610
  black: "#000",
18815
19611
  green: "#22c55e",
@@ -18824,10 +19620,10 @@ var C6 = {
18824
19620
  var TITLE_MIN = 30;
18825
19621
  var TITLE_MAX = 60;
18826
19622
  function getCharColor(len) {
18827
- if (len === 0) return C6.textSecondary;
18828
- if (len >= TITLE_MIN && len <= TITLE_MAX) return C6.green;
18829
- if (len > 0 && len < TITLE_MIN) return C6.orange;
18830
- return C6.red;
19623
+ if (len === 0) return C9.textSecondary;
19624
+ if (len >= TITLE_MIN && len <= TITLE_MAX) return C9.green;
19625
+ if (len > 0 && len < TITLE_MIN) return C9.orange;
19626
+ return C9.red;
18831
19627
  }
18832
19628
  function getProgressPercent(len) {
18833
19629
  if (len === 0) return 0;
@@ -18835,9 +19631,9 @@ function getProgressPercent(len) {
18835
19631
  }
18836
19632
  function getProgressColor(len) {
18837
19633
  if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
18838
- if (len >= TITLE_MIN && len <= TITLE_MAX) return C6.green;
18839
- if (len < TITLE_MIN) return C6.orange;
18840
- return C6.red;
19634
+ if (len >= TITLE_MIN && len <= TITLE_MAX) return C9.green;
19635
+ if (len < TITLE_MIN) return C9.orange;
19636
+ return C9.red;
18841
19637
  }
18842
19638
  function MetaTitleField({
18843
19639
  path,
@@ -18908,7 +19704,7 @@ function MetaTitleField({
18908
19704
  style: {
18909
19705
  fontSize: 13,
18910
19706
  fontWeight: 700,
18911
- color: C6.textPrimary
19707
+ color: C9.textPrimary
18912
19708
  },
18913
19709
  children: t.metaTitle.label
18914
19710
  }
@@ -18948,9 +19744,9 @@ function MetaTitleField({
18948
19744
  fontSize: 14,
18949
19745
  fontFamily: "inherit",
18950
19746
  borderRadius: 8,
18951
- border: `2px solid ${C6.border}`,
18952
- backgroundColor: C6.surfaceBg,
18953
- color: C6.textPrimary,
19747
+ border: `2px solid ${C9.border}`,
19748
+ backgroundColor: C9.surfaceBg,
19749
+ color: C9.textPrimary,
18954
19750
  outline: "none",
18955
19751
  boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
18956
19752
  }
@@ -18968,9 +19764,9 @@ function MetaTitleField({
18968
19764
  gap: 5,
18969
19765
  padding: "8px 14px",
18970
19766
  borderRadius: 8,
18971
- border: `2px solid ${C6.border}`,
18972
- backgroundColor: loading ? C6.surface50 : C6.cyan,
18973
- color: loading ? C6.textSecondary : C6.black,
19767
+ border: `2px solid ${C9.border}`,
19768
+ backgroundColor: loading ? C9.surface50 : C9.cyan,
19769
+ color: loading ? C9.textSecondary : C9.black,
18974
19770
  fontWeight: 800,
18975
19771
  fontSize: 11,
18976
19772
  textTransform: "uppercase",
@@ -19017,7 +19813,7 @@ function MetaTitleField({
19017
19813
  justifyContent: "space-between",
19018
19814
  marginTop: 4,
19019
19815
  fontSize: 10,
19020
- color: C6.textSecondary
19816
+ color: C9.textSecondary
19021
19817
  },
19022
19818
  children: [
19023
19819
  /* @__PURE__ */ jsxs("span", { children: [
@@ -19051,9 +19847,9 @@ function MetaTitleField({
19051
19847
  borderRadius: 6,
19052
19848
  fontSize: 11,
19053
19849
  fontWeight: 600,
19054
- color: C6.red,
19850
+ color: C9.red,
19055
19851
  backgroundColor: "rgba(239,68,68,0.08)",
19056
- border: `1px solid ${C6.red}`
19852
+ border: `1px solid ${C9.red}`
19057
19853
  },
19058
19854
  children: error
19059
19855
  }
@@ -19062,7 +19858,7 @@ function MetaTitleField({
19062
19858
  }
19063
19859
  );
19064
19860
  }
19065
- var C7 = {
19861
+ var C10 = {
19066
19862
  cyan: "#00E5FF",
19067
19863
  black: "#000",
19068
19864
  green: "#22c55e",
@@ -19077,10 +19873,10 @@ var C7 = {
19077
19873
  var DESC_MIN = 120;
19078
19874
  var DESC_MAX = 160;
19079
19875
  function getCharColor2(len) {
19080
- if (len === 0) return C7.textSecondary;
19081
- if (len >= DESC_MIN && len <= DESC_MAX) return C7.green;
19082
- if (len > 0 && len < DESC_MIN) return C7.orange;
19083
- return C7.red;
19876
+ if (len === 0) return C10.textSecondary;
19877
+ if (len >= DESC_MIN && len <= DESC_MAX) return C10.green;
19878
+ if (len > 0 && len < DESC_MIN) return C10.orange;
19879
+ return C10.red;
19084
19880
  }
19085
19881
  function getProgressPercent2(len) {
19086
19882
  if (len === 0) return 0;
@@ -19088,9 +19884,9 @@ function getProgressPercent2(len) {
19088
19884
  }
19089
19885
  function getProgressColor2(len) {
19090
19886
  if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
19091
- if (len >= DESC_MIN && len <= DESC_MAX) return C7.green;
19092
- if (len < DESC_MIN) return C7.orange;
19093
- return C7.red;
19887
+ if (len >= DESC_MIN && len <= DESC_MAX) return C10.green;
19888
+ if (len < DESC_MIN) return C10.orange;
19889
+ return C10.red;
19094
19890
  }
19095
19891
  function MetaDescriptionField({
19096
19892
  path,
@@ -19161,7 +19957,7 @@ function MetaDescriptionField({
19161
19957
  style: {
19162
19958
  fontSize: 13,
19163
19959
  fontWeight: 700,
19164
- color: C7.textPrimary
19960
+ color: C10.textPrimary
19165
19961
  },
19166
19962
  children: t.metaDescription.label
19167
19963
  }
@@ -19201,9 +19997,9 @@ function MetaDescriptionField({
19201
19997
  fontSize: 14,
19202
19998
  fontFamily: "inherit",
19203
19999
  borderRadius: 8,
19204
- border: `2px solid ${C7.border}`,
19205
- backgroundColor: C7.surfaceBg,
19206
- color: C7.textPrimary,
20000
+ border: `2px solid ${C10.border}`,
20001
+ backgroundColor: C10.surfaceBg,
20002
+ color: C10.textPrimary,
19207
20003
  outline: "none",
19208
20004
  resize: "vertical",
19209
20005
  lineHeight: 1.5,
@@ -19223,9 +20019,9 @@ function MetaDescriptionField({
19223
20019
  gap: 5,
19224
20020
  padding: "8px 14px",
19225
20021
  borderRadius: 8,
19226
- border: `2px solid ${C7.border}`,
19227
- backgroundColor: loading ? C7.surface50 : C7.cyan,
19228
- color: loading ? C7.textSecondary : C7.black,
20022
+ border: `2px solid ${C10.border}`,
20023
+ backgroundColor: loading ? C10.surface50 : C10.cyan,
20024
+ color: loading ? C10.textSecondary : C10.black,
19229
20025
  fontWeight: 800,
19230
20026
  fontSize: 11,
19231
20027
  textTransform: "uppercase",
@@ -19273,7 +20069,7 @@ function MetaDescriptionField({
19273
20069
  justifyContent: "space-between",
19274
20070
  marginTop: 4,
19275
20071
  fontSize: 10,
19276
- color: C7.textSecondary
20072
+ color: C10.textSecondary
19277
20073
  },
19278
20074
  children: [
19279
20075
  /* @__PURE__ */ jsxs("span", { children: [
@@ -19307,9 +20103,9 @@ function MetaDescriptionField({
19307
20103
  borderRadius: 6,
19308
20104
  fontSize: 11,
19309
20105
  fontWeight: 600,
19310
- color: C7.red,
20106
+ color: C10.red,
19311
20107
  backgroundColor: "rgba(239,68,68,0.08)",
19312
- border: `1px solid ${C7.red}`
20108
+ border: `1px solid ${C10.red}`
19313
20109
  },
19314
20110
  children: error
19315
20111
  }
@@ -19318,7 +20114,7 @@ function MetaDescriptionField({
19318
20114
  }
19319
20115
  );
19320
20116
  }
19321
- var C8 = {
20117
+ var C11 = {
19322
20118
  cyan: "#00E5FF",
19323
20119
  black: "#000",
19324
20120
  white: "#fff",
@@ -19395,8 +20191,8 @@ function MetaImageField({
19395
20191
  gap: 10,
19396
20192
  padding: "10px 14px",
19397
20193
  borderRadius: 8,
19398
- border: `2px solid ${C8.border}`,
19399
- backgroundColor: C8.surfaceBg,
20194
+ border: `2px solid ${C11.border}`,
20195
+ backgroundColor: C11.surfaceBg,
19400
20196
  boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
19401
20197
  },
19402
20198
  children: [
@@ -19415,7 +20211,7 @@ function MetaImageField({
19415
20211
  fontWeight: 900,
19416
20212
  backgroundColor: hasImage ? "rgba(34,197,94,0.15)" : "rgba(255,138,0,0.15)",
19417
20213
  color: hasImage ? "#16a34a" : "#d97706",
19418
- border: `1px solid ${hasImage ? C8.green : C8.orange}`
20214
+ border: `1px solid ${hasImage ? C11.green : C11.orange}`
19419
20215
  },
19420
20216
  children: hasImage ? "\u2713" : "!"
19421
20217
  }
@@ -19427,7 +20223,7 @@ function MetaImageField({
19427
20223
  style: {
19428
20224
  fontSize: 12,
19429
20225
  fontWeight: 700,
19430
- color: C8.textPrimary
20226
+ color: C11.textPrimary
19431
20227
  },
19432
20228
  children: t.metaImage.label
19433
20229
  }
@@ -19437,7 +20233,7 @@ function MetaImageField({
19437
20233
  {
19438
20234
  style: {
19439
20235
  fontSize: 10,
19440
- color: C8.textSecondary,
20236
+ color: C11.textSecondary,
19441
20237
  lineHeight: 1.4
19442
20238
  },
19443
20239
  children: hasImage ? t.metaImage.imageSet : t.metaImage.noImage
@@ -19457,9 +20253,9 @@ function MetaImageField({
19457
20253
  gap: 5,
19458
20254
  padding: "8px 14px",
19459
20255
  borderRadius: 8,
19460
- border: `2px solid ${C8.border}`,
19461
- backgroundColor: loading ? C8.surface50 : success ? C8.green : C8.cyan,
19462
- color: loading ? C8.textSecondary : success ? C8.white : C8.black,
20256
+ border: `2px solid ${C11.border}`,
20257
+ backgroundColor: loading ? C11.surface50 : success ? C11.green : C11.cyan,
20258
+ color: loading ? C11.textSecondary : success ? C11.white : C11.black,
19463
20259
  fontWeight: 800,
19464
20260
  fontSize: 11,
19465
20261
  textTransform: "uppercase",
@@ -19486,9 +20282,9 @@ function MetaImageField({
19486
20282
  borderRadius: 6,
19487
20283
  fontSize: 11,
19488
20284
  fontWeight: 600,
19489
- color: C8.red,
20285
+ color: C11.red,
19490
20286
  backgroundColor: "rgba(239,68,68,0.08)",
19491
- border: `1px solid ${C8.red}`
20287
+ border: `1px solid ${C11.red}`
19492
20288
  },
19493
20289
  children: error
19494
20290
  }
@@ -19497,7 +20293,7 @@ function MetaImageField({
19497
20293
  }
19498
20294
  );
19499
20295
  }
19500
- var C9 = {
20296
+ var C12 = {
19501
20297
  black: "#000",
19502
20298
  white: "#fff",
19503
20299
  green: "#22c55e",
@@ -19511,15 +20307,15 @@ var C9 = {
19511
20307
  function getCompletenessColor(count) {
19512
20308
  switch (count) {
19513
20309
  case 0:
19514
- return C9.red;
20310
+ return C12.red;
19515
20311
  case 1:
19516
- return C9.orange;
20312
+ return C12.orange;
19517
20313
  case 2:
19518
- return C9.yellow;
20314
+ return C12.yellow;
19519
20315
  case 3:
19520
- return C9.green;
20316
+ return C12.green;
19521
20317
  default:
19522
- return C9.textSecondary;
20318
+ return C12.textSecondary;
19523
20319
  }
19524
20320
  }
19525
20321
  function getCompletenessLabel(count, ov) {
@@ -19577,8 +20373,8 @@ function OverviewField({
19577
20373
  fontFamily: "var(--font-body, Inter, system-ui, sans-serif)",
19578
20374
  padding: "12px 14px",
19579
20375
  borderRadius: 10,
19580
- border: `2px solid ${C9.border}`,
19581
- backgroundColor: C9.surfaceBg,
20376
+ border: `2px solid ${C12.border}`,
20377
+ backgroundColor: C12.surfaceBg,
19582
20378
  boxShadow: "3px 3px 0 0 var(--theme-border-color, rgba(0,0,0,1))",
19583
20379
  marginBottom: 12
19584
20380
  },
@@ -19601,7 +20397,7 @@ function OverviewField({
19601
20397
  fontWeight: 800,
19602
20398
  textTransform: "uppercase",
19603
20399
  letterSpacing: "0.04em",
19604
- color: C9.textPrimary
20400
+ color: C12.textPrimary
19605
20401
  },
19606
20402
  children: t.overview.metaCompleteness
19607
20403
  }
@@ -19616,8 +20412,8 @@ function OverviewField({
19616
20412
  fontSize: 11,
19617
20413
  fontWeight: 800,
19618
20414
  backgroundColor: completenessColor,
19619
- color: completenessColor === C9.yellow ? C9.black : C9.white,
19620
- border: `2px solid ${C9.border}`,
20415
+ color: completenessColor === C12.yellow ? C12.black : C12.white,
20416
+ border: `2px solid ${C12.border}`,
19621
20417
  textTransform: "uppercase",
19622
20418
  letterSpacing: "0.03em"
19623
20419
  },
@@ -19715,7 +20511,7 @@ function OverviewField({
19715
20511
  style: {
19716
20512
  fontSize: 12,
19717
20513
  fontWeight: 600,
19718
- color: item.filled ? C9.textPrimary : C9.textSecondary
20514
+ color: item.filled ? C12.textPrimary : C12.textSecondary
19719
20515
  },
19720
20516
  children: item.label
19721
20517
  }
@@ -19727,7 +20523,7 @@ function OverviewField({
19727
20523
  marginLeft: "auto",
19728
20524
  fontSize: 10,
19729
20525
  fontWeight: 700,
19730
- color: item.filled ? C9.green : C9.red,
20526
+ color: item.filled ? C12.green : C12.red,
19731
20527
  textTransform: "uppercase",
19732
20528
  letterSpacing: "0.03em"
19733
20529
  },
@@ -19744,7 +20540,7 @@ function OverviewField({
19744
20540
  }
19745
20541
  );
19746
20542
  }
19747
- var C10 = {
20543
+ var C13 = {
19748
20544
  cyan: "#00E5FF",
19749
20545
  black: "#000",
19750
20546
  white: "#fff",
@@ -19763,10 +20559,10 @@ var G = {
19763
20559
  descGrey: "#4d5156",
19764
20560
  faviconBg: "#e8eaed"};
19765
20561
  function charCountColor2(len, min, max) {
19766
- if (len >= min && len <= max) return C10.green;
19767
- if (len > 0 && len < min) return C10.orange;
19768
- if (len > max) return C10.red;
19769
- return C10.textSecondary;
20562
+ if (len >= min && len <= max) return C13.green;
20563
+ if (len > 0 && len < min) return C13.orange;
20564
+ if (len > max) return C13.red;
20565
+ return C13.textSecondary;
19770
20566
  }
19771
20567
  function truncateText(text, maxChars) {
19772
20568
  if (text.length <= maxChars) return text;
@@ -19821,8 +20617,8 @@ function SerpPreview({
19821
20617
  padding: "10px 12px",
19822
20618
  cursor: "pointer",
19823
20619
  borderRadius: 8,
19824
- border: `2px solid ${C10.border}`,
19825
- backgroundColor: C10.surface50,
20620
+ border: `2px solid ${C13.border}`,
20621
+ backgroundColor: C13.surface50,
19826
20622
  userSelect: "none"
19827
20623
  },
19828
20624
  children: [
@@ -19837,7 +20633,7 @@ function SerpPreview({
19837
20633
  fontWeight: 800,
19838
20634
  textTransform: "uppercase",
19839
20635
  letterSpacing: "0.04em",
19840
- color: C10.textPrimary
20636
+ color: C13.textPrimary
19841
20637
  },
19842
20638
  children: [
19843
20639
  /* @__PURE__ */ jsxs(
@@ -19869,7 +20665,7 @@ function SerpPreview({
19869
20665
  transition: "transform 0.2s",
19870
20666
  display: "inline-block",
19871
20667
  transform: open ? "rotate(90deg)" : "none",
19872
- color: C10.textSecondary
20668
+ color: C13.textSecondary
19873
20669
  },
19874
20670
  children: "\u25B6"
19875
20671
  }
@@ -19902,10 +20698,10 @@ function SerpPreview({
19902
20698
  "div",
19903
20699
  {
19904
20700
  style: {
19905
- backgroundColor: C10.white,
19906
- border: `2px solid ${C10.border}`,
20701
+ backgroundColor: C13.white,
20702
+ border: `2px solid ${C13.border}`,
19907
20703
  borderRadius: 12,
19908
- boxShadow: `3px 3px 0 0 ${C10.border}`,
20704
+ boxShadow: `3px 3px 0 0 ${C13.border}`,
19909
20705
  padding: isDesktop ? 20 : 14,
19910
20706
  maxWidth: isDesktop ? 650 : 380,
19911
20707
  overflow: "hidden"
@@ -19968,7 +20764,7 @@ function SerpPreview({
19968
20764
  style: {
19969
20765
  fontSize: 14,
19970
20766
  fontWeight: 400,
19971
- color: C10.black,
20767
+ color: C13.black,
19972
20768
  lineHeight: 1.3,
19973
20769
  whiteSpace: "nowrap",
19974
20770
  overflow: "hidden",
@@ -20032,7 +20828,7 @@ function SerpPreview({
20032
20828
  "span",
20033
20829
  {
20034
20830
  style: {
20035
- color: C10.textSecondary,
20831
+ color: C13.textSecondary,
20036
20832
  fontStyle: "italic",
20037
20833
  fontSize: titleFontSize - 2
20038
20834
  },
@@ -20061,7 +20857,7 @@ function SerpPreview({
20061
20857
  "span",
20062
20858
  {
20063
20859
  style: {
20064
- color: C10.textSecondary,
20860
+ color: C13.textSecondary,
20065
20861
  fontStyle: "italic",
20066
20862
  fontSize: descFontSize - 1
20067
20863
  },
@@ -20094,7 +20890,7 @@ function SerpPreview({
20094
20890
  fontSize: 11
20095
20891
  },
20096
20892
  children: [
20097
- /* @__PURE__ */ jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewTitle }),
20893
+ /* @__PURE__ */ jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewTitle }),
20098
20894
  /* @__PURE__ */ jsxs(
20099
20895
  "span",
20100
20896
  {
@@ -20123,7 +20919,7 @@ function SerpPreview({
20123
20919
  fontSize: 11
20124
20920
  },
20125
20921
  children: [
20126
- /* @__PURE__ */ jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewDescription }),
20922
+ /* @__PURE__ */ jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewDescription }),
20127
20923
  /* @__PURE__ */ jsxs(
20128
20924
  "span",
20129
20925
  {
@@ -20152,14 +20948,14 @@ function SerpPreview({
20152
20948
  fontSize: 11
20153
20949
  },
20154
20950
  children: [
20155
- /* @__PURE__ */ jsx("span", { style: { color: C10.textSecondary, fontWeight: 600 }, children: t.serpPreview.url }),
20951
+ /* @__PURE__ */ jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.url }),
20156
20952
  /* @__PURE__ */ jsxs(
20157
20953
  "span",
20158
20954
  {
20159
20955
  style: {
20160
20956
  fontWeight: 700,
20161
20957
  fontVariantNumeric: "tabular-nums",
20162
- color: fullUrl.length <= 75 ? C10.green : C10.red
20958
+ color: fullUrl.length <= 75 ? C13.green : C13.red
20163
20959
  },
20164
20960
  children: [
20165
20961
  fullUrl.length,
@@ -20194,13 +20990,13 @@ function DeviceButton({
20194
20990
  gap: 5,
20195
20991
  padding: "4px 12px",
20196
20992
  borderRadius: 6,
20197
- border: `2px solid ${C10.border}`,
20993
+ border: `2px solid ${C13.border}`,
20198
20994
  fontSize: 11,
20199
20995
  fontWeight: 700,
20200
20996
  cursor: "pointer",
20201
- backgroundColor: active ? C10.cyan : C10.surfaceBg,
20202
- color: active ? C10.black : C10.textPrimary,
20203
- boxShadow: active ? `2px 2px 0 0 ${C10.border}` : "none",
20997
+ backgroundColor: active ? C13.cyan : C13.surfaceBg,
20998
+ color: active ? C13.black : C13.textPrimary,
20999
+ boxShadow: active ? `2px 2px 0 0 ${C13.border}` : "none",
20204
21000
  transition: "background-color 0.15s"
20205
21001
  },
20206
21002
  children: [