@kbach/react 1.0.0-beta.16 → 1.0.0-beta.18

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.
@@ -310,709 +310,6 @@ ${block}` : block;
310
310
  return true;
311
311
  }
312
312
 
313
- // src/vite-plugin/classNameHints.ts
314
- var STRUCTURAL_TOKENS = [
315
- // layout.rs
316
- "flex",
317
- "flex-row",
318
- "flex-col",
319
- "flex-row-reverse",
320
- "flex-col-reverse",
321
- "flex-wrap",
322
- "flex-wrap-reverse",
323
- "flex-nowrap",
324
- "flex-1",
325
- "flex-auto",
326
- "flex-initial",
327
- "flex-none",
328
- "flex-grow",
329
- "flex-grow-0",
330
- "flex-shrink",
331
- "flex-shrink-0",
332
- "grow",
333
- "grow-0",
334
- "shrink",
335
- "shrink-0",
336
- "grid",
337
- "block",
338
- "inline-block",
339
- "inline",
340
- "inline-flex",
341
- "inline-grid",
342
- "contents",
343
- "flow-root",
344
- "hidden",
345
- "items-center",
346
- "items-start",
347
- "items-end",
348
- "items-baseline",
349
- "items-stretch",
350
- "justify-center",
351
- "justify-start",
352
- "justify-end",
353
- "justify-between",
354
- "justify-around",
355
- "justify-evenly",
356
- "content-start",
357
- "content-end",
358
- "content-center",
359
- "content-between",
360
- "content-around",
361
- "content-evenly",
362
- "content-stretch",
363
- "self-auto",
364
- "self-center",
365
- "self-start",
366
- "self-end",
367
- "self-stretch",
368
- "self-baseline",
369
- "overflow-hidden",
370
- "overflow-auto",
371
- "overflow-scroll",
372
- "overflow-visible",
373
- "static",
374
- "relative",
375
- "absolute",
376
- "fixed",
377
- "sticky",
378
- "aspect-square",
379
- "aspect-video",
380
- "w-full",
381
- "h-full",
382
- "min-w-full",
383
- "max-w-full",
384
- "min-h-full",
385
- "max-h-full",
386
- "w-screen",
387
- "h-screen",
388
- "min-w-screen",
389
- "max-w-screen",
390
- "min-h-screen",
391
- "max-h-screen",
392
- "w-auto",
393
- "h-auto",
394
- "m-auto",
395
- "mx-auto",
396
- "my-auto",
397
- // grid.rs — web-only (see the module's own doc comment for why)
398
- "grid-cols-none",
399
- "grid-rows-none",
400
- "grid-flow-row",
401
- "grid-flow-col",
402
- "grid-flow-dense",
403
- "grid-flow-row-dense",
404
- "grid-flow-col-dense",
405
- "auto-cols-auto",
406
- "auto-cols-min",
407
- "auto-cols-max",
408
- "auto-cols-fr",
409
- "auto-rows-auto",
410
- "auto-rows-min",
411
- "auto-rows-max",
412
- "auto-rows-fr",
413
- "col-span-full",
414
- "row-span-full",
415
- "col-start-auto",
416
- "col-end-auto",
417
- "row-start-auto",
418
- "row-end-auto",
419
- "col",
420
- "col-auto",
421
- "row",
422
- "row-auto",
423
- "place-items-start",
424
- "place-items-end",
425
- "place-items-center",
426
- "place-items-stretch",
427
- "place-items-baseline",
428
- "place-content-start",
429
- "place-content-end",
430
- "place-content-center",
431
- "place-content-stretch",
432
- "place-content-between",
433
- "place-content-around",
434
- "place-content-evenly",
435
- "place-content-baseline",
436
- "place-self-auto",
437
- "place-self-start",
438
- "place-self-end",
439
- "place-self-center",
440
- "place-self-stretch",
441
- "justify-items-start",
442
- "justify-items-end",
443
- "justify-items-center",
444
- "justify-items-stretch",
445
- "justify-self-auto",
446
- "justify-self-start",
447
- "justify-self-end",
448
- "justify-self-center",
449
- "justify-self-stretch",
450
- // transform.rs — web-only (see the module's own doc comment for why)
451
- "transform-none",
452
- "origin-center",
453
- "origin-top",
454
- "origin-top-right",
455
- "origin-right",
456
- "origin-bottom-right",
457
- "origin-bottom",
458
- "origin-bottom-left",
459
- "origin-left",
460
- "origin-top-left",
461
- // filters.rs — web-only (see the module's own doc comment for why)
462
- "blur",
463
- "blur-sm",
464
- "blur-md",
465
- "blur-lg",
466
- "blur-xl",
467
- "blur-2xl",
468
- "blur-3xl",
469
- "blur-none",
470
- "grayscale",
471
- "grayscale-0",
472
- "invert",
473
- "invert-0",
474
- "sepia",
475
- "sepia-0",
476
- "drop-shadow",
477
- "drop-shadow-sm",
478
- "drop-shadow-md",
479
- "drop-shadow-lg",
480
- "drop-shadow-xl",
481
- "drop-shadow-2xl",
482
- "drop-shadow-none",
483
- "filter-none",
484
- "backdrop-filter-none",
485
- "backdrop-blur",
486
- "backdrop-blur-sm",
487
- "backdrop-blur-md",
488
- "backdrop-blur-lg",
489
- "backdrop-blur-xl",
490
- "backdrop-blur-2xl",
491
- "backdrop-blur-3xl",
492
- "backdrop-blur-none",
493
- "backdrop-grayscale",
494
- "backdrop-grayscale-0",
495
- "backdrop-invert",
496
- "backdrop-invert-0",
497
- "backdrop-sepia",
498
- "backdrop-sepia-0",
499
- // border.rs
500
- "border",
501
- "border-t",
502
- "border-r",
503
- "border-b",
504
- "border-l",
505
- "rounded",
506
- "rounded-none",
507
- "rounded-sm",
508
- "rounded-md",
509
- "rounded-lg",
510
- "rounded-xl",
511
- "rounded-2xl",
512
- "rounded-3xl",
513
- "rounded-full",
514
- "ring",
515
- "ring-0",
516
- "ring-1",
517
- "ring-2",
518
- "ring-4",
519
- "ring-8",
520
- "ring-inset",
521
- "ring-offset-0",
522
- "ring-offset-1",
523
- "ring-offset-2",
524
- "ring-offset-4",
525
- "ring-offset-8",
526
- "outline",
527
- "outline-none",
528
- "border-solid",
529
- "border-dashed",
530
- "border-dotted",
531
- "border-none",
532
- // typography.rs
533
- "font-thin",
534
- "font-normal",
535
- "font-medium",
536
- "font-semibold",
537
- "font-bold",
538
- "font-extrabold",
539
- "uppercase",
540
- "lowercase",
541
- "capitalize",
542
- "underline",
543
- "line-through",
544
- "no-underline",
545
- "truncate",
546
- "text-xs",
547
- "text-sm",
548
- "text-base",
549
- "text-lg",
550
- "text-xl",
551
- "text-2xl",
552
- "text-3xl",
553
- "text-4xl",
554
- "text-left",
555
- "text-center",
556
- "text-right",
557
- "text-justify",
558
- // typography.rs — Phase 20 (typography completeness)
559
- "italic",
560
- "not-italic",
561
- "leading-none",
562
- "leading-tight",
563
- "leading-snug",
564
- "leading-normal",
565
- "leading-relaxed",
566
- "leading-loose",
567
- "tracking-tighter",
568
- "tracking-tight",
569
- "tracking-normal",
570
- "tracking-wide",
571
- "tracking-wider",
572
- "tracking-widest",
573
- "decoration-auto",
574
- "decoration-from-font",
575
- "decoration-solid",
576
- "decoration-dashed",
577
- "decoration-dotted",
578
- "decoration-double",
579
- "decoration-wavy",
580
- "underline-offset-auto",
581
- "underline-offset-0",
582
- "underline-offset-1",
583
- "underline-offset-2",
584
- "underline-offset-4",
585
- "underline-offset-8",
586
- "text-wrap",
587
- "text-nowrap",
588
- "text-balance",
589
- "text-pretty",
590
- "whitespace-normal",
591
- "whitespace-nowrap",
592
- "whitespace-pre",
593
- "whitespace-pre-wrap",
594
- "whitespace-pre-line",
595
- "break-normal",
596
- "break-words",
597
- "break-all",
598
- "align-baseline",
599
- "align-top",
600
- "align-middle",
601
- "align-bottom",
602
- "align-text-top",
603
- "align-text-bottom",
604
- "align-sub",
605
- "align-super",
606
- "list-none",
607
- "list-disc",
608
- "list-decimal",
609
- "list-inside",
610
- "list-outside",
611
- "hyphens-none",
612
- "hyphens-manual",
613
- "hyphens-auto",
614
- // effects.rs
615
- "shadow",
616
- "shadow-sm",
617
- "shadow-md",
618
- "shadow-lg",
619
- "shadow-xl",
620
- "shadow-2xl",
621
- "shadow-inner",
622
- "shadow-none",
623
- "transition",
624
- "transition-none",
625
- "ease-linear",
626
- "ease-in",
627
- "ease-out",
628
- "ease-in-out",
629
- "cursor-pointer",
630
- "cursor-default",
631
- "cursor-not-allowed",
632
- "cursor-wait",
633
- "select-none",
634
- "select-text",
635
- "select-all",
636
- "pointer-events-none",
637
- "pointer-events-auto",
638
- // effects.rs — Phase 22 (effects completeness)
639
- "text-shadow",
640
- "text-shadow-sm",
641
- "text-shadow-lg",
642
- "text-shadow-none",
643
- "mix-blend-normal",
644
- "mix-blend-multiply",
645
- "mix-blend-screen",
646
- "mix-blend-overlay",
647
- "mix-blend-darken",
648
- "mix-blend-lighten",
649
- "mix-blend-color-dodge",
650
- "mix-blend-color-burn",
651
- "mix-blend-hard-light",
652
- "mix-blend-soft-light",
653
- "mix-blend-difference",
654
- "mix-blend-exclusion",
655
- "mix-blend-hue",
656
- "mix-blend-saturation",
657
- "mix-blend-color",
658
- "mix-blend-luminosity",
659
- "mix-blend-plus-lighter",
660
- "bg-blend-normal",
661
- "bg-blend-multiply",
662
- "bg-blend-screen",
663
- "bg-blend-overlay",
664
- "bg-blend-darken",
665
- "bg-blend-lighten",
666
- "bg-blend-color-dodge",
667
- "bg-blend-color-burn",
668
- "bg-blend-hard-light",
669
- "bg-blend-soft-light",
670
- "bg-blend-difference",
671
- "bg-blend-exclusion",
672
- "bg-blend-hue",
673
- "bg-blend-saturation",
674
- "bg-blend-color",
675
- "bg-blend-luminosity",
676
- "bg-blend-plus-lighter",
677
- "animate-spin",
678
- "animate-ping",
679
- "animate-pulse",
680
- "animate-bounce",
681
- "animate-none",
682
- // interactivity.rs — Phase 23 (interactivity & sizing rest)
683
- "resize",
684
- "resize-none",
685
- "resize-y",
686
- "resize-x",
687
- "touch-auto",
688
- "touch-none",
689
- "touch-pan-x",
690
- "touch-pan-left",
691
- "touch-pan-right",
692
- "touch-pan-y",
693
- "touch-pan-up",
694
- "touch-pan-down",
695
- "touch-pinch-zoom",
696
- "touch-manipulation",
697
- "will-change-auto",
698
- "will-change-scroll",
699
- "will-change-contents",
700
- "will-change-transform",
701
- "sr-only",
702
- "not-sr-only",
703
- "border-collapse",
704
- "border-separate",
705
- "table-auto",
706
- "table-fixed",
707
- "caption-top",
708
- "caption-bottom",
709
- "stroke-width-0",
710
- "stroke-width-1",
711
- "stroke-width-2",
712
- // spacing.rs — Phase 23 (size-* shorthand + fraction-based width/height)
713
- "size-full",
714
- "size-auto",
715
- "size-px",
716
- "w-1/2",
717
- "w-1/3",
718
- "w-2/3",
719
- "w-1/4",
720
- "w-2/4",
721
- "w-3/4",
722
- "w-1/5",
723
- "w-2/5",
724
- "w-3/5",
725
- "w-4/5",
726
- "w-1/6",
727
- "w-5/6",
728
- "w-1/12",
729
- "w-5/12",
730
- "w-7/12",
731
- "w-11/12",
732
- "h-1/2",
733
- "h-1/3",
734
- "h-2/3",
735
- "h-1/4",
736
- "h-2/4",
737
- "h-3/4",
738
- "h-1/5",
739
- "h-2/5",
740
- "h-3/5",
741
- "h-4/5",
742
- "h-1/6",
743
- "h-5/6",
744
- // scroll.rs — Phase 23 (scroll-behavior/-margin/-padding, scroll-snap)
745
- "scroll-auto",
746
- "scroll-smooth",
747
- "snap-start",
748
- "snap-end",
749
- "snap-center",
750
- "snap-align-none",
751
- "snap-normal",
752
- "snap-always",
753
- "snap-none",
754
- "snap-x",
755
- "snap-y",
756
- "snap-both",
757
- "snap-mandatory",
758
- "snap-proximity",
759
- // divide.rs
760
- "divide-x",
761
- "divide-y",
762
- // background.rs — web-only (see the module's own doc comment for why)
763
- "bg-top",
764
- "bg-bottom",
765
- "bg-left",
766
- "bg-right",
767
- "bg-center",
768
- "bg-left-top",
769
- "bg-left-bottom",
770
- "bg-right-top",
771
- "bg-right-bottom",
772
- "bg-auto",
773
- "bg-cover",
774
- "bg-contain",
775
- "bg-repeat",
776
- "bg-no-repeat",
777
- "bg-repeat-x",
778
- "bg-repeat-y",
779
- "bg-repeat-round",
780
- "bg-repeat-space",
781
- "bg-fixed",
782
- "bg-local",
783
- "bg-scroll",
784
- "bg-clip-border",
785
- "bg-clip-padding",
786
- "bg-clip-content",
787
- "bg-clip-text",
788
- "bg-origin-border",
789
- "bg-origin-padding",
790
- "bg-origin-content",
791
- "bg-none",
792
- "bg-linear-to-t",
793
- "bg-linear-to-tr",
794
- "bg-linear-to-r",
795
- "bg-linear-to-br",
796
- "bg-linear-to-b",
797
- "bg-linear-to-bl",
798
- "bg-linear-to-l",
799
- "bg-linear-to-tl",
800
- "bg-radial",
801
- "bg-conic",
802
- // Ancestor/sibling-state marker classes — carry no styles of their own,
803
- // just a selector target for group-hover:/peer-hover:/etc. below (see
804
- // unknownClassWarnings.ts's MARKER_CLASSES for why they need special
805
- // handling there too).
806
- "group",
807
- "peer",
808
- // registry.rs modifiers — bare tokens only, not composed with a
809
- // following utility (see this module's doc header / the Phase 15 plan).
810
- "hover:",
811
- "focus:",
812
- "focus-visible:",
813
- "focus-within:",
814
- "active:",
815
- "visited:",
816
- "disabled:",
817
- "checked:",
818
- "group-hover:",
819
- "group-focus:",
820
- "peer-hover:",
821
- "peer-focus:",
822
- "peer-checked:",
823
- "dark:",
824
- "motion-safe:",
825
- "motion-reduce:",
826
- "print:",
827
- "sm:",
828
- "md:",
829
- "lg:",
830
- "xl:",
831
- "2xl:",
832
- // registry.rs modifiers — Phase 24 (expanded variant system), the
833
- // FIXED/static additions only. Deliberately excluded: every genuinely
834
- // parameterized modifier (has-[...]/group-has-[...]/peer-has-[...]/
835
- // data-[...]/aria-[...]/not-[...]/min-[...]/max-[...], and the
836
- // generalized group-<pseudo>/peer-<pseudo> beyond the five hardcoded
837
- // combos above) — these have no finite enumerable set (their whole point
838
- // is arbitrary user-supplied content), so there's nothing meaningful to
839
- // suggest beyond the bare prefix, same reasoning as every other
840
- // arbitrary-value exclusion in this file. `not-hover:`/`not-disabled:`/
841
- // etc. (wrapping a KNOWN static modifier) are excluded for the same
842
- // reason — enumerable in principle, but a full cross-product with every
843
- // modifier above would be more noise than signal for an editor hint list.
844
- "first:",
845
- "last:",
846
- "only:",
847
- "odd:",
848
- "even:",
849
- "open:",
850
- "inert:",
851
- "aria-checked:",
852
- "aria-disabled:",
853
- "aria-expanded:",
854
- "aria-hidden:",
855
- "aria-pressed:",
856
- "aria-readonly:",
857
- "aria-required:",
858
- "aria-selected:",
859
- "aria-busy:",
860
- // registry.rs modifiers, added later — same "fixed/static, finite" bar
861
- // as the Phase 24 block above. Structural -of-type/empty, form-state and
862
- // validation pseudo-classes, other native pseudo-classes with no aria-*
863
- // counterpart, a pseudo-element, pointer media variants, and the
864
- // direct-children/all-descendants variants. "supports-[...]:"/"in-*:" are
865
- // deliberately excluded here for the same "no finite enumerable set"
866
- // reason as has-[...]:/group-<pseudo>: above.
867
- "first-of-type:",
868
- "last-of-type:",
869
- "only-of-type:",
870
- "empty:",
871
- "enabled:",
872
- "read-only:",
873
- "required:",
874
- "optional:",
875
- "valid:",
876
- "invalid:",
877
- "in-range:",
878
- "out-of-range:",
879
- "default:",
880
- "indeterminate:",
881
- "placeholder-shown:",
882
- "autofill:",
883
- "user-valid:",
884
- "user-invalid:",
885
- "target:",
886
- "fullscreen:",
887
- "popover-open:",
888
- "details-content:",
889
- "pointer-coarse:",
890
- "pointer-fine:",
891
- "any-pointer-coarse:",
892
- "any-pointer-fine:",
893
- "*:",
894
- "**:",
895
- // Phase 25 (container queries & arbitrary properties). "@container" is a
896
- // real UTILITY (container-type: inline-size), not a modifier — included
897
- // as a bare token like "flex"/"hidden" above, not with the trailing ":"
898
- // the modifier tokens below get. "@sm:"/"@md:"/"@lg:"/"@xl:"/"@2xl:" are
899
- // container-responsive modifiers (registry.rs's `is_container_responsive`),
900
- // and "starting:" wraps in @starting-style. Deliberately excluded, same
901
- // "no finite enumerable set" reasoning as Phase 24's exclusions:
902
- // "@min-[...]:"/"@max-[...]:" (arbitrary container breakpoints) and every
903
- // `[property:value]` arbitrary property — both are open-ended by design.
904
- "@container",
905
- "@sm:",
906
- "@md:",
907
- "@lg:",
908
- "@xl:",
909
- "@2xl:",
910
- "starting:"
911
- ];
912
- var COLOR_PREFIXES = [
913
- "bg-",
914
- "text-",
915
- "border-",
916
- "divide-",
917
- "decoration-",
918
- "from-",
919
- "via-",
920
- "to-",
921
- "text-shadow-",
922
- "ring-",
923
- "ring-offset-",
924
- "caret-",
925
- "accent-",
926
- "fill-",
927
- "stroke-"
928
- ];
929
- var SPACING_PREFIXES = [
930
- "p-",
931
- "px-",
932
- "py-",
933
- "pt-",
934
- "pr-",
935
- "pb-",
936
- "pl-",
937
- "m-",
938
- "mx-",
939
- "my-",
940
- "mt-",
941
- "mr-",
942
- "mb-",
943
- "ml-",
944
- "gap-",
945
- "gap-x-",
946
- "gap-y-",
947
- "w-",
948
- "h-",
949
- "min-w-",
950
- "max-w-",
951
- "min-h-",
952
- "max-h-",
953
- "size-",
954
- "top-",
955
- "right-",
956
- "bottom-",
957
- "left-",
958
- "inset-",
959
- "space-x-",
960
- "space-y-",
961
- "indent-",
962
- "scroll-m-",
963
- "scroll-mx-",
964
- "scroll-my-",
965
- "scroll-mt-",
966
- "scroll-mr-",
967
- "scroll-mb-",
968
- "scroll-ml-",
969
- "scroll-p-",
970
- "scroll-px-",
971
- "scroll-py-",
972
- "scroll-pt-",
973
- "scroll-pr-",
974
- "scroll-pb-",
975
- "scroll-pl-"
976
- ];
977
- var SIZE_PREFIXES = ["w-", "h-", "min-w-", "max-w-", "min-h-", "max-h-", "size-"];
978
- var NAMED_SIZES = ["sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl", "8xl", "9xl"];
979
- function buildClassTokens(theme) {
980
- const tokens = new Set(STRUCTURAL_TOKENS);
981
- for (const colorKey of Object.keys(theme.colors)) {
982
- for (const prefix of COLOR_PREFIXES) tokens.add(`${prefix}${colorKey}`);
983
- }
984
- for (const spacingKey of Object.keys(theme.spacing)) {
985
- for (const prefix of SPACING_PREFIXES) tokens.add(`${prefix}${spacingKey}`);
986
- }
987
- for (const size of NAMED_SIZES) {
988
- for (const prefix of SIZE_PREFIXES) tokens.add(`${prefix}${size}`);
989
- }
990
- return Array.from(tokens).sort();
991
- }
992
- function buildClassNameHintsDts(tokens) {
993
- const literals = tokens.map((t) => ` | '${t}'`).join("\n");
994
- return [
995
- "// Generated by Kbach \u2014 do not edit",
996
- "// Editor autocomplete for className \u2014 see packages/react/src/vite-plugin/classNameHints.ts",
997
- "",
998
- "type KbachClassToken =",
999
- literals,
1000
- ";",
1001
- "",
1002
- "export type KbachClassName = KbachClassToken | `${string} ${KbachClassToken}` | (string & {});",
1003
- "",
1004
- "declare module 'react' {",
1005
- " interface HTMLAttributes<T> {",
1006
- " className?: KbachClassName | undefined;",
1007
- " }",
1008
- " interface SVGAttributes<T> {",
1009
- " className?: KbachClassName | undefined;",
1010
- " }",
1011
- "}",
1012
- ""
1013
- ].join("\n");
1014
- }
1015
-
1016
313
  // src/generatedPalette.ts
1017
314
  var PALETTE = {
1018
315
  "amber-1": "#fffbeb",
@@ -1704,8 +1001,8 @@ function scanDir(dir, onFile, depth = 0, fileMatch = DEFAULT_FILE_MATCH) {
1704
1001
 
1705
1002
  // src/vite-plugin/unknownClassWarnings.ts
1706
1003
  var import_path2 = require("path");
1707
- var CSS_CLASS_SELECTOR_RE = /\.(-?[a-zA-Z_][a-zA-Z0-9_-]*)/g;
1708
- var CSS_FILE_RE = /\.(css|scss|sass|less)$/;
1004
+
1005
+ // src/terminalWarn.ts
1709
1006
  var useColor = !!process.stdout?.isTTY && !process.env.NO_COLOR;
1710
1007
  var paint = (code, s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
1711
1008
  var green = (s) => paint("32", s);
@@ -1713,9 +1010,14 @@ var blue = (s) => paint("34", s);
1713
1010
  var white = (s) => paint("97", s);
1714
1011
  var gray = (s) => paint("90", s);
1715
1012
  var bold = (s) => paint("1", s);
1716
- var ARROW = () => green("\u2192");
1717
- var TAG = () => bold(green("[kbach]"));
1718
1013
  var highlight = (s) => bold(white(s));
1014
+ function kbachTag() {
1015
+ return `${green("\u2192")} ${bold(green("[Kbach]"))}`;
1016
+ }
1017
+
1018
+ // src/vite-plugin/unknownClassWarnings.ts
1019
+ var CSS_CLASS_SELECTOR_RE = /\.(-?[a-zA-Z_][a-zA-Z0-9_-]*)/g;
1020
+ var CSS_FILE_RE = /\.(css|scss|sass|less)$/;
1719
1021
  function findLineCol(code, needle) {
1720
1022
  const index = code.indexOf(needle);
1721
1023
  if (index === -1) return null;
@@ -1745,15 +1047,21 @@ function stripModifierPrefix(token) {
1745
1047
  return token.replace(/^(?:[a-zA-Z0-9_/-]+:)+/, "");
1746
1048
  }
1747
1049
  var MARKER_CLASSES = /* @__PURE__ */ new Set(["group", "peer"]);
1050
+ function isMarkerClass(base) {
1051
+ if (MARKER_CLASSES.has(base)) return true;
1052
+ const slashIdx = base.lastIndexOf("/");
1053
+ if (slashIdx === -1) return false;
1054
+ return MARKER_CLASSES.has(base.slice(0, slashIdx)) && slashIdx < base.length - 1;
1055
+ }
1748
1056
  function warnIfUnknownClass(token, filePath, code, isResolvable, projectCssClasses, warnedTokens) {
1749
1057
  if (isResolvable || warnedTokens.has(token)) return;
1750
1058
  const base = stripModifierPrefix(token);
1751
- if (!base || projectCssClasses.has(base) || MARKER_CLASSES.has(base)) return;
1059
+ if (!base || projectCssClasses.has(base) || isMarkerClass(base)) return;
1752
1060
  warnedTokens.add(token);
1753
1061
  const pos = findLineCol(code, token);
1754
1062
  const location = pos ? `${blue(filePath)}${green(`:${pos.line}:${pos.column}`)}` : blue(filePath);
1755
1063
  console.warn(
1756
- `${ARROW()} ${TAG()} ${gray("Unknown class")} ${highlight(token)} ${gray("\u2014 no Kbach utility or project CSS rule matches it. Typo?")}
1064
+ `${kbachTag()} ${gray("Unknown class")} ${highlight(token)} ${gray("\u2014 no Kbach utility or project CSS rule matches it. Typo?")}
1757
1065
  ${bold("at")} ${location}`
