node-red-contrib-me-vplc 1.0.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 (37) hide show
  1. package/README.md +42 -0
  2. package/me-vplc.html +64 -0
  3. package/me-vplc.js +603 -0
  4. package/package.json +26 -0
  5. package/project/README.md +1052 -0
  6. package/project/START_ME_VPLC.cmd +176 -0
  7. package/project/backend/active_project.json +3 -0
  8. package/project/backend/app.py +839 -0
  9. package/project/backend/connector_runtime.py +585 -0
  10. package/project/backend/requirements.txt +3 -0
  11. package/project/backend/st_compiler.py +1415 -0
  12. package/project/frontend/index.html +12 -0
  13. package/project/frontend/package.json +18 -0
  14. package/project/frontend/src/App.jsx +631 -0
  15. package/project/frontend/src/style.css +964 -0
  16. package/project/frontend/vite.config.js +14 -0
  17. package/wheelhouse/Flask_Cors-4.0.1-py2.py3-none-any.whl +0 -0
  18. package/wheelhouse/blinker-1.9.0-py3-none-any.whl +0 -0
  19. package/wheelhouse/click-8.3.3-py3-none-any.whl +0 -0
  20. package/wheelhouse/colorama-0.4.6-py2.py3-none-any.whl +0 -0
  21. package/wheelhouse/flask-3.0.3-py3-none-any.whl +0 -0
  22. package/wheelhouse/itsdangerous-2.2.0-py3-none-any.whl +0 -0
  23. package/wheelhouse/jinja2-3.1.6-py3-none-any.whl +0 -0
  24. package/wheelhouse/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl +0 -0
  25. package/wheelhouse/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +0 -0
  26. package/wheelhouse/markupsafe-3.0.3-cp310-cp310-win_amd64.whl +0 -0
  27. package/wheelhouse/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl +0 -0
  28. package/wheelhouse/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +0 -0
  29. package/wheelhouse/markupsafe-3.0.3-cp311-cp311-win_amd64.whl +0 -0
  30. package/wheelhouse/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl +0 -0
  31. package/wheelhouse/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +0 -0
  32. package/wheelhouse/markupsafe-3.0.3-cp312-cp312-win_amd64.whl +0 -0
  33. package/wheelhouse/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl +0 -0
  34. package/wheelhouse/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +0 -0
  35. package/wheelhouse/markupsafe-3.0.3-cp313-cp313-win_amd64.whl +0 -0
  36. package/wheelhouse/pymodbus-3.6.9-py3-none-any.whl +0 -0
  37. package/wheelhouse/werkzeug-3.1.8-py3-none-any.whl +0 -0
