@matter-server/dashboard 0.5.15 → 0.6.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.
Files changed (111) hide show
  1. package/dist/esm/components/dialog-box/dialog-box.d.ts +1 -0
  2. package/dist/esm/components/dialog-box/dialog-box.d.ts.map +1 -1
  3. package/dist/esm/components/dialog-box/dialog-box.js +15 -1
  4. package/dist/esm/components/dialog-box/dialog-box.js.map +1 -1
  5. package/dist/esm/components/dialogs/binding/node-binding-dialog.js +15 -19
  6. package/dist/esm/components/dialogs/binding/node-binding-dialog.js.map +1 -1
  7. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-existing.d.ts.map +1 -1
  8. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-existing.js +2 -1
  9. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-existing.js.map +1 -1
  10. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-thread.d.ts.map +1 -1
  11. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-thread.js +13 -5
  12. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-thread.js.map +1 -1
  13. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-wifi.d.ts.map +1 -1
  14. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-wifi.js +13 -9
  15. package/dist/esm/components/dialogs/commission-node-dialog/commission-node-wifi.js.map +1 -1
  16. package/dist/esm/components/dialogs/settings/log-level-dialog.d.ts.map +1 -1
  17. package/dist/esm/components/dialogs/settings/log-level-dialog.js +2 -1
  18. package/dist/esm/components/dialogs/settings/log-level-dialog.js.map +1 -1
  19. package/dist/esm/components/ha-svg-icon.d.ts.map +1 -1
  20. package/dist/esm/components/ha-svg-icon.js +0 -1
  21. package/dist/esm/components/ha-svg-icon.js.map +1 -1
  22. package/dist/esm/entrypoint/main.js +1 -1
  23. package/dist/esm/entrypoint/main.js.map +1 -1
  24. package/dist/esm/pages/cluster-commands/base-cluster-commands.d.ts.map +1 -1
  25. package/dist/esm/pages/cluster-commands/base-cluster-commands.js +72 -68
  26. package/dist/esm/pages/cluster-commands/base-cluster-commands.js.map +1 -1
  27. package/dist/esm/pages/components/header.d.ts +1 -1
  28. package/dist/esm/pages/components/header.d.ts.map +1 -1
  29. package/dist/esm/pages/components/header.js +59 -55
  30. package/dist/esm/pages/components/header.js.map +1 -1
  31. package/dist/esm/pages/components/node-details.js +1 -1
  32. package/dist/esm/pages/components/server-details.d.ts.map +1 -1
  33. package/dist/esm/pages/components/server-details.js +2 -0
  34. package/dist/esm/pages/components/server-details.js.map +1 -1
  35. package/dist/esm/pages/matter-cluster-view.d.ts +2 -1
  36. package/dist/esm/pages/matter-cluster-view.d.ts.map +1 -1
  37. package/dist/esm/pages/matter-cluster-view.js +49 -39
  38. package/dist/esm/pages/matter-cluster-view.js.map +1 -1
  39. package/dist/esm/pages/matter-endpoint-view.d.ts +2 -1
  40. package/dist/esm/pages/matter-endpoint-view.d.ts.map +1 -1
  41. package/dist/esm/pages/matter-endpoint-view.js +44 -35
  42. package/dist/esm/pages/matter-endpoint-view.js.map +1 -1
  43. package/dist/esm/pages/matter-network-view.d.ts +1 -1
  44. package/dist/esm/pages/matter-network-view.d.ts.map +1 -1
  45. package/dist/esm/pages/matter-network-view.js +216 -207
  46. package/dist/esm/pages/matter-network-view.js.map +1 -1
  47. package/dist/esm/pages/matter-node-view.d.ts +2 -1
  48. package/dist/esm/pages/matter-node-view.d.ts.map +1 -1
  49. package/dist/esm/pages/matter-node-view.js +104 -94
  50. package/dist/esm/pages/matter-node-view.js.map +1 -1
  51. package/dist/esm/pages/network/base-network-graph.d.ts.map +1 -1
  52. package/dist/esm/pages/network/base-network-graph.js +12 -5
  53. package/dist/esm/pages/network/base-network-graph.js.map +1 -1
  54. package/dist/esm/pages/network/device-panel.d.ts +1 -0
  55. package/dist/esm/pages/network/device-panel.d.ts.map +1 -1
  56. package/dist/esm/pages/network/device-panel.js +19 -5
  57. package/dist/esm/pages/network/device-panel.js.map +1 -1
  58. package/dist/esm/pages/network/network-details.d.ts +1 -1
  59. package/dist/esm/pages/network/network-details.d.ts.map +1 -1
  60. package/dist/esm/pages/network/network-details.js +275 -272
  61. package/dist/esm/pages/network/network-details.js.map +1 -1
  62. package/dist/esm/pages/network/network-utils.d.ts +5 -0
  63. package/dist/esm/pages/network/network-utils.d.ts.map +1 -1
  64. package/dist/esm/pages/network/network-utils.js +47 -17
  65. package/dist/esm/pages/network/network-utils.js.map +1 -1
  66. package/dist/esm/pages/network/update-connections-dialog.d.ts +1 -1
  67. package/dist/esm/pages/network/update-connections-dialog.d.ts.map +1 -1
  68. package/dist/esm/pages/network/update-connections-dialog.js +51 -47
  69. package/dist/esm/pages/network/update-connections-dialog.js.map +1 -1
  70. package/dist/esm/util/device-icons.d.ts.map +1 -1
  71. package/dist/esm/util/device-icons.js +6 -6
  72. package/dist/esm/util/device-icons.js.map +1 -1
  73. package/dist/esm/util/shared-styles.d.ts +10 -0
  74. package/dist/esm/util/shared-styles.d.ts.map +1 -0
  75. package/dist/esm/util/shared-styles.js +56 -0
  76. package/dist/esm/util/shared-styles.js.map +6 -0
  77. package/dist/web/index.html +53 -1
  78. package/dist/web/js/{commission-node-dialog-ByflSEDK.js → commission-node-dialog-DfwKU9qk.js} +4 -4
  79. package/dist/web/js/{commission-node-existing-CD6-Epwb.js → commission-node-existing-C7ITvNfj.js} +6 -3
  80. package/dist/web/js/{commission-node-thread-CekKshVL.js → commission-node-thread-D-icSzto.js} +23 -7
  81. package/dist/web/js/{commission-node-wifi-D_VKTWwF.js → commission-node-wifi-DwUkXlWz.js} +29 -11
  82. package/dist/web/js/{dialog-box-DdVdxz2_.js → dialog-box-BmpaTrvT.js} +16 -2
  83. package/dist/web/js/{fire_event-uMluKQub.js → fire_event-2ZxL-AHZ.js} +1 -1
  84. package/dist/web/js/{log-level-dialog-BO1OSL0z.js → log-level-dialog-D4hubdib.js} +5 -2
  85. package/dist/web/js/main.js +2 -2
  86. package/dist/web/js/{matter-dashboard-app-b1R3Pout.js → matter-dashboard-app-BtHTmAPq.js} +874 -788
  87. package/dist/web/js/{node-binding-dialog-rikORH9_.js → node-binding-dialog-MMx9rkCF.js} +40 -20
  88. package/package.json +4 -4
  89. package/src/components/dialog-box/dialog-box.ts +16 -1
  90. package/src/components/dialogs/binding/node-binding-dialog.ts +15 -15
  91. package/src/components/dialogs/commission-node-dialog/commission-node-existing.ts +2 -1
  92. package/src/components/dialogs/commission-node-dialog/commission-node-thread.ts +13 -5
  93. package/src/components/dialogs/commission-node-dialog/commission-node-wifi.ts +13 -9
  94. package/src/components/dialogs/settings/log-level-dialog.ts +2 -1
  95. package/src/components/ha-svg-icon.ts +0 -1
  96. package/src/entrypoint/main.ts +1 -1
  97. package/src/pages/cluster-commands/base-cluster-commands.ts +84 -80
  98. package/src/pages/components/header.ts +59 -55
  99. package/src/pages/components/node-details.ts +1 -1
  100. package/src/pages/components/server-details.ts +2 -0
  101. package/src/pages/matter-cluster-view.ts +49 -39
  102. package/src/pages/matter-endpoint-view.ts +49 -40
  103. package/src/pages/matter-network-view.ts +200 -191
  104. package/src/pages/matter-node-view.ts +94 -84
  105. package/src/pages/network/base-network-graph.ts +12 -5
  106. package/src/pages/network/device-panel.ts +20 -5
  107. package/src/pages/network/network-details.ts +236 -231
  108. package/src/pages/network/network-utils.ts +51 -17
  109. package/src/pages/network/update-connections-dialog.ts +51 -47
  110. package/src/util/device-icons.ts +12 -6
  111. package/src/util/shared-styles.ts +58 -0
