sqlseed-web 0.2.4__py3-none-any.whl

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 (87) hide show
  1. sqlseed_web/AGENTS.md +106 -0
  2. sqlseed_web/__init__.py +24 -0
  3. sqlseed_web/__main__.py +8 -0
  4. sqlseed_web/_application.py +205 -0
  5. sqlseed_web/ai_settings.py +290 -0
  6. sqlseed_web/api.py +1102 -0
  7. sqlseed_web/app.py +26 -0
  8. sqlseed_web/managed_worker.py +184 -0
  9. sqlseed_web/operation_errors.py +42 -0
  10. sqlseed_web/plugin_environment.py +231 -0
  11. sqlseed_web/plugin_management.py +322 -0
  12. sqlseed_web/plugin_process.py +131 -0
  13. sqlseed_web/runtime_lifecycle.py +130 -0
  14. sqlseed_web/runtime_session.py +97 -0
  15. sqlseed_web/settings_environment.py +368 -0
  16. sqlseed_web/sqlite_target.py +86 -0
  17. sqlseed_web/state.py +348 -0
  18. sqlseed_web/static/AGENTS.md +180 -0
  19. sqlseed_web/static/ai.css +57 -0
  20. sqlseed_web/static/configs.css +50 -0
  21. sqlseed_web/static/date-picker.css +230 -0
  22. sqlseed_web/static/disclosure.css +149 -0
  23. sqlseed_web/static/graph-clarity.css +103 -0
  24. sqlseed_web/static/index.html +29 -0
  25. sqlseed_web/static/js/api.js +228 -0
  26. sqlseed_web/static/js/app.js +97 -0
  27. sqlseed_web/static/js/dropdown.js +432 -0
  28. sqlseed_web/static/js/filepicker.js +203 -0
  29. sqlseed_web/static/js/genform.js +1066 -0
  30. sqlseed_web/static/js/labels.js +195 -0
  31. sqlseed_web/static/js/pages/browse.js +209 -0
  32. sqlseed_web/static/js/pages/configs.js +424 -0
  33. sqlseed_web/static/js/pages/connect.js +332 -0
  34. sqlseed_web/static/js/pages/heal.js +395 -0
  35. sqlseed_web/static/js/pages/meta.js +110 -0
  36. sqlseed_web/static/js/pages/runs.js +293 -0
  37. sqlseed_web/static/js/pages/settings.js +942 -0
  38. sqlseed_web/static/js/pages/wizard.js +751 -0
  39. sqlseed_web/static/js/pages/workbench.js +3123 -0
  40. sqlseed_web/static/js/tree.js +126 -0
  41. sqlseed_web/static/js/workbench/ai-eligibility.js +33 -0
  42. sqlseed_web/static/js/workbench/ai-handoff.js +31 -0
  43. sqlseed_web/static/js/workbench/ai-stream.js +116 -0
  44. sqlseed_web/static/js/workbench/ai.js +888 -0
  45. sqlseed_web/static/js/workbench/connection.js +508 -0
  46. sqlseed_web/static/js/workbench/date-picker.js +445 -0
  47. sqlseed_web/static/js/workbench/dependency-view.js +119 -0
  48. sqlseed_web/static/js/workbench/editor.js +1236 -0
  49. sqlseed_web/static/js/workbench/focus.js +11 -0
  50. sqlseed_web/static/js/workbench/graph-layout.js +332 -0
  51. sqlseed_web/static/js/workbench/graph.js +970 -0
  52. sqlseed_web/static/js/workbench/guidance.js +29 -0
  53. sqlseed_web/static/js/workbench/model.js +124 -0
  54. sqlseed_web/static/js/workbench/plugin-management.js +512 -0
  55. sqlseed_web/static/js/workbench/preview-scroll-layout.js +94 -0
  56. sqlseed_web/static/js/workbench/preview.js +572 -0
  57. sqlseed_web/static/js/workbench/provider-guide.js +33 -0
  58. sqlseed_web/static/js/workbench/recovery.js +28 -0
  59. sqlseed_web/static/js/workbench/scroll-lock.js +26 -0
  60. sqlseed_web/static/js/workbench/session.js +174 -0
  61. sqlseed_web/static/js/workbench/table-data.js +186 -0
  62. sqlseed_web/static/js/workbench/ui.js +262 -0
  63. sqlseed_web/static/navigation.css +92 -0
  64. sqlseed_web/static/preview.css +29 -0
  65. sqlseed_web/static/runs.css +53 -0
  66. sqlseed_web/static/scrollbars.css +42 -0
  67. sqlseed_web/static/settings.css +108 -0
  68. sqlseed_web/static/style.css +3382 -0
  69. sqlseed_web/static/table-data.css +27 -0
  70. sqlseed_web/static/workbench.css +509 -0
  71. sqlseed_web/supervised_plugins.py +173 -0
  72. sqlseed_web/supervisor.py +238 -0
  73. sqlseed_web/workbench.py +381 -0
  74. sqlseed_web/workbench_ai.py +887 -0
  75. sqlseed_web/workbench_ai_relations.py +285 -0
  76. sqlseed_web/workbench_ai_stream.py +172 -0
  77. sqlseed_web/workbench_data.py +163 -0
  78. sqlseed_web/workbench_execution.py +199 -0
  79. sqlseed_web/workbench_runtime.py +1218 -0
  80. sqlseed_web/workbench_schema.py +277 -0
  81. sqlseed_web/workbench_store.py +458 -0
  82. sqlseed_web/worker_control.py +192 -0
  83. sqlseed_web-0.2.4.dist-info/METADATA +105 -0
  84. sqlseed_web-0.2.4.dist-info/RECORD +87 -0
  85. sqlseed_web-0.2.4.dist-info/WHEEL +4 -0
  86. sqlseed_web-0.2.4.dist-info/entry_points.txt +2 -0
  87. sqlseed_web-0.2.4.dist-info/licenses/LICENSE +679 -0