@@ -0,0 +1,964 @@
1
+ :root {
2
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
3
+ background: #eef2f7;
4
+ color: #172033;
5
+ }
6
+
7
+ * {
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ html,
12
+ body,
13
+ #root {
14
+ width: 100%;
15
+ min-height: 100%;
16
+ }
17
+
18
+ body {
19
+ margin: 0;
20
+ }
21
+
22
+ button,
23
+ input {
24
+ font: inherit;
25
+ }
26
+
27
+ button {
28
+ border: 0;
29
+ border-radius: 12px;
30
+ padding: 10px 16px;
31
+ background: #e3e9f3;
32
+ color: #172033;
33
+ cursor: pointer;
34
+ font-weight: 700;
35
+ }
36
+
37
+ button:disabled {
38
+ opacity: 0.45;
39
+ cursor: not-allowed;
40
+ }
41
+
42
+ button.primary {
43
+ background: #167a3c;
44
+ color: white;
45
+ }
46
+
47
+ button.danger {
48
+ background: #b42d2d;
49
+ color: white;
50
+ }
51
+
52
+ .app {
53
+ width: 100%;
54
+ max-width: none;
55
+ margin: 0;
56
+ padding: 24px;
57
+ display: grid;
58
+ gap: 16px;
59
+ }
60
+
61
+ .header {
62
+ display: flex;
63
+ justify-content: space-between;
64
+ align-items: center;
65
+ gap: 16px;
66
+ }
67
+
68
+ .header h1 {
69
+ margin: 0;
70
+ font-size: 32px;
71
+ }
72
+
73
+ .header p {
74
+ margin: 4px 0 0;
75
+ color: #607089;
76
+ }
77
+
78
+ .status {
79
+ padding: 10px 16px;
80
+ border-radius: 999px;
81
+ color: white;
82
+ font-weight: 800;
83
+ letter-spacing: 0.05em;
84
+ }
85
+
86
+ .status.running {
87
+ background: #167a3c;
88
+ }
89
+
90
+ .status.stopped {
91
+ background: #7b8495;
92
+ }
93
+
94
+ .page-nav {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 10px;
98
+ flex-wrap: wrap;
99
+ padding: 8px;
100
+ background: #dde6f2;
101
+ border: 1px solid #cfd9e8;
102
+ border-radius: 18px;
103
+ }
104
+
105
+ .nav-button {
106
+ background: transparent;
107
+ color: #42526b;
108
+ border-radius: 12px;
109
+ }
110
+
111
+ .nav-button.active {
112
+ background: white;
113
+ color: #172033;
114
+ box-shadow: 0 6px 18px rgba(35, 55, 80, 0.08);
115
+ }
116
+
117
+ .page-grid {
118
+ display: grid;
119
+ gap: 16px;
120
+ }
121
+
122
+ .control-page {
123
+ grid-template-columns: 1fr;
124
+ }
125
+
126
+ .control-page .controls-card {
127
+ width: 100%;
128
+ }
129
+
130
+ .card {
131
+ background: white;
132
+ border: 1px solid #d9e1eb;
133
+ border-radius: 18px;
134
+ box-shadow: 0 12px 30px rgba(35, 55, 80, 0.08);
135
+ padding: 18px;
136
+ }
137
+
138
+ .section-title-row {
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: space-between;
142
+ gap: 12px;
143
+ margin-bottom: 16px;
144
+ }
145
+
146
+ .section-title-row h2 {
147
+ margin: 0;
148
+ }
149
+
150
+ .section-title-row span {
151
+ color: #607089;
152
+ font-weight: 700;
153
+ font-size: 13px;
154
+ }
155
+
156
+ .full-row {
157
+ width: 100%;
158
+ }
159
+
160
+ .controls-card {
161
+ display: grid;
162
+ gap: 18px;
163
+ }
164
+
165
+ .control-actions,
166
+ .cycle-settings {
167
+ display: flex;
168
+ align-items: end;
169
+ gap: 12px;
170
+ flex-wrap: wrap;
171
+ }
172
+
173
+ .imports {
174
+ display: flex;
175
+ align-items: end;
176
+ gap: 12px;
177
+ flex-wrap: wrap;
178
+ }
179
+
180
+ .cycle-control {
181
+ display: grid;
182
+ gap: 6px;
183
+ min-width: 180px;
184
+ }
185
+
186
+ .cycle-control span {
187
+ font-size: 13px;
188
+ font-weight: 700;
189
+ color: #53657d;
190
+ }
191
+
192
+ .cycle-control input {
193
+ border: 1px solid #cdd7e4;
194
+ border-radius: 12px;
195
+ padding: 9px 12px;
196
+ width: 100%;
197
+ }
198
+
199
+ .togglebar {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ gap: 10px;
203
+ min-height: 42px;
204
+ padding: 4px 8px;
205
+ font-weight: 800;
206
+ color: #172033;
207
+ user-select: none;
208
+ }
209
+
210
+ .togglebar input {
211
+ display: none;
212
+ }
213
+
214
+ .toggle-slider {
215
+ position: relative;
216
+ display: inline-block;
217
+ width: 54px;
218
+ height: 30px;
219
+ border-radius: 999px;
220
+ background: #cbd5e1;
221
+ transition: background 0.18s ease;
222
+ }
223
+
224
+ .toggle-slider::after {
225
+ content: "";
226
+ position: absolute;
227
+ top: 4px;
228
+ left: 4px;
229
+ width: 22px;
230
+ height: 22px;
231
+ border-radius: 50%;
232
+ background: #ffffff;
233
+ box-shadow: 0 2px 8px rgba(20, 35, 55, 0.22);
234
+ transition: transform 0.18s ease;
235
+ }
236
+
237
+ .togglebar input:checked + .toggle-slider {
238
+ background: #167a3c;
239
+ }
240
+
241
+ .togglebar input:checked + .toggle-slider::after {
242
+ transform: translateX(24px);
243
+ }
244
+
245
+ .toggle-text {
246
+ white-space: nowrap;
247
+ }
248
+
249
+ .import-info {
250
+ display: flex;
251
+ gap: 18px;
252
+ flex-wrap: wrap;
253
+ color: #53657d;
254
+ font-weight: 700;
255
+ }
256
+
257
+ .connector-info {
258
+ display: grid;
259
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
260
+ gap: 10px 18px;
261
+ width: 100%;
262
+ margin-top: 12px;
263
+ padding-top: 12px;
264
+ border-top: 1px solid #e6edf5;
265
+ color: #42526b;
266
+ font-size: 0.92rem;
267
+ }
268
+
269
+ .connector-error {
270
+ color: #a32020;
271
+ font-weight: 700;
272
+ }
273
+
274
+ .empty-state {
275
+ border: 1px dashed #cdd7e4;
276
+ border-radius: 14px;
277
+ padding: 14px;
278
+ color: #607089;
279
+ background: #f8fafc;
280
+ }
281
+
282
+ .summary {
283
+ display: grid;
284
+ grid-template-columns: repeat(4, 1fr);
285
+ gap: 12px;
286
+ }
287
+
288
+ .summary div {
289
+ border-radius: 14px;
290
+ background: #f4f7fb;
291
+ padding: 14px;
292
+ display: grid;
293
+ gap: 6px;
294
+ }
295
+
296
+ .summary span {
297
+ color: #607089;
298
+ font-weight: 700;
299
+ }
300
+
301
+ .summary strong {
302
+ font-size: 24px;
303
+ }
304
+
305
+ .summary small {
306
+ color: #7b8495;
307
+ font-weight: 700;
308
+ }
309
+
310
+ .phases h2 {
311
+ margin: 0 0 14px;
312
+ }
313
+
314
+ table {
315
+ width: 100%;
316
+ border-collapse: collapse;
317
+ }
318
+
319
+ th,
320
+ td {
321
+ text-align: left;
322
+ border-bottom: 1px solid #e4eaf2;
323
+ padding: 12px 10px;
324
+ }
325
+
326
+ th {
327
+ color: #53657d;
328
+ font-size: 13px;
329
+ text-transform: uppercase;
330
+ letter-spacing: 0.04em;
331
+ }
332
+
333
+ @media (max-width: 1060px) {
334
+ .summary {
335
+ grid-template-columns: repeat(2, 1fr);
336
+ }
337
+ }
338
+
339
+ @media (max-width: 760px) {
340
+ .app {
341
+ padding: 16px;
342
+ }
343
+
344
+ .header,
345
+ .control-actions,
346
+ .cycle-settings,
347
+ .imports,
348
+ .section-title-row {
349
+ align-items: stretch;
350
+ flex-direction: column;
351
+ }
352
+
353
+ .summary {
354
+ grid-template-columns: 1fr;
355
+ }
356
+
357
+ .control-page {
358
+ grid-template-columns: 1fr;
359
+ }
360
+ }
361
+
362
+ .text-link {
363
+ padding: 0;
364
+ border-radius: 0;
365
+ background: transparent;
366
+ color: #1d4f91;
367
+ font-weight: 800;
368
+ text-decoration: underline;
369
+ text-underline-offset: 3px;
370
+ }
371
+
372
+ .text-link:disabled {
373
+ color: #69778d;
374
+ text-decoration: none;
375
+ opacity: 0.75;
376
+ }
377
+
378
+ .modal-backdrop {
379
+ position: fixed;
380
+ inset: 0;
381
+ z-index: 1000;
382
+ display: grid;
383
+ place-items: center;
384
+ padding: 24px;
385
+ background: rgba(12, 20, 33, 0.52);
386
+ }
387
+
388
+ .modal-card {
389
+ width: min(1400px, 96vw);
390
+ height: min(860px, 92vh);
391
+ display: grid;
392
+ grid-template-rows: auto auto minmax(0, 1fr) auto;
393
+ gap: 12px;
394
+ background: #ffffff;
395
+ border: 1px solid #d9e1eb;
396
+ border-radius: 20px;
397
+ box-shadow: 0 24px 80px rgba(0, 0, 0, 0.28);
398
+ padding: 18px;
399
+ }
400
+
401
+ .modal-header,
402
+ .modal-actions {
403
+ display: flex;
404
+ align-items: center;
405
+ justify-content: space-between;
406
+ gap: 12px;
407
+ }
408
+
409
+ .modal-header h2 {
410
+ margin: 0;
411
+ }
412
+
413
+ .modal-header p {
414
+ margin: 4px 0 0;
415
+ color: #607089;
416
+ font-weight: 700;
417
+ }
418
+
419
+ .modal-close {
420
+ background: #edf2f8;
421
+ }
422
+
423
+ .modal-error {
424
+ border: 1px solid #f0b4b4;
425
+ border-radius: 12px;
426
+ padding: 10px 12px;
427
+ background: #fff3f3;
428
+ color: #a32020;
429
+ font-weight: 700;
430
+ }
431
+
432
+ .editor-layout {
433
+ min-height: 0;
434
+ display: grid;
435
+ grid-template-columns: minmax(240px, 340px) minmax(0, 1fr);
436
+ gap: 12px;
437
+ }
438
+
439
+ .editor-file-list {
440
+ min-height: 0;
441
+ overflow: auto;
442
+ display: grid;
443
+ align-content: start;
444
+ gap: 6px;
445
+ padding: 8px;
446
+ border: 1px solid #d9e1eb;
447
+ border-radius: 14px;
448
+ background: #f7f9fc;
449
+ }
450
+
451
+ .editor-file {
452
+ width: 100%;
453
+ text-align: left;
454
+ white-space: nowrap;
455
+ overflow: hidden;
456
+ text-overflow: ellipsis;
457
+ border-radius: 10px;
458
+ background: transparent;
459
+ color: #42526b;
460
+ padding: 9px 10px;
461
+ }
462
+
463
+ .editor-file.active {
464
+ background: #dfe8f5;
465
+ color: #172033;
466
+ }
467
+
468
+ .editor-main {
469
+ min-width: 0;
470
+ min-height: 0;
471
+ display: grid;
472
+ grid-template-rows: auto minmax(0, 1fr);
473
+ gap: 8px;
474
+ }
475
+
476
+ .editor-path {
477
+ padding: 10px 12px;
478
+ border-radius: 12px;
479
+ background: #f4f7fb;
480
+ color: #42526b;
481
+ font-weight: 800;
482
+ }
483
+
484
+ .editor-main textarea {
485
+ width: 100%;
486
+ height: 100%;
487
+ resize: none;
488
+ border: 1px solid #cdd7e4;
489
+ border-radius: 14px;
490
+ padding: 14px;
491
+ font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
492
+ font-size: 13px;
493
+ line-height: 1.45;
494
+ color: #102033;
495
+ background: #fbfdff;
496
+ }
497
+
498
+ .modal-actions {
499
+ color: #607089;
500
+ font-weight: 700;
501
+ }
502
+
503
+ .modal-actions > div {
504
+ display: flex;
505
+ gap: 10px;
506
+ }
507
+
508
+ @media (max-width: 860px) {
509
+ .modal-card {
510
+ height: 94vh;
511
+ }
512
+
513
+ .editor-layout {
514
+ grid-template-columns: 1fr;
515
+ grid-template-rows: minmax(120px, 220px) minmax(0, 1fr);
516
+ }
517
+
518
+ .modal-header,
519
+ .modal-actions {
520
+ align-items: stretch;
521
+ flex-direction: column;
522
+ }
523
+
524
+ .modal-actions > div {
525
+ width: 100%;
526
+ }
527
+
528
+ .modal-actions button {
529
+ flex: 1;
530
+ }
531
+ }
532
+
533
+ /* Fullscreen editor optimizations */
534
+ .modal-backdrop {
535
+ padding: 0;
536
+ place-items: stretch;
537
+ }
538
+
539
+ .modal-card.editor-modal {
540
+ width: 100vw;
541
+ height: 100vh;
542
+ max-width: none;
543
+ max-height: none;
544
+ border-radius: 0;
545
+ border: 0;
546
+ padding: 18px 24px;
547
+ grid-template-rows: auto auto auto minmax(0, 1fr) auto;
548
+ gap: 12px;
549
+ }
550
+
551
+ .editor-header {
552
+ padding-bottom: 12px;
553
+ border-bottom: 1px solid #e1e8f2;
554
+ }
555
+
556
+ .editor-title-block h2 {
557
+ font-size: 28px;
558
+ letter-spacing: 0.01em;
559
+ }
560
+
561
+ .editor-header-actions {
562
+ display: flex;
563
+ align-items: center;
564
+ gap: 10px;
565
+ flex-wrap: wrap;
566
+ }
567
+
568
+ .editor-toolbar {
569
+ display: flex;
570
+ align-items: end;
571
+ justify-content: space-between;
572
+ gap: 16px;
573
+ padding: 12px;
574
+ border: 1px solid #d9e1eb;
575
+ border-radius: 16px;
576
+ background: #f7f9fc;
577
+ }
578
+
579
+ .editor-search {
580
+ display: grid;
581
+ gap: 6px;
582
+ min-width: min(420px, 100%);
583
+ }
584
+
585
+ .editor-search span {
586
+ color: #53657d;
587
+ font-size: 13px;
588
+ font-weight: 800;
589
+ }
590
+
591
+ .editor-search input {
592
+ width: 100%;
593
+ border: 1px solid #cdd7e4;
594
+ border-radius: 12px;
595
+ padding: 10px 12px;
596
+ background: #ffffff;
597
+ }
598
+
599
+ .editor-meta {
600
+ display: flex;
601
+ align-items: center;
602
+ justify-content: flex-end;
603
+ gap: 10px;
604
+ flex-wrap: wrap;
605
+ color: #53657d;
606
+ font-weight: 800;
607
+ }
608
+
609
+ .editor-meta span {
610
+ padding: 8px 10px;
611
+ border-radius: 999px;
612
+ background: #e8eef7;
613
+ }
614
+
615
+ .editor-layout {
616
+ grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
617
+ gap: 14px;
618
+ min-height: 0;
619
+ }
620
+
621
+ .editor-file-panel {
622
+ min-height: 0;
623
+ display: grid;
624
+ grid-template-rows: auto minmax(0, 1fr);
625
+ border: 1px solid #d9e1eb;
626
+ border-radius: 16px;
627
+ background: #f7f9fc;
628
+ overflow: hidden;
629
+ }
630
+
631
+ .editor-file-panel-title {
632
+ padding: 12px 14px;
633
+ color: #42526b;
634
+ font-weight: 900;
635
+ border-bottom: 1px solid #e1e8f2;
636
+ background: #edf3fb;
637
+ }
638
+
639
+ .editor-file-list {
640
+ border: 0;
641
+ border-radius: 0;
642
+ padding: 8px;
643
+ background: transparent;
644
+ }
645
+
646
+ .editor-file {
647
+ display: grid;
648
+ gap: 3px;
649
+ padding: 10px 12px;
650
+ border: 1px solid transparent;
651
+ }
652
+
653
+ .editor-file:hover {
654
+ background: #edf3fb;
655
+ }
656
+
657
+ .editor-file.active {
658
+ border-color: #bfcede;
659
+ background: #dfe8f5;
660
+ }
661
+
662
+ .editor-file-name {
663
+ overflow: hidden;
664
+ text-overflow: ellipsis;
665
+ white-space: nowrap;
666
+ font-weight: 900;
667
+ }
668
+
669
+ .editor-file-path {
670
+ overflow: hidden;
671
+ text-overflow: ellipsis;
672
+ white-space: nowrap;
673
+ color: #6d7d93;
674
+ font-size: 12px;
675
+ font-weight: 700;
676
+ }
677
+
678
+ .editor-empty {
679
+ padding: 14px;
680
+ color: #607089;
681
+ font-weight: 700;
682
+ }
683
+
684
+ .editor-main {
685
+ border: 1px solid #d9e1eb;
686
+ border-radius: 16px;
687
+ overflow: hidden;
688
+ background: #ffffff;
689
+ gap: 0;
690
+ }
691
+
692
+ .editor-path {
693
+ display: flex;
694
+ align-items: center;
695
+ min-height: 46px;
696
+ border-radius: 0;
697
+ border-bottom: 1px solid #e1e8f2;
698
+ background: #edf3fb;
699
+ }
700
+
701
+ .editor-main textarea {
702
+ border: 0;
703
+ border-radius: 0;
704
+ padding: 18px;
705
+ font-size: 14px;
706
+ line-height: 1.55;
707
+ tab-size: 2;
708
+ outline: none;
709
+ }
710
+
711
+ .editor-main textarea:focus {
712
+ box-shadow: inset 0 0 0 2px rgba(22, 122, 60, 0.18);
713
+ }
714
+
715
+ .editor-footer {
716
+ padding-top: 12px;
717
+ border-top: 1px solid #e1e8f2;
718
+ }
719
+
720
+ @media (max-width: 920px) {
721
+ .modal-card.editor-modal {
722
+ padding: 14px;
723
+ }
724
+
725
+ .editor-toolbar,
726
+ .editor-header,
727
+ .editor-footer {
728
+ align-items: stretch;
729
+ flex-direction: column;
730
+ }
731
+
732
+ .editor-header-actions,
733
+ .editor-footer > div {
734
+ width: 100%;
735
+ }
736
+
737
+ .editor-header-actions button,
738
+ .editor-footer button {
739
+ flex: 1;
740
+ }
741
+
742
+ .editor-layout {
743
+ grid-template-columns: 1fr;
744
+ grid-template-rows: minmax(160px, 28vh) minmax(0, 1fr);
745
+ }
746
+ }
747
+
748
+ /* Editor usability refinement: full-height work area and readable file names */
749
+ .modal-card.editor-modal {
750
+ display: flex;
751
+ flex-direction: column;
752
+ min-height: 100vh;
753
+ overflow: hidden;
754
+ }
755
+
756
+ .editor-header,
757
+ .editor-toolbar,
758
+ .editor-footer,
759
+ .modal-error {
760
+ flex: 0 0 auto;
761
+ }
762
+
763
+ .editor-layout {
764
+ flex: 1 1 auto;
765
+ min-height: 0;
766
+ height: auto;
767
+ grid-template-columns: minmax(360px, 28vw) minmax(0, 1fr);
768
+ }
769
+
770
+ .editor-file-panel {
771
+ height: 100%;
772
+ min-height: 0;
773
+ }
774
+
775
+ .editor-file-list {
776
+ height: 100%;
777
+ min-height: 0;
778
+ }
779
+
780
+ .editor-file {
781
+ min-height: 62px;
782
+ align-content: center;
783
+ white-space: normal;
784
+ }
785
+
786
+ .editor-file-name {
787
+ display: block;
788
+ color: #172033;
789
+ font-size: 15px;
790
+ line-height: 1.25;
791
+ white-space: normal;
792
+ overflow-wrap: anywhere;
793
+ }
794
+
795
+ .editor-file-path {
796
+ display: block;
797
+ color: #607089;
798
+ line-height: 1.25;
799
+ white-space: normal;
800
+ overflow-wrap: anywhere;
801
+ }
802
+
803
+ .editor-main {
804
+ height: 100%;
805
+ min-height: 0;
806
+ }
807
+
808
+ .editor-path {
809
+ min-height: 52px;
810
+ padding: 12px 16px;
811
+ font-size: 15px;
812
+ overflow-wrap: anywhere;
813
+ }
814
+
815
+ .editor-path span {
816
+ overflow-wrap: anywhere;
817
+ }
818
+
819
+ .editor-main textarea {
820
+ min-height: 0;
821
+ height: 100%;
822
+ font-size: 15px;
823
+ line-height: 1.6;
824
+ overflow: auto;
825
+ white-space: pre;
826
+ }
827
+
828
+ .editor-toolbar {
829
+ padding: 10px 12px;
830
+ }
831
+
832
+ .editor-footer {
833
+ min-height: 58px;
834
+ }
835
+
836
+ @media (max-width: 920px) {
837
+ .editor-layout {
838
+ grid-template-columns: 1fr;
839
+ grid-template-rows: minmax(180px, 32vh) minmax(0, 1fr);
840
+ }
841
+ }
842
+
843
+ .project-toolbar {
844
+ display: flex;
845
+ align-items: center;
846
+ justify-content: space-between;
847
+ gap: 16px;
848
+ padding: 14px 18px;
849
+ background: #ffffff;
850
+ border: 1px solid #d9e1eb;
851
+ border-radius: 18px;
852
+ box-shadow: 0 10px 26px rgba(35, 55, 80, 0.06);
853
+ }
854
+
855
+ .project-toolbar > div,
856
+ .project-toolbar label {
857
+ display: flex;
858
+ align-items: center;
859
+ gap: 10px;
860
+ color: #53657d;
861
+ font-weight: 800;
862
+ }
863
+
864
+ .project-toolbar strong {
865
+ color: #172033;
866
+ background: #eef4fb;
867
+ border-radius: 999px;
868
+ padding: 8px 14px;
869
+ }
870
+
871
+ .project-toolbar select {
872
+ min-width: 220px;
873
+ border: 1px solid #cdd7e4;
874
+ border-radius: 12px;
875
+ padding: 10px 12px;
876
+ color: #172033;
877
+ background: #f8fafc;
878
+ font-weight: 800;
879
+ }
880
+
881
+ .project-toolbar select:disabled {
882
+ opacity: 0.55;
883
+ cursor: not-allowed;
884
+ }
885
+
886
+ @media (max-width: 760px) {
887
+ .project-toolbar,
888
+ .project-toolbar > div,
889
+ .project-toolbar label {
890
+ align-items: stretch;
891
+ flex-direction: column;
892
+ }
893
+
894
+ .project-toolbar select {
895
+ width: 100%;
896
+ min-width: 0;
897
+ }
898
+ }
899
+
900
+
901
+ /* PLC Control compact row layout */
902
+ .header p {
903
+ display: none;
904
+ }
905
+
906
+ .control-page .controls-card {
907
+ width: 100%;
908
+ display: grid;
909
+ grid-template-columns: auto minmax(0, 1fr);
910
+ align-items: end;
911
+ column-gap: 18px;
912
+ row-gap: 14px;
913
+ }
914
+
915
+ .control-page .controls-card .section-title-row {
916
+ grid-column: 1 / -1;
917
+ margin-bottom: 0;
918
+ }
919
+
920
+ .control-page .control-actions,
921
+ .control-page .cycle-settings {
922
+ min-width: 0;
923
+ flex-wrap: nowrap;
924
+ align-items: end;
925
+ }
926
+
927
+ .control-page .cycle-settings {
928
+ justify-content: flex-end;
929
+ }
930
+
931
+ .control-page .cycle-control {
932
+ min-width: 210px;
933
+ max-width: 260px;
934
+ }
935
+
936
+ @media (max-width: 1180px) {
937
+ .control-page .controls-card {
938
+ grid-template-columns: 1fr;
939
+ }
940
+
941
+ .control-page .control-actions,
942
+ .control-page .cycle-settings {
943
+ justify-content: flex-start;
944
+ flex-wrap: wrap;
945
+ }
946
+ }
947
+
948
+ @media (max-width: 760px) {
949
+ .control-page .control-actions,
950
+ .control-page .cycle-settings {
951
+ align-items: stretch;
952
+ flex-direction: column;
953
+ }
954
+
955
+ .control-page .cycle-control {
956
+ max-width: none;
957
+ }
958
+ }
959
+
960
+ .phase-window-note {
961
+ color: #657085;
962
+ font-weight: 700;
963
+ align-self: center;
964
+ }