1758
1066
  );
1759
1067
  }
@@ -1905,13 +1213,6 @@ function kbach(options = {}) {
1905
1213
  function mainCSSFile() {
1906
1214
  return mainCSSFilePath;
1907
1215
  }
1908
- function classNameHintsFile() {
1909
- return (0, import_path4.join)(root, ".kbach", "kbach-classnames.d.ts");
1910
- }
1911
- function writeClassNameHints() {
1912
- const dts = buildClassNameHintsDts(buildClassTokens(theme));
1913
- writeFileEnsuringDir(classNameHintsFile(), dts);
1914
- }
1915
1216
  function syncMainCSSFile(server) {
1916
1217
  const changed = writeKbachToFile(mainCSSFile(), engine.generateCSS(), readSourceFile, writeFileEnsuringDir);
1917
1218
  if (changed && server) server.watcher.emit("change", mainCSSFile());
@@ -1938,7 +1239,6 @@ function kbach(options = {}) {
1938
1239
  engine.initialScan();
1939
1240
  engine.processSafelist();
1940
1241
  writeKbachToFile(mainCSSFile(), engine.generateCSS(), readSourceFile, writeFileEnsuringDir);
1941
- writeClassNameHints();
1942
1242
  },
1943
1243
  // handleHotUpdate covers edits; add/unlink (create/delete) land on the
1944
1244
  // raw watcher instead — Vite's handleHotUpdate hook only fires for