@@ -0,0 +1,92 @@
1
+ /* Persistent application navigation; route motion never controls lifecycle. */
2
+ html { overflow-y:scroll; }
3
+ @supports(scrollbar-gutter:stable) {
4
+ html { overflow-y:auto; scrollbar-gutter:stable; }
5
+ }
6
+ body > header.top {
7
+ display:grid;
8
+ grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
9
+ align-items:center;
10
+ gap:24px;
11
+ height:67px;
12
+ padding:0 30px;
13
+ }
14
+ body > header.top > .brand { justify-self:start; min-width:0; }
15
+ body > header.top > .top-end { justify-self:end; min-width:0; max-width:100%; margin-left:0; }
16
+ body > header.top #connection-button { max-width:100%; }
17
+ body > header.top #connection-label { min-width:0; }
18
+ #nav {
19
+ display:flex;
20
+ align-items:center;
21
+ justify-self:center;
22
+ gap:4px;
23
+ height:auto;
24
+ padding:4px;
25
+ overflow:visible;
26
+ }
27
+ #nav button {
28
+ position:relative;
29
+ display:inline-flex;
30
+ align-items:center;
31
+ justify-content:center;
32
+ min-height:40px;
33
+ padding:9px 14px;
34
+ border:0;
35
+ border-radius:8px;
36
+ background:transparent;
37
+ color:var(--muted);
38
+ font-size:13px;
39
+ font-weight:600;
40
+ line-height:20px;
41
+ white-space:nowrap;
42
+ transition:color 160ms ease-out,background-color 160ms ease-out;
43
+ }
44
+ #nav button::after {
45
+ content:'';
46
+ position:absolute;
47
+ bottom:4px;
48
+ left:calc(50% - 7px);
49
+ width:14px;
50
+ height:2px;
51
+ border-radius:999px;
52
+ background:transparent;
53
+ transition:background-color 160ms ease-out;
54
+ }
55
+ #nav button:hover { color:var(--ink); background:var(--wash); }
56
+ #nav button.active { color:var(--teal); background:var(--soft); }
57
+ #nav button.active::after { background:var(--teal); }
58
+ #nav button:focus-visible { outline:2px solid var(--teal); outline-offset:2px; }
59
+ #app > .page-enter { animation:page-enter 180ms ease-out; }
60
+ @keyframes page-enter {
61
+ from { opacity:.65; }
62
+ to { opacity:1; }
63
+ }
64
+ @media(max-width:760px) {
65
+ body > header.top {
66
+ grid-template-columns:minmax(0,1fr) auto;
67
+ height:auto;
68
+ gap:0 12px;
69
+ padding:0 16px;
70
+ }
71
+ body > header.top > .brand { grid-column:1; grid-row:1; min-height:54px; }
72
+ body > header.top > .top-end { grid-column:2; grid-row:1; min-height:54px; }
73
+ #nav {
74
+ grid-column:1 / -1;
75
+ grid-row:2;
76
+ justify-self:stretch;
77
+ display:grid;
78
+ grid-template-columns:repeat(4,minmax(0,1fr));
79
+ min-height:54px;
80
+ padding:6px 4px 8px;
81
+ border-top:1px solid var(--line);
82
+ }
83
+ #nav button { min-width:0; width:100%; padding:9px 4px; }
84
+ }
85
+ @media(prefers-reduced-motion:reduce) {
86
+ #nav button,#nav button::after { transition:none; }
87
+ #app > .page-enter { animation:none; }
88
+ }
89
+ @media(forced-colors:active) {
90
+ #nav button.active::after { background:ButtonText; forced-color-adjust:none; }
91
+ #nav button:focus-visible { outline:2px solid Highlight; outline-offset:2px; }
92
+ }
@@ -0,0 +1,29 @@
1
+ /* Keep status copy and first-load feedback within the preview's natural size. */
2
+ .wb-data-preview .wb-preview-status { min-height:1.6em; line-height:1.6; }
3
+ .wb-data-preview .wb-preview-loading {
4
+ display:grid;
5
+ place-items:center;
6
+ min-height:min(160px,20vh);
7
+ margin:12px 0 0;
8
+ padding:20px;
9
+ border:1px dashed var(--line);
10
+ border-radius:8px;
11
+ background:var(--wash);
12
+ color:var(--muted);
13
+ font-size:13px;
14
+ }
15
+ .wb-data-preview .wb-preview-column-name { display:block; font-weight:600; }
16
+ .wb-data-preview .wb-preview-column-meta { display:block; margin-top:5px; font-size:10px; line-height:1.5; font-weight:400; color:var(--muted); }
17
+ .wb-data-preview .wb-preview-interactive-header:hover,
18
+ .wb-data-preview .wb-preview-interactive-header:focus-within { background:var(--wash); }
19
+ .wb-data-preview .wb-preview-interactive-header:has([aria-pressed=true]) { box-shadow:inset 0 -2px 0 var(--teal); }
20
+ .wb-data-preview .wb-preview-column-button { display:block; width:fit-content; min-height:24px; padding:2px 0; text-align:left; color:inherit; font:inherit; text-decoration:none; }
21
+ .wb-data-preview .wb-preview-column-button:hover,
22
+ .wb-data-preview .wb-preview-column-button:focus-visible { text-decoration:underline; text-underline-offset:4px; text-decoration-thickness:1px; }
23
+ .wb-data-preview .wb-preview-column-button[aria-pressed=true] { color:var(--teal); }
24
+ .wb-data-preview .wb-preview-column-button:focus-visible { outline:2px solid var(--teal); outline-offset:2px; border-radius:3px; }
25
+ .wb-data-preview .wb-preview-column-rule { margin-top:5px; font-size:11px; font-weight:400; color:var(--teal); }
26
+ .wb-data-preview .wb-preview-interactive-header .wb-preview-column-meta { margin-top:2px; }
27
+ .wb-field-rule-ai { display:flex; align-items:center; flex-wrap:wrap; gap:8px 12px; padding-bottom:14px; margin-bottom:16px; border-bottom:1px solid var(--line); }
28
+ .wb-field-rule-ai .btn { flex-shrink:0; }
29
+ .wb-field-rule-ai p { flex:1 1 180px; margin:0; font-size:12px; line-height:1.6; }
@@ -0,0 +1,53 @@
1
+ /* Run-specific layout stays stronger than the shared base rules. */
2
+ .runs-page .run-list {
3
+ min-width: 0;
4
+ padding: 8px;
5
+ border: 1px solid var(--line);
6
+ border-radius: 12px;
7
+ background: var(--wash);
8
+ scrollbar-gutter: stable;
9
+ scroll-padding: 8px;
10
+ }
11
+
12
+ .runs-page .run-card {
13
+ border-color: #e8eef0;
14
+ }
15
+
16
+ .runs-page .run-card:last-child {
17
+ margin-bottom: 0;
18
+ }
19
+
20
+ .runs-page .run-card:hover {
21
+ border-color: #b4cfc5;
22
+ background: #f2f8f5;
23
+ }
24
+
25
+ .runs-page .run-card.active {
26
+ border-color: #92bcae;
27
+ background: #edf6f1;
28
+ box-shadow: inset 3px 0 0 var(--teal);
29
+ }
30
+
31
+ .runs-page .run-result-content {
32
+ display: flex;
33
+ flex-direction: column;
34
+ align-items: flex-start;
35
+ gap: 10px;
36
+ min-width: 0;
37
+ }
38
+
39
+ .runs-page .run-result-content > span {
40
+ max-width: 100%;
41
+ white-space: pre-wrap;
42
+ overflow-wrap: anywhere;
43
+ }
44
+
45
+ .runs-page .run-view-data {
46
+ margin: 0;
47
+ }
48
+
49
+ @media (max-width: 760px) {
50
+ .runs-page .run-list {
51
+ max-height: min(240px, 45vh);
52
+ }
53
+ }
@@ -0,0 +1,42 @@
1
+ /* Keep root, panels, menus and tables on the same quiet scrollbar treatment. */
2
+ * {
3
+ scrollbar-width: thin;
4
+ scrollbar-color: var(--muted) var(--wash);
5
+ }
6
+
7
+ ::-webkit-scrollbar {
8
+ width: 8px;
9
+ height: 8px;
10
+ }
11
+
12
+ ::-webkit-scrollbar-track,
13
+ ::-webkit-scrollbar-corner {
14
+ background: var(--wash);
15
+ }
16
+
17
+ ::-webkit-scrollbar-thumb {
18
+ border: 2px solid var(--wash);
19
+ border-radius: 999px;
20
+ background: var(--muted);
21
+ }
22
+
23
+ ::-webkit-scrollbar-thumb:hover {
24
+ background: var(--teal);
25
+ }
26
+
27
+ /* The stable root gutter remains reserved while a dialog owns scrolling. */
28
+ html.wb-scroll-locked {
29
+ overflow: hidden !important;
30
+ }
31
+
32
+ .overlay,
33
+ .modal-body,
34
+ .drawer-body,
35
+ .connection-modal,
36
+ .dropdown-floating {
37
+ overscroll-behavior: contain;
38
+ }
39
+
40
+ @media (forced-colors: active) {
41
+ * { scrollbar-color: auto; }
42
+ }
@@ -0,0 +1,108 @@
1
+ /* Application settings share the workbench theme; generation rules stay in the workbench. */
2
+ .settings-page { max-width:1200px; }
3
+ .settings-layout { display:grid; grid-template-columns:180px minmax(0,1fr); align-items:start; gap:24px; }
4
+ .settings-tabs { display:flex; flex-direction:column; gap:6px; padding:8px; background:var(--wash); border:1px solid var(--line); border-radius:var(--radius); }
5
+ .settings-tabs .btn { justify-content:flex-start; padding:12px 16px; border-color:transparent; background:transparent; }
6
+ .settings-tabs [aria-selected=true] { color:var(--teal); background:var(--soft); border-color:#b6d7cc; font-weight:600; }
7
+ .settings-panels { min-width:0; }
8
+ .settings-panel { padding:26px 30px; background:var(--paper); border:1px solid var(--line); border-radius:var(--radius); }
9
+ .settings-panel[hidden],.settings-form[hidden],.settings-return-prompt[hidden],.settings-install[hidden] { display:none; }
10
+ .settings-panel-head { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin-bottom:22px; }
11
+ .settings-panel-head h2 { margin:0; font-size:20px; }
12
+ .settings-panel-head p { margin:5px 0 0; }
13
+ .settings-badge { display:inline-flex; align-items:center; flex-shrink:0; background:var(--soft); color:var(--teal); border-radius:5px; padding:4px 9px; font-size:12px; white-space:nowrap; }
14
+ .settings-badge-warning { color:#8c581e; background:#fff6e7; }
15
+ .settings-component-impact { margin:8px 0 0; color:#805323; font-size:13px; line-height:1.7; overflow-wrap:anywhere; }
16
+ .settings-current { padding:13px 16px; background:var(--wash); border:1px solid var(--line); border-radius:7px; margin-bottom:24px; }
17
+ .settings-current > span { font-size:12px; }
18
+ .settings-current-model { margin:4px 0 0; font-weight:600; overflow-wrap:anywhere; }
19
+ .settings-readiness { font-size:12px; margin:6px 0 0; }
20
+ .settings-save-state { font-size:12px; min-height:1.6em; margin:10px 0 0; }
21
+ .settings-notice:empty { display:none; }
22
+ .settings-fields { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.5fr); gap:18px; }
23
+ .settings-field { display:flex; flex-direction:column; gap:7px; min-width:0; font-size:13px; }
24
+ .settings-field > span { font-weight:600; }
25
+ .settings-field input { width:100%; min-width:0; height:40px; margin:0; padding:8px 12px; border:1px solid var(--line); border-radius:7px; background:var(--paper); color:var(--ink); }
26
+ .settings-field input:disabled { background:var(--wash); }
27
+ .settings-field .dropdown { width:100%; }
28
+ .settings-field .dropdown-btn { min-height:40px; }
29
+ .settings-service-hint { font-size:12px; margin:10px 0 22px; line-height:1.7; }
30
+ .settings-key { border-top:1px solid var(--line); padding-top:20px; margin-top:20px; }
31
+ .settings-key-hint { font-size:12px; margin:8px 0; }
32
+ .settings-clear-key { display:flex; gap:8px; align-items:center; font-size:12px; color:var(--muted); }
33
+ .settings-clear-key input { width:15px; height:15px; margin:0; }
34
+ .settings-clear-key[hidden] { display:none; }
35
+ .settings-actions { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:22px; }
36
+ .settings-form .settings-actions .btn { box-sizing:border-box; width:108px; height:40px; padding:0 14px; justify-content:center; font-size:13px; line-height:20px; }
37
+ .settings-notice { min-height:1.6em; font-size:13px; margin:12px 0 0; overflow-wrap:anywhere; }
38
+ .settings-test-notice { font-size:12px; margin:10px 0; overflow-wrap:anywhere; }
39
+ .settings-test-notice:empty,.settings-models:empty { display:none; }
40
+ .settings-models { display:flex; flex-wrap:wrap; gap:7px; max-height:130px; overflow:auto; margin:8px 0 16px; }
41
+ .settings-models .btn { max-width:100%; white-space:normal; overflow-wrap:anywhere; text-align:left; }
42
+ .settings-storage { font-size:12px; color:var(--muted); border-top:1px solid var(--line); padding-top:15px; margin-top:18px; }
43
+ .settings-storage summary { cursor:pointer; }
44
+ .settings-storage p { overflow-wrap:anywhere; }
45
+ .settings-storage-location { margin-top:14px; }
46
+ .settings-storage-location .mono { user-select:text; }
47
+ .settings-install { padding:16px; background:var(--soft); border-radius:8px; }
48
+ .settings-install h3 { margin-top:0; }
49
+ .settings-return-prompt { padding:14px 18px; margin-bottom:20px; background:#fff6e7; border:1px solid #e4c99b; border-radius:8px; }
50
+ .settings-return-prompt p { margin:0; }
51
+ .settings-return-prompt .settings-actions { margin-top:10px; }
52
+ .settings-package-group { margin-top:24px; }
53
+ .settings-package-group h3 { font-size:14px; margin:0 0 10px; }
54
+ .settings-package { display:grid; grid-template-columns:minmax(0,1fr) minmax(80px,auto) minmax(68px,auto); gap:18px; align-items:center; padding:15px 0; border-top:1px solid var(--line); }
55
+ .settings-package p { margin:5px 0 0; font-size:12px; overflow-wrap:anywhere; }
56
+ .settings-package-status { text-align:right; }
57
+ .settings-package-name { display:flex; align-items:center; gap:10px; }
58
+ .settings-requirement { color:var(--muted); font-size:11px; border:1px solid var(--line); border-radius:4px; padding:1px 6px; }
59
+ .settings-badge-neutral { color:var(--muted); background:var(--wash); }
60
+ .settings-package-help { grid-column:1 / -1; font-size:12px; padding:10px 12px; background:var(--wash); border-radius:6px; }
61
+ .settings-package-help summary { cursor:pointer; color:var(--teal); font-weight:600; }
62
+ .settings-command { min-width:0; margin-top:10px; }
63
+ .settings-command code { display:block; padding:10px 12px; border:1px solid var(--line); border-radius:6px; background:var(--paper); user-select:text; white-space:pre-wrap; overflow-wrap:anywhere; }
64
+ .settings-command-actions { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:8px; }
65
+ .settings-command-actions .btn { flex-shrink:0; }
66
+ .settings-copy-status { font-size:12px; overflow-wrap:anywhere; }
67
+ .settings-copy-status:empty { display:none; }
68
+ .settings-dependency { color:var(--muted); }
69
+ .settings-version { font-size:12px; color:var(--muted); overflow-wrap:anywhere; max-width:180px; }
70
+ .settings-distribution { color:var(--muted); font-size:11px; overflow-wrap:anywhere; }
71
+ .settings-environment > p { margin-top:24px; font-size:12px; }
72
+ .settings-management { padding:16px 18px; margin:0 0 22px; background:var(--wash); border:1px solid var(--line); border-radius:8px; font-size:13px; }
73
+ .settings-management h3 { margin:0 0 8px; font-size:14px; }
74
+ .settings-management p { margin:8px 0 0; line-height:1.7; overflow-wrap:anywhere; }
75
+ .settings-management .mono { font-size:12px; }
76
+ .settings-management-environment { margin-top:12px; font-size:12px; }
77
+ .settings-management-environment summary { color:var(--muted); }
78
+ .settings-plugin-stages { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 0; padding:0; list-style:none; }
79
+ .settings-plugin-stages li { padding:5px 10px; border:1px solid var(--line); border-radius:16px; font-size:12px; color:var(--muted); }
80
+ .settings-plugin-stages [aria-current=step] { color:var(--teal); border-color:var(--teal); background:var(--soft); }
81
+ .settings-management-restart { color:#8c581e; padding:10px 12px; border:1px solid #e4c99b; border-radius:6px; background:#fff6e7; }
82
+ .settings-package > [data-plugin-controls] { grid-column:1 / -1; }
83
+ .settings-package > [data-plugin-controls]:empty { display:none; }
84
+ .settings-package-management { display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:12px; }
85
+ .settings-package-management:empty { display:none; }
86
+ .settings-package-management .btn { min-width:64px; }
87
+ .settings-plugin-task { border-top:1px solid var(--line); margin-top:14px; padding-top:14px; }
88
+ .settings-plugin-task h4 { margin:0; font-size:13px; }
89
+ .settings-plugin-task details { margin-top:10px; }
90
+ .settings-plugin-task summary { cursor:pointer; color:var(--teal); }
91
+ .settings-plugin-task > .btn { margin-top:10px; }
92
+ .settings-plugin-output { max-height:220px; overflow:auto; padding:12px; border:1px solid var(--line); background:var(--paper); border-radius:6px; white-space:pre-wrap; overflow-wrap:anywhere; font-size:11px; line-height:1.6; user-select:text; }
93
+ .settings-plugin-plan { display:grid; grid-template-columns:72px minmax(0,1fr); gap:10px 14px; margin:20px 0; font-size:13px; }
94
+ .settings-plugin-plan dt { color:var(--muted); }
95
+ .settings-plugin-plan dd { margin:0; overflow-wrap:anywhere; user-select:text; }
96
+ .settings-plugin-warnings { margin:16px 0; padding-left:20px; font-size:13px; line-height:1.8; }
97
+ .settings-plugin-warnings:empty { display:none; }
98
+ @media (max-width:760px) {
99
+ .settings-layout { grid-template-columns:1fr; gap:16px; }
100
+ .settings-tabs { flex-direction:row; }
101
+ .settings-tabs .btn { flex:1; justify-content:center; }
102
+ .settings-panel { padding:20px; }
103
+ .settings-fields { grid-template-columns:1fr; }
104
+ .settings-panel-head { flex-wrap:wrap; }
105
+ .settings-package { gap:12px; grid-template-columns:minmax(0,1fr) auto; }
106
+ .settings-package > div:first-child { grid-column:1 / -1; }
107
+ .settings-version { max-width:none; }
108
+ }