@kywi-software/core 0.6.6 → 0.7.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 (102) hide show
  1. package/AGENT-PATTERNS.md +58 -2
  2. package/dist/admin/registry.d.ts +2 -2
  3. package/dist/admin/registry.d.ts.map +1 -1
  4. package/dist/admin/registry.js +41 -19
  5. package/dist/admin/registry.js.map +1 -1
  6. package/dist/admin/styles/admin.css +130 -0
  7. package/dist/admin/surfaces/menus/menu-editor.d.ts +3 -0
  8. package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -0
  9. package/dist/admin/surfaces/menus/menu-editor.js +260 -0
  10. package/dist/admin/surfaces/menus/menu-editor.js.map +1 -0
  11. package/dist/admin/surfaces/menus/menu-tree.d.ts +123 -0
  12. package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -0
  13. package/dist/admin/surfaces/menus/menu-tree.js +292 -0
  14. package/dist/admin/surfaces/menus/menu-tree.js.map +1 -0
  15. package/dist/admin/surfaces/menus/menus-data.d.ts +101 -0
  16. package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -0
  17. package/dist/admin/surfaces/menus/menus-data.js +98 -0
  18. package/dist/admin/surfaces/menus/menus-data.js.map +1 -0
  19. package/dist/admin/surfaces/menus/menus-list.d.ts +3 -0
  20. package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -0
  21. package/dist/admin/surfaces/menus/menus-list.js +105 -0
  22. package/dist/admin/surfaces/menus/menus-list.js.map +1 -0
  23. package/dist/admin/surfaces/menus/page-picker.d.ts +10 -0
  24. package/dist/admin/surfaces/menus/page-picker.d.ts.map +1 -0
  25. package/dist/admin/surfaces/menus/page-picker.js +38 -0
  26. package/dist/admin/surfaces/menus/page-picker.js.map +1 -0
  27. package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
  28. package/dist/admin/surfaces/settings/admin-features.js +1 -0
  29. package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
  30. package/dist/api/feed-routes.d.ts +2 -2
  31. package/dist/api/index.d.ts +1 -0
  32. package/dist/api/index.d.ts.map +1 -1
  33. package/dist/api/index.js +5 -0
  34. package/dist/api/index.js.map +1 -1
  35. package/dist/api/menu-routes.d.ts +46 -0
  36. package/dist/api/menu-routes.d.ts.map +1 -0
  37. package/dist/api/menu-routes.js +247 -0
  38. package/dist/api/menu-routes.js.map +1 -0
  39. package/dist/api/openapi.d.ts.map +1 -1
  40. package/dist/api/openapi.js +105 -0
  41. package/dist/api/openapi.js.map +1 -1
  42. package/dist/cache/cached-queries.d.ts +22 -0
  43. package/dist/cache/cached-queries.d.ts.map +1 -1
  44. package/dist/cache/cached-queries.js +31 -1
  45. package/dist/cache/cached-queries.js.map +1 -1
  46. package/dist/cache/keys.d.ts +2 -0
  47. package/dist/cache/keys.d.ts.map +1 -1
  48. package/dist/cache/keys.js +4 -0
  49. package/dist/cache/keys.js.map +1 -1
  50. package/dist/db/index.d.ts +1 -0
  51. package/dist/db/index.d.ts.map +1 -1
  52. package/dist/db/index.js +1 -0
  53. package/dist/db/index.js.map +1 -1
  54. package/dist/db/menu-queries.d.ts +182 -0
  55. package/dist/db/menu-queries.d.ts.map +1 -0
  56. package/dist/db/menu-queries.js +326 -0
  57. package/dist/db/menu-queries.js.map +1 -0
  58. package/dist/layout/index.d.ts +1 -0
  59. package/dist/layout/index.d.ts.map +1 -1
  60. package/dist/layout/index.js +1 -0
  61. package/dist/layout/index.js.map +1 -1
  62. package/dist/layout/modules-extended.d.ts +32 -2
  63. package/dist/layout/modules-extended.d.ts.map +1 -1
  64. package/dist/layout/modules-extended.js +159 -39
  65. package/dist/layout/modules-extended.js.map +1 -1
  66. package/dist/layout/nav-hydration.d.ts +62 -0
  67. package/dist/layout/nav-hydration.d.ts.map +1 -0
  68. package/dist/layout/nav-hydration.js +149 -0
  69. package/dist/layout/nav-hydration.js.map +1 -0
  70. package/dist/layout/registry.d.ts +0 -26
  71. package/dist/layout/registry.d.ts.map +1 -1
  72. package/dist/layout/registry.js +22 -8
  73. package/dist/layout/registry.js.map +1 -1
  74. package/dist/nav/builder.d.ts +16 -0
  75. package/dist/nav/builder.d.ts.map +1 -1
  76. package/dist/nav/builder.js +21 -2
  77. package/dist/nav/builder.js.map +1 -1
  78. package/dist/nav/index.d.ts +1 -0
  79. package/dist/nav/index.d.ts.map +1 -1
  80. package/dist/nav/index.js +1 -0
  81. package/dist/nav/index.js.map +1 -1
  82. package/dist/nav/menu-resolver.d.ts +52 -0
  83. package/dist/nav/menu-resolver.d.ts.map +1 -0
  84. package/dist/nav/menu-resolver.js +113 -0
  85. package/dist/nav/menu-resolver.js.map +1 -0
  86. package/dist/nav/types.d.ts +30 -0
  87. package/dist/nav/types.d.ts.map +1 -1
  88. package/dist/schema/base.d.ts +331 -0
  89. package/dist/schema/base.d.ts.map +1 -1
  90. package/dist/schema/base.js +45 -0
  91. package/dist/schema/base.js.map +1 -1
  92. package/dist/schema/mysql-tables.d.ts +303 -0
  93. package/dist/schema/mysql-tables.d.ts.map +1 -1
  94. package/dist/schema/mysql-tables.js +25 -0
  95. package/dist/schema/mysql-tables.js.map +1 -1
  96. package/dist/scope/create-scope.d.ts.map +1 -1
  97. package/dist/scope/create-scope.js +27 -1
  98. package/dist/scope/create-scope.js.map +1 -1
  99. package/dist/scope/types.d.ts +28 -1
  100. package/dist/scope/types.d.ts.map +1 -1
  101. package/dist/site/styles.css +387 -3
  102. package/package.json +1 -1