@@ -9,6 +9,7 @@ import { LitElement, css } from "lit";
9
9
  import { property, state } from "lit/decorators.js";
10
10
  // @ts-expect-error vis-network doesn't have proper type declarations for standalone export
11
11
  import { DataSet, Network } from "vis-network/standalone";
12
+ import { getCssVar } from "../../util/shared-styles.js";
12
13
  import { ThemeService } from "../../util/theme-service.js";
13
14
  import type { NetworkGraphEdge, NetworkGraphNode } from "./network-types.js";
14
15
 
@@ -43,11 +44,11 @@ export abstract class BaseNetworkGraph extends LitElement {
43
44
  private _originalEdgeColors: Map<string, { color: string; highlight: string }> = new Map();
44
45
 
45
46
  protected _getFontColor(): string {
46
- return ThemeService.effectiveTheme === "dark" ? "#e0e0e0" : "#333333";
47
+ return getCssVar("--graph-font-color", ThemeService.effectiveTheme === "dark" ? "#e0e0e0" : "#333333");
47
48
  }
48
49
 
49
50
  protected _getDimmedEdgeColor(): string {
50
- return ThemeService.effectiveTheme === "dark" ? "#555555" : "#cccccc";
51
+ return getCssVar("--graph-edge-dimmed", ThemeService.effectiveTheme === "dark" ? "#555555" : "#cccccc");
51
52
  }
52
53
 
53
54
  /**
@@ -432,7 +433,7 @@ export abstract class BaseNetworkGraph extends LitElement {
432
433
  if (!this._originalEdgeColors.has(edgeId)) {
433
434
  const colorObj = edge.color as { color: string; highlight: string } | undefined;
434
435
  // Extract colors, with fallbacks
435
- const color = colorObj?.color ?? "#999999";
436
+ const color = colorObj?.color ?? getCssVar("--graph-node-fallback", "#999999");
436
437
  const highlight = colorObj?.highlight ?? color;
437
438
  this._originalEdgeColors.set(edgeId, { color, highlight });
438
439
  }
@@ -459,7 +460,10 @@ export abstract class BaseNetworkGraph extends LitElement {
459
460
  const isConnected = edge.from === nodeId || edge.to === nodeId;
460
461
  const originalColor = this._originalEdgeColors.get(String(edge.id));
461
462
  // Use stored original color for connected edges, fallback to a default if somehow missing
462
- const connectedColor = originalColor ?? { color: "#999999", highlight: "#999999" };
463
+ const connectedColor = originalColor ?? {
464
+ color: getCssVar("--graph-node-fallback", "#999999"),
465
+ highlight: getCssVar("--graph-node-fallback", "#999999"),
466
+ };
463
467
  return {
464
468
  id: edge.id,
465
469
  width: isConnected ? 3 : 1,
@@ -502,7 +506,10 @@ export abstract class BaseNetworkGraph extends LitElement {
502
506
  return {
503
507
  id: edge.id,
504
508
  width: 2,
505
- color: originalColor ?? { color: "#999999", highlight: "#999999" },
509
+ color: originalColor ?? {
510
+ color: getCssVar("--graph-node-fallback", "#999999"),
511
+ highlight: getCssVar("--graph-node-fallback", "#999999"),
512
+ },
506
513
  };
507
514
  });
508
515
  this._edgesDataSet.update(edgeUpdates);
@@ -70,6 +70,13 @@ export class DevicePanel extends LitElement {
70
70
  this._isExpanded = !this._isExpanded;
71
71
  }
72
72
 
73
+ private _handleHeaderKeydown(event: KeyboardEvent): void {
74
+ if (event.key === "Enter" || event.key === " ") {
75
+ event.preventDefault();
76
+ this._toggleExpanded();
77
+ }
78
+ }
79
+
73
80
  private _handleNodeClick(nodeId: number | bigint): void {
74
81
  this.dispatchEvent(
75
82
  new CustomEvent("node-selected", {
@@ -87,7 +94,14 @@ export class DevicePanel extends LitElement {
87
94
 
88
95
  return html`
89
96
  <div class="panel">
90
- <div class="header" @click=${this._toggleExpanded}>
97
+ <div
98
+ class="header"
99
+ role="button"
100
+ tabindex="0"
101
+ aria-expanded=${this._isExpanded}
102
+ @click=${this._toggleExpanded}
103
+ @keydown=${this._handleHeaderKeydown}
104
+ >
91
105
  <ha-svg-icon .path=${this._getIcon()} class="type-icon"></ha-svg-icon>
92
106
  <span class="title">${this._getTitle()}</span>
93
107
  <span class="count">(${this.nodeIds.length})</span>
@@ -143,6 +157,11 @@ export class DevicePanel extends LitElement {
143
157
  background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
144
158
  }
145
159
 
160
+ .header:focus-visible {
161
+ outline: 2px solid var(--md-sys-color-primary);
162
+ outline-offset: -2px;
163
+ }
164
+
146
165
  .type-icon {
147
166
  --icon-primary-color: var(--md-sys-color-primary, #6200ee);
148
167
  margin-right: 12px;
@@ -172,9 +191,5 @@ export class DevicePanel extends LitElement {
172
191
  md-list-item {
173
192
  --md-list-item-one-line-container-height: 48px;
174
193
  }
175
-
176
- md-list-item::part(focus-ring) {
177
- display: none;
178
- }
179
194
  `;
180
195
  }
@@ -13,6 +13,7 @@ import { customElement, property, state } from "lit/decorators.js";
13
13
  import { clientContext } from "../../client/client-context.js";
14
14
  import "../../components/ha-svg-icon";
15
15
  import { formatNodeAddressFromAny, getEffectiveFabricIndex } from "../../util/format_hex.js";
16
+ import { getCssVar, reducedMotionStyles } from "../../util/shared-styles.js";
16
17
  import type { ThreadNeighbor } from "./network-types.js";
17
18
  import type { NodeConnection } from "./network-utils.js";
18
19
  import {
@@ -100,16 +101,15 @@ export class NetworkDetails extends LitElement {
100
101
  }
101
102
 
102
103
  private _getSignalIcon(neighbor: ThreadNeighbor): string {
103
- const color = getSignalColor(neighbor);
104
- if (color === "#4caf50") return mdiSignalCellular3; // Strong
105
- if (color === "#ff9800") return mdiSignalCellular2; // Medium
106
- return mdiSignalCellular1; // Weak
104
+ return this._getSignalIconFromColor(getSignalColor(neighbor));
107
105
  }
108
106
 
109
107
  private _getSignalIconFromColor(color: string): string {
110
- if (color === "#4caf50") return mdiSignalCellular3; // Strong
111
- if (color === "#ff9800") return mdiSignalCellular2; // Medium
112
- return mdiSignalCellular1; // Weak
108
+ const strongColor = getCssVar("--signal-color-strong", "#4caf50");
109
+ const mediumColor = getCssVar("--signal-color-medium", "#ff9800");
110
+ if (color === strongColor) return mdiSignalCellular3;
111
+ if (color === mediumColor) return mdiSignalCellular2;
112
+ return mdiSignalCellular1;
113
113
  }
114
114
 
115
115
  /**
@@ -429,7 +429,9 @@ export class NetworkDetails extends LitElement {
429
429
 
430
430
  // Find the neighbor entry to get RSSI/LQI
431
431
  const neighborEntry = this._findNeighborEntry(node, unknown.extAddressHex);
432
- const signalColor = neighborEntry ? getSignalColor(neighborEntry) : "#999";
432
+ const signalColor = neighborEntry
433
+ ? getSignalColor(neighborEntry)
434
+ : getCssVar("--graph-node-fallback", "#999");
433
435
  const rssi = neighborEntry?.avgRssi ?? neighborEntry?.lastRssi ?? null;
434
436
  const lqi = neighborEntry?.lqi;
435
437
 
@@ -793,269 +795,272 @@ export class NetworkDetails extends LitElement {
793
795
  `;
794
796
  }
795
797
 
796
- static override styles = css`
797
- :host {
798
- display: block;
799
- height: 100%;
800
- }
798
+ static override styles = [
799
+ reducedMotionStyles,
800
+ css`
801
+ :host {
802
+ display: block;
803
+ height: 100%;
804
+ }
801
805
 
802
- .empty-state {
803
- display: flex;
804
- align-items: center;
805
- justify-content: center;
806
- height: 100%;
807
- color: var(--md-sys-color-on-surface-variant, #666);
808
- text-align: center;
809
- padding: 24px;
810
- }
806
+ .empty-state {
807
+ display: flex;
808
+ align-items: center;
809
+ justify-content: center;
810
+ height: 100%;
811
+ color: var(--md-sys-color-on-surface-variant, #666);
812
+ text-align: center;
813
+ padding: 24px;
814
+ }
811
815
 
812
- .details-panel {
813
- display: flex;
814
- flex-direction: column;
815
- height: 100%;
816
- background-color: var(--md-sys-color-surface, #fff);
817
- border-radius: 8px;
818
- border: 1px solid var(--md-sys-color-outline-variant, #ccc);
819
- overflow: hidden;
820
- }
816
+ .details-panel {
817
+ display: flex;
818
+ flex-direction: column;
819
+ height: 100%;
820
+ background-color: var(--md-sys-color-surface, #fff);
821
+ border-radius: 8px;
822
+ border: 1px solid var(--md-sys-color-outline-variant, #ccc);
823
+ overflow: hidden;
824
+ }
821
825
 
822
- .header {
823
- display: flex;
824
- align-items: center;
825
- justify-content: space-between;
826
- padding: 12px 16px;
827
- background-color: var(--md-sys-color-surface-container, #f5f5f5);
828
- border-bottom: 1px solid var(--md-sys-color-outline-variant, #ccc);
829
- }
826
+ .header {
827
+ display: flex;
828
+ align-items: center;
829
+ justify-content: space-between;
830
+ padding: 12px 16px;
831
+ background-color: var(--md-sys-color-surface-container, #f5f5f5);
832
+ border-bottom: 1px solid var(--md-sys-color-outline-variant, #ccc);
833
+ }
830
834
 
831
- .header h3 {
832
- margin: 0;
833
- font-size: 1rem;
834
- font-weight: 500;
835
- color: var(--md-sys-color-on-surface, #333);
836
- }
835
+ .header h3 {
836
+ margin: 0;
837
+ font-size: 1rem;
838
+ font-weight: 500;
839
+ color: var(--md-sys-color-on-surface, #333);
840
+ }
837
841
 
838
- .node-id-hex {
839
- font-size: 0.75em;
840
- font-weight: 400;
841
- color: var(--md-sys-color-on-surface-variant, #666);
842
- font-family: monospace;
843
- }
842
+ .node-id-hex {
843
+ font-size: 0.75em;
844
+ font-weight: 400;
845
+ color: var(--md-sys-color-on-surface-variant, #666);
846
+ font-family: var(--monospace-font, monospace);
847
+ }
844
848
 
845
- .header-actions {
846
- display: flex;
847
- align-items: center;
848
- gap: 4px;
849
- }
849
+ .header-actions {
850
+ display: flex;
851
+ align-items: center;
852
+ gap: 4px;
853
+ }
850
854
 
851
- .action-button {
852
- background: none;
853
- border: none;
854
- padding: 4px;
855
- cursor: pointer;
856
- border-radius: 50%;
857
- display: flex;
858
- align-items: center;
859
- justify-content: center;
860
- }
855
+ .action-button {
856
+ background: none;
857
+ border: none;
858
+ padding: 4px;
859
+ cursor: pointer;
860
+ border-radius: 50%;
861
+ display: flex;
862
+ align-items: center;
863
+ justify-content: center;
864
+ }
861
865
 
862
- .action-button:hover {
863
- background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
864
- }
866
+ .action-button:hover {
867
+ background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
868
+ }
865
869
 
866
- .action-button ha-svg-icon {
867
- --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
868
- }
870
+ .action-button ha-svg-icon {
871
+ --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
872
+ }
869
873
 
870
- .close-button {
871
- background: none;
872
- border: none;
873
- padding: 4px;
874
- cursor: pointer;
875
- border-radius: 50%;
876
- display: flex;
877
- align-items: center;
878
- justify-content: center;
879
- }
874
+ .close-button {
875
+ background: none;
876
+ border: none;
877
+ padding: 4px;
878
+ cursor: pointer;
879
+ border-radius: 50%;
880
+ display: flex;
881
+ align-items: center;
882
+ justify-content: center;
883
+ }
880
884
 
881
- .close-button:hover {
882
- background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
883
- }
885
+ .close-button:hover {
886
+ background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
887
+ }
884
888
 
885
- .close-button ha-svg-icon {
886
- --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
887
- }
889
+ .close-button ha-svg-icon {
890
+ --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
891
+ }
888
892
 
889
- .content {
890
- flex: 1;
891
- overflow-y: auto;
892
- padding: 0;
893
- }
893
+ .content {
894
+ flex: 1;
895
+ overflow-y: auto;
896
+ padding: 0;
897
+ }
894
898
 
895
- .section {
896
- padding: 16px;
897
- }
899
+ .section {
900
+ padding: 16px;
901
+ }
898
902
 
899
- .section h4 {
900
- margin: 0 0 12px 0;
901
- font-size: 0.875rem;
902
- font-weight: 500;
903
- color: var(--md-sys-color-primary, #6200ee);
904
- text-transform: uppercase;
905
- letter-spacing: 0.5px;
906
- }
903
+ .section h4 {
904
+ margin: 0 0 12px 0;
905
+ font-size: 0.875rem;
906
+ font-weight: 500;
907
+ color: var(--md-sys-color-primary, #6200ee);
908
+ text-transform: uppercase;
909
+ letter-spacing: 0.5px;
910
+ }
907
911
 
908
- .info-row {
909
- display: flex;
910
- justify-content: space-between;
911
- padding: 6px 0;
912
- font-size: 0.875rem;
913
- }
912
+ .info-row {
913
+ display: flex;
914
+ justify-content: space-between;
915
+ padding: 6px 0;
916
+ font-size: 0.875rem;
917
+ }
914
918
 
915
- .label {
916
- color: var(--md-sys-color-on-surface-variant, #666);
917
- }
919
+ .label {
920
+ color: var(--md-sys-color-on-surface-variant, #666);
921
+ }
918
922
 
919
- .value {
920
- color: var(--md-sys-color-on-surface, #333);
921
- font-weight: 500;
922
- text-align: right;
923
- word-break: break-all;
924
- max-width: 60%;
925
- }
923
+ .value {
924
+ color: var(--md-sys-color-on-surface, #333);
925
+ font-weight: 500;
926
+ text-align: right;
927
+ word-break: break-all;
928
+ max-width: 60%;
929
+ }
926
930
 
927
- .value.mono {
928
- font-family: monospace;
929
- font-size: 0.8rem;
930
- }
931
+ .value.mono {
932
+ font-family: var(--monospace-font, monospace);
933
+ font-size: 0.8rem;
934
+ }
931
935
 
932
- .status-online {
933
- color: #4caf50;
934
- }
936
+ .status-online {
937
+ color: var(--signal-color-strong, #4caf50);
938
+ }
935
939
 
936
- .status-offline {
937
- color: var(--danger-color, #f44336);
938
- }
940
+ .status-offline {
941
+ color: var(--danger-color, #f44336);
942
+ }
939
943
 
940
- .neighbors-list {
941
- display: flex;
942
- flex-direction: column;
943
- gap: 8px;
944
- }
944
+ .neighbors-list {
945
+ display: flex;
946
+ flex-direction: column;
947
+ gap: 8px;
948
+ }
945
949
 
946
- .neighbor-item {
947
- display: flex;
948
- align-items: flex-start;
949
- gap: 12px;
950
- padding: 8px;
951
- background-color: var(--md-sys-color-surface-container, #f5f5f5);
952
- border-radius: 4px;
953
- }
950
+ .neighbor-item {
951
+ display: flex;
952
+ align-items: flex-start;
953
+ gap: 12px;
954
+ padding: 8px;
955
+ background-color: var(--md-sys-color-surface-container, #f5f5f5);
956
+ border-radius: 4px;
957
+ }
954
958
 
955
- .neighbor-item.clickable {
956
- cursor: pointer;
957
- transition: background-color 0.15s;
958
- }
959
+ .neighbor-item.clickable {
960
+ cursor: pointer;
961
+ transition: background-color 0.15s;
962
+ }
959
963
 
960
- .neighbor-item.clickable:hover {
961
- background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
962
- }
964
+ .neighbor-item.clickable:hover {
965
+ background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
966
+ }
963
967
 
964
- .neighbor-item ha-svg-icon {
965
- flex-shrink: 0;
966
- margin-top: 2px;
967
- }
968
+ .neighbor-item ha-svg-icon {
969
+ flex-shrink: 0;
970
+ margin-top: 2px;
971
+ }
968
972
 
969
- .neighbor-info {
970
- flex: 1;
971
- min-width: 0;
972
- }
973
+ .neighbor-info {
974
+ flex: 1;
975
+ min-width: 0;
976
+ }
973
977
 
974
- .neighbor-name {
975
- font-size: 0.875rem;
976
- color: var(--md-sys-color-on-surface, #333);
977
- word-break: break-word;
978
- }
978
+ .neighbor-name {
979
+ font-size: 0.875rem;
980
+ color: var(--md-sys-color-on-surface, #333);
981
+ word-break: break-word;
982
+ }
979
983
 
980
- .neighbor-signal {
981
- font-size: 0.75rem;
982
- color: var(--md-sys-color-on-surface-variant, #666);
983
- margin-top: 2px;
984
- }
984
+ .neighbor-signal {
985
+ font-size: 0.75rem;
986
+ color: var(--md-sys-color-on-surface-variant, #666);
987
+ margin-top: 2px;
988
+ }
985
989
 
986
- .direction-hint {
987
- font-style: italic;
988
- opacity: 0.8;
989
- }
990
+ .direction-hint {
991
+ font-style: italic;
992
+ opacity: 0.8;
993
+ }
990
994
 
991
- .route-info {
992
- color: var(--md-sys-color-tertiary, #7d5260);
993
- font-size: 0.85em;
994
- }
995
+ .route-info {
996
+ color: var(--md-sys-color-tertiary, #7d5260);
997
+ font-size: 0.85em;
998
+ }
995
999
 
996
- .footer {
997
- padding: 12px 16px;
998
- border-top: 1px solid var(--md-sys-color-outline-variant, #ccc);
999
- text-align: center;
1000
- }
1000
+ .footer {
1001
+ padding: 12px 16px;
1002
+ border-top: 1px solid var(--md-sys-color-outline-variant, #ccc);
1003
+ text-align: center;
1004
+ }
1001
1005
 
1002
- .view-link {
1003
- color: var(--md-sys-color-primary, #6200ee);
1004
- text-decoration: none;
1005
- font-size: 0.875rem;
1006
- font-weight: 500;
1007
- }
1006
+ .view-link {
1007
+ color: var(--md-sys-color-primary, #6200ee);
1008
+ text-decoration: none;
1009
+ font-size: 0.875rem;
1010
+ font-weight: 500;
1011
+ }
1008
1012
 
1009
- .view-link:hover {
1010
- text-decoration: underline;
1011
- }
1013
+ .view-link:hover {
1014
+ text-decoration: underline;
1015
+ }
1012
1016
 
1013
- md-divider {
1014
- --md-divider-color: var(--md-sys-color-outline-variant, #ccc);
1015
- }
1017
+ md-divider {
1018
+ --md-divider-color: var(--md-sys-color-outline-variant, #ccc);
1019
+ }
1016
1020
 
1017
- .hint-text {
1018
- font-size: 0.8rem;
1019
- color: var(--md-sys-color-on-surface-variant, #666);
1020
- line-height: 1.4;
1021
- margin: 0;
1022
- }
1021
+ .hint-text {
1022
+ font-size: 0.8rem;
1023
+ color: var(--md-sys-color-on-surface-variant, #666);
1024
+ line-height: 1.4;
1025
+ margin: 0;
1026
+ }
1023
1027
 
1024
- .connected-nodes-list {
1025
- display: flex;
1026
- flex-direction: column;
1027
- gap: 8px;
1028
- }
1028
+ .connected-nodes-list {
1029
+ display: flex;
1030
+ flex-direction: column;
1031
+ gap: 8px;
1032
+ }
1029
1033
 
1030
- .connected-node-item {
1031
- display: flex;
1032
- align-items: center;
1033
- justify-content: space-between;
1034
- padding: 8px;
1035
- background-color: var(--md-sys-color-surface-container, #f5f5f5);
1036
- border-radius: 4px;
1037
- }
1034
+ .connected-node-item {
1035
+ display: flex;
1036
+ align-items: center;
1037
+ justify-content: space-between;
1038
+ padding: 8px;
1039
+ background-color: var(--md-sys-color-surface-container, #f5f5f5);
1040
+ border-radius: 4px;
1041
+ }
1038
1042
 
1039
- .connected-node-item.clickable {
1040
- cursor: pointer;
1041
- transition: background-color 0.15s;
1042
- }
1043
+ .connected-node-item.clickable {
1044
+ cursor: pointer;
1045
+ transition: background-color 0.15s;
1046
+ }
1043
1047
 
1044
- .connected-node-item.clickable:hover {
1045
- background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
1046
- }
1048
+ .connected-node-item.clickable:hover {
1049
+ background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
1050
+ }
1047
1051
 
1048
- .connected-node-item .node-name {
1049
- font-size: 0.875rem;
1050
- color: var(--md-sys-color-on-surface, #333);
1051
- word-break: break-word;
1052
- }
1052
+ .connected-node-item .node-name {
1053
+ font-size: 0.875rem;
1054
+ color: var(--md-sys-color-on-surface, #333);
1055
+ word-break: break-word;
1056
+ }
1053
1057
 
1054
- .connected-node-item .node-signal {
1055
- font-size: 0.8rem;
1056
- font-weight: 500;
1057
- flex-shrink: 0;
1058
- margin-left: 8px;
1059
- }
1060
- `;
1058
+ .connected-node-item .node-signal {
1059
+ font-size: 0.8rem;
1060
+ font-weight: 500;
1061
+ flex-shrink: 0;
1062
+ margin-left: 8px;
1063
+ }
1064
+ `,
1065
+ ];
1061
1066
  }