lastriko 0.1.0 → 0.1.2

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.
@@ -63,19 +63,19 @@ body {
63
63
  padding: 1.25rem;
64
64
  }
65
65
 
66
- /* App body: padded column, centered, comfortable spacing (Phase 1 default shell). */
66
+ /* App root: full-width column (shell + wide demos need horizontal space). */
67
67
  .lk-page {
68
68
  box-sizing: border-box;
69
- max-width: 40rem;
69
+ max-width: 100%;
70
70
  width: 100%;
71
- margin: 0 auto;
72
- padding: 2rem 1.5rem 3rem;
71
+ margin: 0;
72
+ padding: 1.25rem 1.5rem 2.5rem;
73
73
  display: flex;
74
74
  flex-direction: column;
75
75
  gap: 1.25rem;
76
76
  align-items: stretch;
77
77
  min-height: calc(100vh - 3.5rem);
78
- justify-content: center;
78
+ justify-content: flex-start;
79
79
  }
80
80
 
81
81
  .lk-stack {
@@ -132,3 +132,652 @@ body {
132
132
  min-width: 220px;
133
133
  box-shadow: var(--lk-shadow);
134
134
  }
135
+
136
+ /* —— Layout: shell, grid —— */
137
+ .lk-shell {
138
+ display: grid;
139
+ grid-template-columns: var(--lk-sidebar-width, 260px) minmax(0, 1fr);
140
+ grid-template-rows: auto 1fr auto;
141
+ grid-template-areas:
142
+ 'header header'
143
+ 'sidebar main'
144
+ 'footer footer';
145
+ gap: 0 1.25rem;
146
+ width: 100%;
147
+ align-items: start;
148
+ }
149
+
150
+ .lk-shell--sidebar-right {
151
+ grid-template-columns: minmax(0, 1fr) var(--lk-sidebar-width, 260px);
152
+ grid-template-areas:
153
+ 'header header'
154
+ 'main sidebar'
155
+ 'footer footer';
156
+ }
157
+
158
+ .lk-shell-header {
159
+ grid-area: header;
160
+ display: flex;
161
+ flex-wrap: wrap;
162
+ gap: 0.5rem 0.75rem;
163
+ align-items: center;
164
+ padding: 0.75rem 0;
165
+ border-bottom: 1px solid var(--lk-border);
166
+ margin-bottom: 0.5rem;
167
+ }
168
+
169
+ .lk-shell-sidebar {
170
+ grid-area: sidebar;
171
+ position: sticky;
172
+ top: 3.75rem;
173
+ align-self: start;
174
+ max-height: calc(100vh - 5rem);
175
+ overflow: auto;
176
+ padding: 0.5rem 0.75rem 1rem 0;
177
+ border-right: 1px solid var(--lk-border);
178
+ display: flex;
179
+ flex-direction: column;
180
+ gap: 0.85rem;
181
+ background: var(--lk-surface-2);
182
+ border-radius: var(--lk-radius);
183
+ }
184
+
185
+ .lk-shell--sidebar-right .lk-shell-sidebar {
186
+ border-right: none;
187
+ border-left: 1px solid var(--lk-border);
188
+ padding: 0.5rem 0 1rem 0.75rem;
189
+ }
190
+
191
+ .lk-shell-main {
192
+ grid-area: main;
193
+ min-width: 0;
194
+ display: flex;
195
+ flex-direction: column;
196
+ gap: 1rem;
197
+ padding: 0.25rem 0 1.5rem;
198
+ }
199
+
200
+ .lk-shell-footer {
201
+ grid-area: footer;
202
+ padding: 1rem 0 0;
203
+ margin-top: 0.5rem;
204
+ border-top: 1px solid var(--lk-border);
205
+ display: flex;
206
+ flex-direction: column;
207
+ gap: 0.75rem;
208
+ }
209
+
210
+ @media (max-width: 900px) {
211
+ .lk-shell,
212
+ .lk-shell--sidebar-right {
213
+ grid-template-columns: 1fr;
214
+ grid-template-areas:
215
+ 'header'
216
+ 'sidebar'
217
+ 'main'
218
+ 'footer';
219
+ }
220
+
221
+ .lk-shell-sidebar {
222
+ position: static;
223
+ max-height: none;
224
+ border-right: none;
225
+ border-left: none;
226
+ border-bottom: 1px solid var(--lk-border);
227
+ padding-bottom: 1rem;
228
+ }
229
+ }
230
+
231
+ .lk-grid {
232
+ width: 100%;
233
+ }
234
+
235
+ .lk-grid-cell {
236
+ min-width: 0;
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 0.5rem;
240
+ }
241
+
242
+ /* —— Forms —— */
243
+ .lk-field {
244
+ display: flex;
245
+ flex-direction: column;
246
+ gap: 0.35rem;
247
+ align-items: stretch;
248
+ }
249
+
250
+ .lk-label {
251
+ font-size: 0.8125rem;
252
+ font-weight: 600;
253
+ color: var(--lk-muted);
254
+ }
255
+
256
+ .lk-helper {
257
+ font-size: 0.75rem;
258
+ color: var(--lk-muted);
259
+ }
260
+
261
+ .lk-field input[type='text'],
262
+ .lk-field input[type='number'],
263
+ .lk-field input[type='range'],
264
+ .lk-field input[type='file'],
265
+ .lk-field select,
266
+ .lk-field textarea {
267
+ font: inherit;
268
+ color: var(--lk-text);
269
+ background: var(--lk-surface);
270
+ border: 1px solid var(--lk-border);
271
+ border-radius: 8px;
272
+ padding: 0.45rem 0.6rem;
273
+ max-width: 100%;
274
+ }
275
+
276
+ .lk-field textarea {
277
+ min-height: 4.5rem;
278
+ resize: vertical;
279
+ }
280
+
281
+ .lk-slider-row {
282
+ display: flex;
283
+ align-items: center;
284
+ gap: 0.75rem;
285
+ }
286
+
287
+ .lk-slider-row input[type='range'] {
288
+ flex: 1;
289
+ }
290
+
291
+ .lk-slider-value {
292
+ font-variant-numeric: tabular-nums;
293
+ font-size: 0.875rem;
294
+ color: var(--lk-muted);
295
+ min-width: 2.5rem;
296
+ }
297
+
298
+ .lk-field--toggle .lk-toggle-wrap {
299
+ display: inline-flex;
300
+ align-items: center;
301
+ gap: 0.5rem;
302
+ cursor: pointer;
303
+ }
304
+
305
+ .lk-toggle-wrap input {
306
+ position: absolute;
307
+ opacity: 0;
308
+ width: 0;
309
+ height: 0;
310
+ }
311
+
312
+ .lk-toggle {
313
+ width: 2.5rem;
314
+ height: 1.35rem;
315
+ border-radius: 999px;
316
+ background: var(--lk-border);
317
+ position: relative;
318
+ transition: background 0.15s;
319
+ }
320
+
321
+ .lk-toggle::after {
322
+ content: '';
323
+ position: absolute;
324
+ top: 2px;
325
+ left: 2px;
326
+ width: calc(1.35rem - 4px);
327
+ height: calc(1.35rem - 4px);
328
+ border-radius: 50%;
329
+ background: var(--lk-surface);
330
+ transition: transform 0.15s;
331
+ }
332
+
333
+ .lk-toggle-wrap input:checked + .lk-toggle {
334
+ background: var(--lk-primary);
335
+ }
336
+
337
+ .lk-toggle-wrap input:checked + .lk-toggle::after {
338
+ transform: translateX(1.1rem);
339
+ }
340
+
341
+ .lk-file-upload-value {
342
+ font-size: 0.8125rem;
343
+ color: var(--lk-muted);
344
+ }
345
+
346
+ .lk-meta {
347
+ font-size: 0.75rem;
348
+ color: var(--lk-muted);
349
+ }
350
+
351
+ /* —— Markdown & prose —— */
352
+ .lk-markdown {
353
+ font-size: 1rem;
354
+ line-height: 1.55;
355
+ color: var(--lk-text);
356
+ }
357
+
358
+ .lk-markdown :first-child {
359
+ margin-top: 0;
360
+ }
361
+
362
+ .lk-markdown :last-child {
363
+ margin-bottom: 0;
364
+ }
365
+
366
+ .lk-markdown h1,
367
+ .lk-markdown h2,
368
+ .lk-markdown h3 {
369
+ margin: 0.75rem 0 0.4rem;
370
+ line-height: 1.25;
371
+ }
372
+
373
+ .lk-markdown p {
374
+ margin: 0.5rem 0;
375
+ }
376
+
377
+ .lk-markdown a {
378
+ color: var(--lk-primary);
379
+ }
380
+
381
+ .lk-markdown code {
382
+ font-size: 0.9em;
383
+ padding: 0.1em 0.35em;
384
+ border-radius: 4px;
385
+ background: var(--lk-surface-2);
386
+ }
387
+
388
+ .lk-markdown pre {
389
+ overflow: auto;
390
+ padding: 0.65rem 0.85rem;
391
+ border-radius: 8px;
392
+ background: var(--lk-surface-2);
393
+ border: 1px solid var(--lk-border);
394
+ }
395
+
396
+ .lk-markdown pre code {
397
+ padding: 0;
398
+ background: none;
399
+ }
400
+
401
+ /* —— Code & JSON —— */
402
+ .lk-code {
403
+ margin: 0;
404
+ padding: 0.75rem 1rem;
405
+ border-radius: 8px;
406
+ background: var(--lk-surface-2);
407
+ border: 1px solid var(--lk-border);
408
+ overflow: auto;
409
+ font-size: 0.875rem;
410
+ }
411
+
412
+ .lk-json {
413
+ border: 1px solid var(--lk-border);
414
+ border-radius: var(--lk-radius);
415
+ background: var(--lk-surface);
416
+ padding: 0.65rem 0.85rem;
417
+ }
418
+
419
+ .lk-json-label {
420
+ font-size: 0.75rem;
421
+ font-weight: 600;
422
+ color: var(--lk-muted);
423
+ margin-bottom: 0.35rem;
424
+ }
425
+
426
+ .lk-json pre {
427
+ margin: 0;
428
+ font-size: 0.8125rem;
429
+ overflow: auto;
430
+ }
431
+
432
+ /* —— Table —— */
433
+ .lk-table-wrap {
434
+ border: 1px solid var(--lk-border);
435
+ border-radius: var(--lk-radius);
436
+ background: var(--lk-surface);
437
+ }
438
+
439
+ .lk-table {
440
+ width: 100%;
441
+ border-collapse: collapse;
442
+ font-size: 0.9375rem;
443
+ }
444
+
445
+ .lk-table th,
446
+ .lk-table td {
447
+ padding: 0.5rem 0.75rem;
448
+ text-align: left;
449
+ border-bottom: 1px solid var(--lk-border);
450
+ }
451
+
452
+ .lk-table th {
453
+ font-weight: 600;
454
+ color: var(--lk-muted);
455
+ font-size: 0.8125rem;
456
+ background: var(--lk-surface-2);
457
+ }
458
+
459
+ .lk-table--striped tbody tr:nth-child(even) {
460
+ background: var(--lk-surface-2);
461
+ }
462
+
463
+ .lk-table tbody tr {
464
+ cursor: pointer;
465
+ }
466
+
467
+ .lk-table tbody tr:hover {
468
+ filter: brightness(0.97);
469
+ }
470
+
471
+ [data-theme='dark'] .lk-table tbody tr:hover {
472
+ filter: brightness(1.08);
473
+ }
474
+
475
+ /* —— Metric & progress —— */
476
+ .lk-metric {
477
+ padding: 0.65rem 0.85rem;
478
+ border: 1px solid var(--lk-border);
479
+ border-radius: var(--lk-radius);
480
+ background: var(--lk-surface);
481
+ }
482
+
483
+ .lk-metric-label {
484
+ font-size: 0.75rem;
485
+ font-weight: 600;
486
+ color: var(--lk-muted);
487
+ }
488
+
489
+ .lk-metric-value {
490
+ font-size: 1.35rem;
491
+ font-weight: 700;
492
+ font-variant-numeric: tabular-nums;
493
+ }
494
+
495
+ .lk-metric-delta {
496
+ font-size: 0.8125rem;
497
+ color: var(--lk-muted);
498
+ margin-top: 0.25rem;
499
+ }
500
+
501
+ .lk-progress {
502
+ padding: 0.5rem 0;
503
+ }
504
+
505
+ .lk-progress-label {
506
+ font-size: 0.8125rem;
507
+ margin-bottom: 0.35rem;
508
+ color: var(--lk-muted);
509
+ }
510
+
511
+ .lk-progress-bar {
512
+ height: 8px;
513
+ border-radius: 999px;
514
+ background: var(--lk-surface-2);
515
+ overflow: hidden;
516
+ }
517
+
518
+ .lk-progress-bar > span {
519
+ display: block;
520
+ height: 100%;
521
+ border-radius: 999px;
522
+ background: var(--lk-primary);
523
+ transition: width 0.2s ease;
524
+ }
525
+
526
+ .lk-progress-pct {
527
+ font-size: 0.75rem;
528
+ color: var(--lk-muted);
529
+ margin-top: 0.25rem;
530
+ }
531
+
532
+ .lk-progress--indeterminate {
533
+ display: flex;
534
+ align-items: center;
535
+ gap: 0.65rem;
536
+ font-size: 0.875rem;
537
+ color: var(--lk-muted);
538
+ }
539
+
540
+ /* —— Images —— */
541
+ .lk-image {
542
+ margin: 0;
543
+ max-width: 100%;
544
+ }
545
+
546
+ .lk-image img {
547
+ max-width: 100%;
548
+ height: auto;
549
+ border-radius: 8px;
550
+ display: block;
551
+ }
552
+
553
+ .lk-image figcaption {
554
+ font-size: 0.8125rem;
555
+ color: var(--lk-muted);
556
+ margin-top: 0.35rem;
557
+ }
558
+
559
+ .lk-image--empty .lk-image-placeholder {
560
+ padding: 2rem;
561
+ text-align: center;
562
+ border: 1px dashed var(--lk-border);
563
+ border-radius: var(--lk-radius);
564
+ color: var(--lk-muted);
565
+ }
566
+
567
+ .lk-image-grid figure {
568
+ margin: 0;
569
+ }
570
+
571
+ .lk-image-grid img {
572
+ width: 100%;
573
+ height: auto;
574
+ border-radius: 6px;
575
+ display: block;
576
+ }
577
+
578
+ /* —— Tabs —— */
579
+ .lk-tabs {
580
+ border: 1px solid var(--lk-border);
581
+ border-radius: var(--lk-radius);
582
+ background: var(--lk-surface);
583
+ overflow: hidden;
584
+ }
585
+
586
+ .lk-tab-nav {
587
+ display: flex;
588
+ flex-wrap: wrap;
589
+ gap: 0.25rem;
590
+ padding: 0.5rem;
591
+ border-bottom: 1px solid var(--lk-border);
592
+ background: var(--lk-surface-2);
593
+ }
594
+
595
+ .lk-tab {
596
+ border: 1px solid transparent;
597
+ border-radius: 8px;
598
+ padding: 0.4rem 0.85rem;
599
+ font: inherit;
600
+ font-weight: 600;
601
+ font-size: 0.875rem;
602
+ cursor: pointer;
603
+ background: transparent;
604
+ color: var(--lk-muted);
605
+ }
606
+
607
+ .lk-tab.is-active {
608
+ background: var(--lk-surface);
609
+ color: var(--lk-text);
610
+ border-color: var(--lk-border);
611
+ }
612
+
613
+ .lk-tab:disabled {
614
+ opacity: 0.45;
615
+ cursor: not-allowed;
616
+ }
617
+
618
+ .lk-tab-panel {
619
+ padding: 0.85rem 1rem 1rem;
620
+ display: flex;
621
+ flex-direction: column;
622
+ gap: 0.75rem;
623
+ }
624
+
625
+ .lk-tab-panel[hidden] {
626
+ display: none !important;
627
+ }
628
+
629
+ /* —— Card title —— */
630
+ .lk-card-title {
631
+ font-weight: 700;
632
+ font-size: 1rem;
633
+ margin: 0 0 0.65rem;
634
+ padding-bottom: 0.5rem;
635
+ border-bottom: 1px solid var(--lk-border);
636
+ }
637
+
638
+ /* —— Divider & spacer —— */
639
+ .lk-divider {
640
+ border: none;
641
+ border-top: 1px solid var(--lk-border);
642
+ margin: 0.5rem 0;
643
+ }
644
+
645
+ div.lk-divider {
646
+ display: flex;
647
+ align-items: center;
648
+ gap: 0.75rem;
649
+ border: none;
650
+ margin: 0.75rem 0;
651
+ }
652
+
653
+ div.lk-divider::before,
654
+ div.lk-divider::after {
655
+ content: '';
656
+ flex: 1;
657
+ height: 1px;
658
+ background: var(--lk-border);
659
+ }
660
+
661
+ div.lk-divider span {
662
+ font-size: 0.75rem;
663
+ color: var(--lk-muted);
664
+ white-space: nowrap;
665
+ }
666
+
667
+ /* —— Alert & loading —— */
668
+ .lk-alert {
669
+ padding: 0.65rem 0.85rem;
670
+ border-radius: var(--lk-radius);
671
+ border: 1px solid var(--lk-border);
672
+ font-size: 0.9375rem;
673
+ }
674
+
675
+ .lk-alert-title {
676
+ font-weight: 700;
677
+ margin-bottom: 0.25rem;
678
+ }
679
+
680
+ .lk-alert--info {
681
+ background: color-mix(in srgb, var(--lk-primary) 12%, var(--lk-surface));
682
+ }
683
+
684
+ .lk-alert--success {
685
+ background: color-mix(in srgb, #10b981 14%, var(--lk-surface));
686
+ }
687
+
688
+ .lk-alert--warning {
689
+ background: color-mix(in srgb, #f59e0b 14%, var(--lk-surface));
690
+ }
691
+
692
+ .lk-alert--error {
693
+ background: color-mix(in srgb, #ef4444 14%, var(--lk-surface));
694
+ }
695
+
696
+ .lk-loading {
697
+ display: inline-flex;
698
+ align-items: center;
699
+ gap: 0.5rem;
700
+ font-size: 0.875rem;
701
+ color: var(--lk-muted);
702
+ }
703
+
704
+ .lk-spinner {
705
+ width: 1rem;
706
+ height: 1rem;
707
+ border: 2px solid var(--lk-border);
708
+ border-top-color: var(--lk-primary);
709
+ border-radius: 50%;
710
+ animation: lk-spin 0.7s linear infinite;
711
+ }
712
+
713
+ @keyframes lk-spin {
714
+ to {
715
+ transform: rotate(360deg);
716
+ }
717
+ }
718
+
719
+ /* —— Stream & chat —— */
720
+ .lk-stream {
721
+ border: 1px solid var(--lk-border);
722
+ border-radius: var(--lk-radius);
723
+ padding: 0.65rem 0.85rem;
724
+ background: var(--lk-surface);
725
+ min-height: 4rem;
726
+ }
727
+
728
+ .lk-stream-body {
729
+ font-size: 0.9375rem;
730
+ white-space: pre-wrap;
731
+ word-break: break-word;
732
+ }
733
+
734
+ .lk-stream-cursor {
735
+ opacity: 0.7;
736
+ animation: lk-blink 1s step-end infinite;
737
+ }
738
+
739
+ @keyframes lk-blink {
740
+ 50% {
741
+ opacity: 0;
742
+ }
743
+ }
744
+
745
+ .lk-chat {
746
+ border: 1px solid var(--lk-border);
747
+ border-radius: var(--lk-radius);
748
+ background: var(--lk-surface);
749
+ overflow: hidden;
750
+ }
751
+
752
+ .lk-chat-history {
753
+ max-height: 280px;
754
+ overflow: auto;
755
+ padding: 0.65rem 0.85rem;
756
+ display: flex;
757
+ flex-direction: column;
758
+ gap: 0.65rem;
759
+ }
760
+
761
+ .lk-chat-msg {
762
+ padding: 0.45rem 0.65rem;
763
+ border-radius: 8px;
764
+ background: var(--lk-surface-2);
765
+ }
766
+
767
+ .lk-chat-msg--assistant {
768
+ border-left: 3px solid var(--lk-primary);
769
+ }
770
+
771
+ .lk-chat-role {
772
+ font-size: 0.6875rem;
773
+ font-weight: 700;
774
+ text-transform: uppercase;
775
+ color: var(--lk-muted);
776
+ display: block;
777
+ margin-bottom: 0.2rem;
778
+ }
779
+
780
+ .lk-chat-msg p {
781
+ margin: 0;
782
+ font-size: 0.9rem;
783
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lastriko",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TypeScript UI toolkit for AI demos and rapid prototyping (server-rendered HTML + WebSocket).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -51,10 +51,13 @@
51
51
  "check:bundle": "node ../../scripts/check-client-size.mjs"
52
52
  },
53
53
  "dependencies": {
54
+ "marked": "^18.0.0",
54
55
  "nanostores": "^1.1.0",
56
+ "sanitize-html": "^2.17.2",
55
57
  "ws": "^8.20.0"
56
58
  },
57
59
  "devDependencies": {
60
+ "@types/sanitize-html": "^2.16.1",
58
61
  "@types/ws": "^8.18.1"
59
62
  }
60
63
  }