@@ -315,6 +315,386 @@
315
315
  color: #065f46;
316
316
  }
317
317
 
318
+ /* ── Navigation (navMenu / navigation / breadcrumbs / siteMap) ───────────────
319
+ * Root markup:
320
+ * <nav class="kywi-nav kywi-nav--{variant}" data-kywi-nav data-kywi-nav-variant>
321
+ * <details class="kywi-nav-mobile"><summary>…</summary></details>
322
+ * <ul class="kywi-nav-list kywi-nav-list--level-1">
323
+ * <li class="kywi-nav-item kywi-nav-item--has-children">
324
+ * <a class="kywi-nav-link">…</a>
325
+ * <button class="kywi-nav-toggle" aria-expanded>…</button>
326
+ * <div class="kywi-nav-panel">…</div>
327
+ *
328
+ * BREAKPOINT — one constant, 860px. A media query cannot read a custom
329
+ * property, so the literal below (859.98px, the last step before 860) is the
330
+ * ONLY place it appears in this file; kywi.js switches hover/keyboard behaviour
331
+ * at the matching `(min-width: 860px)`. Everything else — spacing, colour,
332
+ * radius, panel width — is a `--kywi-*` token with a neutral fallback, and the
333
+ * per-nav knobs are re-exposed as `--kywi-nav-*` so a theme can retune one nav
334
+ * without rewriting these rules.
335
+ *
336
+ * Panels open three ways so the nav works with JS off: `.kywi-nav-item--open`
337
+ * (kywi.js), `:hover`, and `:focus-within` (keyboard). Closed panels stay in the
338
+ * tab order — that is what makes the focus fallback reachable without JS.
339
+ *
340
+ * Every selector is rooted at `[data-kywi-nav-variant]` deliberately: the bare
341
+ * `.kywi-nav` / `.kywi-nav-item` / `.kywi-nav-link` classes are also used by the
342
+ * KywiNav scope helper and the admin sidebar, and neither should inherit this. */
343
+
344
+ .kywi-nav[data-kywi-nav-variant] {
345
+ --_kywi-nav-gap: var(--kywi-nav-gap, var(--kywi-spacing-md, 1rem));
346
+ --_kywi-nav-pad-y: var(--kywi-nav-link-padding-y, var(--kywi-spacing-sm, 0.5rem));
347
+ --_kywi-nav-pad-x: var(--kywi-nav-link-padding-x, var(--kywi-spacing-sm, 0.5rem));
348
+ --_kywi-nav-text: var(--kywi-nav-color, var(--kywi-color-text, #0f172a));
349
+ --_kywi-nav-muted: var(--kywi-color-muted, #64748b);
350
+ --_kywi-nav-accent: var(--kywi-nav-color-active, var(--kywi-color-primary, #2563eb));
351
+ --_kywi-nav-surface: var(--kywi-nav-panel-background, var(--kywi-color-background, #ffffff));
352
+ --_kywi-nav-border: var(--kywi-color-border, #e2e8f0);
353
+ --_kywi-nav-radius: var(--kywi-border-radius-md, 10px);
354
+ --_kywi-nav-shadow: var(--kywi-nav-panel-shadow, 0 12px 32px rgba(15, 23, 42, 0.14));
355
+ --_kywi-nav-panel-width: var(--kywi-nav-panel-width, 15rem);
356
+ position: relative;
357
+ font-family: var(--kywi-font-family-base, inherit);
358
+ color: var(--_kywi-nav-text);
359
+ }
360
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-list {
361
+ list-style: none;
362
+ margin: 0;
363
+ padding: 0;
364
+ }
365
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-link,
366
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-label {
367
+ display: block;
368
+ padding: var(--_kywi-nav-pad-y) var(--_kywi-nav-pad-x);
369
+ color: inherit;
370
+ text-decoration: none;
371
+ border-radius: var(--kywi-border-radius-sm, 6px);
372
+ }
373
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-label { color: var(--_kywi-nav-muted); }
374
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-link:hover { color: var(--_kywi-nav-accent); }
375
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-link:focus-visible,
376
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-toggle:focus-visible,
377
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile-toggle:focus-visible {
378
+ outline: 2px solid var(--_kywi-nav-accent);
379
+ outline-offset: 2px;
380
+ }
381
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item--active > .kywi-nav-link {
382
+ color: var(--_kywi-nav-accent);
383
+ font-weight: 600;
384
+ }
385
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item--ancestor > .kywi-nav-link { font-weight: 600; }
386
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-description {
387
+ display: block;
388
+ padding: 0 var(--_kywi-nav-pad-x) var(--_kywi-nav-pad-y);
389
+ margin-top: calc(-1 * var(--kywi-spacing-xs, 0.25rem));
390
+ font-size: 0.82rem;
391
+ line-height: 1.45;
392
+ color: var(--_kywi-nav-muted);
393
+ }
394
+
395
+ /* Disclosure trigger — sits beside the link, never replaces it. */
396
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-toggle {
397
+ display: inline-flex;
398
+ align-items: center;
399
+ justify-content: center;
400
+ width: 1.6rem;
401
+ height: 1.6rem;
402
+ padding: 0;
403
+ font: inherit;
404
+ color: inherit;
405
+ cursor: pointer;
406
+ background: none;
407
+ border: 0;
408
+ border-radius: var(--kywi-border-radius-sm, 6px);
409
+ }
410
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-chevron {
411
+ width: 0.4rem;
412
+ height: 0.4rem;
413
+ border-right: 2px solid currentColor;
414
+ border-bottom: 2px solid currentColor;
415
+ transform: translateY(-0.1rem) rotate(45deg);
416
+ transition: transform 140ms ease;
417
+ }
418
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item--open > .kywi-nav-toggle .kywi-nav-chevron {
419
+ transform: translateY(0.05rem) rotate(-135deg);
420
+ }
421
+
422
+ /* Panels — hidden but focusable (see header note), revealed by class, hover or
423
+ * focus-within. */
424
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-panel {
425
+ position: absolute;
426
+ z-index: 40;
427
+ min-width: var(--_kywi-nav-panel-width);
428
+ padding: var(--kywi-spacing-sm, 0.5rem);
429
+ background: var(--_kywi-nav-surface);
430
+ border: 1px solid var(--_kywi-nav-border);
431
+ border-radius: var(--_kywi-nav-radius);
432
+ box-shadow: var(--_kywi-nav-shadow);
433
+ opacity: 0;
434
+ pointer-events: none;
435
+ transform: translateY(-0.35rem);
436
+ transition: opacity 140ms ease, transform 140ms ease;
437
+ }
438
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item--open > .kywi-nav-panel,
439
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item:hover > .kywi-nav-panel,
440
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item:focus-within > .kywi-nav-panel {
441
+ opacity: 1;
442
+ pointer-events: auto;
443
+ transform: none;
444
+ }
445
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-panel .kywi-nav-list--level-3 {
446
+ padding-left: var(--kywi-spacing-sm, 0.5rem);
447
+ }
448
+
449
+ /* Horizontal bar. */
450
+ .kywi-nav--horizontal .kywi-nav-list--level-1 {
451
+ display: flex;
452
+ flex-wrap: wrap;
453
+ align-items: center;
454
+ gap: var(--_kywi-nav-gap);
455
+ }
456
+ .kywi-nav--horizontal .kywi-nav-item,
457
+ .kywi-nav--vertical .kywi-nav-item { position: relative; }
458
+ .kywi-nav--horizontal .kywi-nav-item--has-children,
459
+ .kywi-nav--mega .kywi-nav-item--has-children {
460
+ display: flex;
461
+ align-items: center;
462
+ gap: calc(var(--kywi-spacing-xs, 0.25rem) / 2);
463
+ }
464
+ .kywi-nav--horizontal .kywi-nav-panel {
465
+ top: 100%;
466
+ left: 0;
467
+ margin-top: var(--kywi-spacing-xs, 0.25rem);
468
+ }
469
+ .kywi-nav--horizontal .kywi-nav-panel--flip { left: auto; right: 0; }
470
+
471
+ /* Mega — one full-width panel measured against the nav, not the item. */
472
+ .kywi-nav--mega .kywi-nav-list--level-1 {
473
+ display: flex;
474
+ flex-wrap: wrap;
475
+ align-items: center;
476
+ gap: var(--_kywi-nav-gap);
477
+ }
478
+ .kywi-nav--mega .kywi-nav-item { position: static; }
479
+ .kywi-nav--mega .kywi-nav-panel--mega {
480
+ top: 100%;
481
+ left: 0;
482
+ right: 0;
483
+ margin-top: var(--kywi-spacing-xs, 0.25rem);
484
+ padding: var(--kywi-spacing-lg, 1.5rem);
485
+ }
486
+ .kywi-nav-mega-inner {
487
+ max-width: var(--kywi-nav-mega-max-width, 1100px);
488
+ margin: 0 auto;
489
+ }
490
+ .kywi-nav-mega-intro {
491
+ margin: 0 0 var(--kywi-spacing-md, 1rem);
492
+ color: var(--_kywi-nav-muted);
493
+ font-size: 0.9rem;
494
+ }
495
+ .kywi-nav-mega-columns {
496
+ display: grid;
497
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
498
+ gap: var(--kywi-spacing-lg, 1.5rem);
499
+ }
500
+ .kywi-nav-mega-heading {
501
+ margin: 0 0 var(--kywi-spacing-xs, 0.25rem);
502
+ font-family: var(--kywi-font-family-heading, var(--kywi-font-family-base, inherit));
503
+ font-size: 0.78rem;
504
+ font-weight: 700;
505
+ letter-spacing: 0.05em;
506
+ text-transform: uppercase;
507
+ color: var(--_kywi-nav-muted);
508
+ }
509
+ .kywi-nav-mega-heading .kywi-nav-link,
510
+ .kywi-nav-mega-heading .kywi-nav-label { padding-left: 0; padding-right: 0; }
511
+ .kywi-nav-mega-description {
512
+ margin: 0 0 var(--kywi-spacing-sm, 0.5rem);
513
+ font-size: 0.85rem;
514
+ color: var(--_kywi-nav-muted);
515
+ }
516
+ .kywi-nav-mega-column .kywi-nav-link { padding-left: 0; }
517
+ .kywi-nav-mega-column .kywi-nav-description { padding-left: 0; }
518
+
519
+ /* Vertical side nav — panels fly out to the right. */
520
+ .kywi-nav--vertical .kywi-nav-list--level-1 {
521
+ display: flex;
522
+ flex-direction: column;
523
+ gap: calc(var(--_kywi-nav-gap) / 4);
524
+ }
525
+ .kywi-nav--vertical .kywi-nav-item--has-children {
526
+ display: grid;
527
+ grid-template-columns: 1fr auto;
528
+ align-items: center;
529
+ }
530
+ .kywi-nav--vertical .kywi-nav-item--has-children > .kywi-nav-description { grid-column: 1 / -1; }
531
+ .kywi-nav--vertical .kywi-nav-panel {
532
+ top: 0;
533
+ left: 100%;
534
+ margin-left: var(--kywi-spacing-xs, 0.25rem);
535
+ transform: translateX(-0.35rem);
536
+ }
537
+ .kywi-nav--vertical .kywi-nav-panel--flip {
538
+ left: auto;
539
+ right: 100%;
540
+ margin-left: 0;
541
+ margin-right: var(--kywi-spacing-xs, 0.25rem);
542
+ }
543
+ .kywi-nav--vertical .kywi-nav-list--level-2,
544
+ .kywi-nav--vertical .kywi-nav-list--level-3 {
545
+ display: flex;
546
+ flex-direction: column;
547
+ }
548
+
549
+ /* Footer columns — headings + link stacks, no interactivity. */
550
+ .kywi-nav--footer .kywi-nav-columns {
551
+ display: grid;
552
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
553
+ gap: var(--kywi-spacing-xl, 2.5rem);
554
+ }
555
+ .kywi-nav--footer .kywi-nav-column-heading {
556
+ margin: 0 0 var(--kywi-spacing-sm, 0.5rem);
557
+ font-family: var(--kywi-font-family-heading, var(--kywi-font-family-base, inherit));
558
+ font-size: 0.78rem;
559
+ font-weight: 700;
560
+ letter-spacing: 0.05em;
561
+ text-transform: uppercase;
562
+ color: var(--_kywi-nav-muted);
563
+ }
564
+ .kywi-nav--footer .kywi-nav-column-heading .kywi-nav-link,
565
+ .kywi-nav--footer .kywi-nav-column-heading .kywi-nav-label,
566
+ .kywi-nav--footer .kywi-nav-list .kywi-nav-link { padding-left: 0; padding-right: 0; }
567
+ .kywi-nav--footer .kywi-nav-column-description {
568
+ margin: 0 0 var(--kywi-spacing-sm, 0.5rem);
569
+ font-size: 0.85rem;
570
+ color: var(--_kywi-nav-muted);
571
+ }
572
+ .kywi-nav--footer .kywi-nav-list--level-2 { display: grid; gap: calc(var(--kywi-spacing-xs, 0.25rem) / 2); }
573
+ .kywi-nav--footer .kywi-nav-description { padding-left: 0; }
574
+
575
+ /* Mobile hamburger. The <details> is EMPTY on purpose — its list sibling is
576
+ * revealed with `[open] ~ .kywi-nav-list`, because a closed <details> does not
577
+ * paint or hit-test its own contents in current Chromium, which makes the
578
+ * "force it open again on desktop" trick unreliable. Above the breakpoint the
579
+ * summary is simply hidden and the bar renders normally. */
580
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile { display: none; }
581
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile-toggle {
582
+ display: inline-flex;
583
+ align-items: center;
584
+ gap: var(--kywi-spacing-sm, 0.5rem);
585
+ padding: var(--_kywi-nav-pad-y) var(--_kywi-nav-pad-x);
586
+ cursor: pointer;
587
+ list-style: none;
588
+ border: 1px solid var(--_kywi-nav-border);
589
+ border-radius: var(--kywi-border-radius-sm, 6px);
590
+ }
591
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile-toggle::-webkit-details-marker { display: none; }
592
+ .kywi-nav-burger {
593
+ position: relative;
594
+ width: 1rem;
595
+ height: 2px;
596
+ background: currentColor;
597
+ }
598
+ .kywi-nav-burger::before,
599
+ .kywi-nav-burger::after {
600
+ content: '';
601
+ position: absolute;
602
+ left: 0;
603
+ width: 100%;
604
+ height: 2px;
605
+ background: currentColor;
606
+ }
607
+ .kywi-nav-burger::before { top: -5px; }
608
+ .kywi-nav-burger::after { top: 5px; }
609
+
610
+ @media (max-width: 859.98px) {
611
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile { display: block; }
612
+ /* Collapsed: the bar is hidden until the disclosure is open. */
613
+ .kywi-nav--horizontal .kywi-nav-mobile ~ .kywi-nav-list--level-1,
614
+ .kywi-nav--mega .kywi-nav-mobile ~ .kywi-nav-list--level-1,
615
+ .kywi-nav--vertical .kywi-nav-mobile ~ .kywi-nav-list--level-1 { display: none; }
616
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-mobile[open] ~ .kywi-nav-list--level-1 {
617
+ display: block;
618
+ margin-top: var(--kywi-spacing-sm, 0.5rem);
619
+ }
620
+ /* Accordion: panels sit inline and stay open, so every link is reachable
621
+ * without JS — the hamburger itself is the only disclosure. */
622
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-item { position: static; display: block; }
623
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-toggle { display: none; }
624
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-panel,
625
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-panel--mega {
626
+ position: static;
627
+ min-width: 0;
628
+ margin: 0 0 0 var(--kywi-spacing-md, 1rem);
629
+ padding: 0;
630
+ opacity: 1;
631
+ pointer-events: auto;
632
+ transform: none;
633
+ background: none;
634
+ border: 0;
635
+ border-left: 1px solid var(--_kywi-nav-border);
636
+ border-radius: 0;
637
+ box-shadow: none;
638
+ }
639
+ .kywi-nav-mega-columns { grid-template-columns: 1fr; gap: var(--kywi-spacing-md, 1rem); }
640
+ .kywi-nav--footer .kywi-nav-columns { gap: var(--kywi-spacing-lg, 1.5rem); }
641
+ }
642
+
643
+ @media (prefers-reduced-motion: reduce) {
644
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-panel,
645
+ .kywi-nav[data-kywi-nav-variant] .kywi-nav-chevron { transition: none; }
646
+ }
647
+
648
+ /* Breadcrumbs — inline trail, separators drawn by CSS. */
649
+ .kywi-module-breadcrumbs .kywi-breadcrumbs-list {
650
+ display: flex;
651
+ flex-wrap: wrap;
652
+ align-items: center;
653
+ gap: var(--kywi-spacing-xs, 0.25rem);
654
+ margin: 0;
655
+ padding: 0;
656
+ list-style: none;
657
+ font-size: 0.88rem;
658
+ color: var(--kywi-color-muted, #64748b);
659
+ }
660
+ .kywi-module-breadcrumbs .kywi-breadcrumb-item { display: flex; align-items: center; }
661
+ .kywi-module-breadcrumbs .kywi-breadcrumb-item + .kywi-breadcrumb-item::before {
662
+ content: var(--kywi-breadcrumb-separator, '/');
663
+ margin-right: var(--kywi-spacing-xs, 0.25rem);
664
+ color: var(--kywi-color-border, #e2e8f0);
665
+ }
666
+ .kywi-module-breadcrumbs .kywi-breadcrumb-item a { color: inherit; text-decoration: none; }
667
+ .kywi-module-breadcrumbs .kywi-breadcrumb-item a:hover { color: var(--kywi-color-primary, #2563eb); }
668
+ .kywi-module-breadcrumbs .kywi-breadcrumb-current > span {
669
+ color: var(--kywi-color-text, #0f172a);
670
+ font-weight: 600;
671
+ }
672
+
673
+ /* Site map — indented nested outline. */
674
+ .kywi-module-sitemap .kywi-sitemap-title {
675
+ margin: 0 0 var(--kywi-spacing-md, 1rem);
676
+ font-family: var(--kywi-font-family-heading, var(--kywi-font-family-base, inherit));
677
+ font-size: 1.35rem;
678
+ color: var(--kywi-color-heading, var(--kywi-color-text, #0f172a));
679
+ }
680
+ .kywi-module-sitemap .kywi-sitemap-list { margin: 0; padding: 0; list-style: none; }
681
+ .kywi-module-sitemap .kywi-sitemap-list .kywi-sitemap-list {
682
+ margin-top: var(--kywi-spacing-xs, 0.25rem);
683
+ padding-left: var(--kywi-spacing-md, 1rem);
684
+ border-left: 1px solid var(--kywi-color-border, #e2e8f0);
685
+ }
686
+ .kywi-module-sitemap .kywi-sitemap-item { padding: 0.15rem 0; }
687
+ .kywi-module-sitemap .kywi-sitemap-link {
688
+ color: var(--kywi-color-text, #0f172a);
689
+ text-decoration: none;
690
+ }
691
+ .kywi-module-sitemap .kywi-sitemap-link:hover { color: var(--kywi-color-primary, #2563eb); }
692
+ .kywi-module-sitemap .kywi-sitemap-active > .kywi-sitemap-link {
693
+ color: var(--kywi-color-primary, #2563eb);
694
+ font-weight: 600;
695
+ }
696
+ .kywi-module-sitemap .kywi-sitemap-label { color: var(--kywi-color-muted, #64748b); }
697
+
318
698
  /* ── Front-of-site edit overlay (?kywi-edit=1) ───────────────────────────────
319
699
  * Styles the KywiEditToolbar + editable-region affordances so the overlay is
320
700
  * visible on a fresh public site. The toolbar self-gates on edit permission
@@ -671,7 +1051,8 @@ body.kywi-selfid-hello-bar-top-open {
671
1051
  .kywi-selfid-skip:hover { color: var(--kywi-color-text, #0f172a); }
672
1052
 
673
1053
  /* Transparency surface — the single global personalization control (#105).
674
- * Anchored to the bottom-right corner as a small pill; clicking the pill swaps
1054
+ * Anchored to the bottom-left corner as a small pill (the self-ID slide-in owns
1055
+ * the bottom-right); clicking the pill swaps
675
1056
  * it for the panel (which audience, switch, reset, opt out). This file is the
676
1057
  * ONLY stylesheet for it — the runtime injects nothing of its own. */
677
1058
  /* These surfaces are injected into whatever the host page's CSS reset is, so
@@ -686,12 +1067,15 @@ body.kywi-selfid-hello-bar-top-open {
686
1067
  }
687
1068
  .kywi-transparency {
688
1069
  position: fixed;
689
- right: var(--kywi-spacing-lg, 1.5rem);
1070
+ /* Bottom-LEFT, deliberately: the self-ID slide-in card owns the bottom-right
1071
+ corner, and stacking both there leaves the pill unreachable underneath the
1072
+ card (caught in live UAT). Two fixed personalization surfaces, two corners. */
1073
+ left: var(--kywi-spacing-lg, 1.5rem);
690
1074
  bottom: var(--kywi-spacing-lg, 1.5rem);
691
1075
  z-index: 55;
692
1076
  display: flex;
693
1077
  flex-direction: column;
694
- align-items: flex-end;
1078
+ align-items: flex-start;
695
1079
  gap: var(--kywi-spacing-sm, 0.5rem);
696
1080
  width: max-content;
697
1081
  max-width: min(22rem, calc(100vw - 2rem));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kywi-software/core",
3
- "version": "0.6.6",
3
+ "version": "0.7.0",
4
4
  "description": "Kywi CMS core — schema generator, REST API, and admin UI for Next.js.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",