home readme diff tree note docs

0commit 248955bdc49ab1c6cfa5d98912ac073fef5ced9a
1Author: Mason Wright <mason@lakefox.net>
2Date:   Sun Oct 12 19:03:49 2025 -0600
3
4    Changed how unit parsing works
5
6diff --git a/docs/content/features/.supported-css-selectors.md.swp b/docs/content/features/.supported-css-selectors.md.swp
7index 17c75ef..b3fbabf 100644
8Binary files a/docs/content/features/.supported-css-selectors.md.swp and b/docs/content/features/.supported-css-selectors.md.swp differ
9diff --git a/docs/content/features/supported-css-selectors.1 b/docs/content/features/supported-css-selectors.1
10new file mode 100644
11index 0000000..b556b3a
12--- /dev/null
13+++ b/docs/content/features/supported-css-selectors.1
14@@ -0,0 +1,1727 @@
15+'\" t
16+.\" Automatically generated by Pandoc 2.17.1.1
17+.\"
18+.\" Define V font for inline verbatim, using C font in formats
19+.\" that render this, and otherwise B font.
20+.ie "\f[CB]x\f[]"x" \{\
21+. ftr V B
22+. ftr VI BI
23+. ftr VB B
24+. ftr VBI BI
25+.\}
26+.el \{\
27+. ftr V CR
28+. ftr VI CI
29+. ftr VB CB
30+. ftr VBI CBI
31+.\}
32+.TH "" "" "" "" ""
33+.hy
34+.SH Supported Selectors
35+.SS Support
36+.IP \[bu] 2
37+(*) parsing supported, not implemented
38+.IP \[bu] 2
39+(X) fully supported, implemented
40+.IP \[bu] 2
41+(/) No support planned
42+.SS Selectors
43+.PP
44+.TS
45+tab(@);
46+lw(14.0n) lw(14.0n) lw(14.0n) lw(14.0n) lw(14.0n).
47+T{
48+Name
49+T}@T{
50+Support
51+T}@T{
52+Test Case
53+T}@T{
54+Section
55+T}@T{
56+Test File
57+T}
58+_
59+T{
60+Type
61+T}@T{
62+X
63+T}@T{
64+testSelector
65+T}@T{
66+testSelector can match a element given it\[cq]s tagName
67+T}@T{
68+tests/css_selector.cc
69+T}
70+T{
71+Attribute
72+T}@T{
73+X
74+T}@T{
75+testSelector
76+T}@T{
77+testSelector can match a element by it\[cq]s attributes only
78+T}@T{
79+tests/css_selector.cc
80+T}
81+T{
82+ID
83+T}@T{
84+X
85+T}@T{
86+testSelector
87+T}@T{
88+testSelector can match a element by it\[cq]s id only
89+T}@T{
90+tests/css_selector.cc
91+T}
92+T{
93+Class
94+T}@T{
95+X
96+T}@T{
97+testSelector
98+T}@T{
99+testSelector can match a element by it\[cq]s class and not match on a
100+non class
101+T}@T{
102+tests/css_selector.cc
103+T}
104+T{
105+Universal
106+T}@T{
107+X
108+T}@T{
109+testSelector
110+T}@T{
111+testSelector can match a universal selector
112+T}@T{
113+tests/css_selector.cc
114+T}
115+T{
116+Nesting
117+T}@T{
118+X
119+T}@T{
120+parseCSS can parse a CSS sheet, parseCSS can parse multiple selectors
121+nested
122+T}@T{
123+parseCSS can parse a nested CSS rule without a &, parseCSS can parse a
124+the parent of a nested CSS rule, parseCSS can parse a nested CSS rule
125+with a pseudo element, parseCSS can parse a parent CSS rule with a
126+property in between sub-classes, multi selector test
127+T}@T{
128+tests/css_parser.cc
129+T}
130+T{
131+& Nesting
132+T}@T{
133+X
134+T}@T{
135+parseCSS can parse a CSS sheet, parseCSS can parse multiple selectors
136+nested
137+T}@T{
138+parseCSS can parse a nested CSS rule without a &, parseCSS can parse a
139+the parent of a nested CSS rule, parseCSS can parse a nested CSS rule
140+with a pseudo element, parseCSS can parse a double nested CSS rule with
141+a pseudo element and &, parseCSS can parse a nested CSS rule with a &,
142+parseCSS can parse a parent CSS rule with a property in between
143+sub-classes, multi selector test
144+T}@T{
145+tests/css_parser.cc
146+T}
147+.TE
148+.SS Combinator
149+.PP
150+.TS
151+tab(@);
152+lw(14.0n) lw(14.0n) lw(14.0n) lw(14.0n) lw(14.0n).
153+T{
154+Name
155+T}@T{
156+Support
157+T}@T{
158+Test Case
159+T}@T{
160+Section
161+T}@T{
162+Test File
163+T}
164+_
165+T{
166+Child Combinator
167+T}@T{
168+X
169+T}@T{
170+testSelector
171+T}@T{
172+testSelector can match a child combinator
173+T}@T{
174+tests/css_selector.cc
175+T}
176+T{
177+Next-Sibling Combinator
178+T}@T{
179+X
180+T}@T{
181+testSelector
182+T}@T{
183+testSelector can match a next sibling combinator
184+T}@T{
185+tests/css_selector.cc
186+T}
187+T{
188+Descendant Combinator
189+T}@T{
190+X
191+T}@T{
192+testSelector
193+T}@T{
194+testSelector can match a descendant combinator
195+T}@T{
196+tests/css_selector.cc
197+T}
198+T{
199+Subsequent-Sibling Combinator
200+T}@T{
201+X
202+T}@T{
203+testSelector
204+T}@T{
205+testSelector can match a subsequent-sibling combinator
206+T}@T{
207+tests/css_selector.cc
208+T}
209+.TE
210+.SS Pseudo Classes
211+.PP
212+.TS
213+tab(@);
214+lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n).
215+T{
216+Name
217+T}@T{
218+Support
219+T}@T{
220+Test Case
221+T}@T{
222+Section
223+T}@T{
224+Test File
225+T}@T{
226+Note
227+T}
228+_
229+T{
230+:active
231+T}@T{
232+T}@T{
233+T}@T{
234+T}@T{
235+T}@T{
236+Will be added when links are
237+T}
238+T{
239+:any-link
240+T}@T{
241+T}@T{
242+T}@T{
243+T}@T{
244+T}@T{
245+Will be added when links are
246+T}
247+T{
248+:autofill
249+T}@T{
250+T}@T{
251+T}@T{
252+T}@T{
253+T}@T{
254+Will be added when inputs are added
255+T}
256+T{
257+:buffering
258+T}@T{
259+T}@T{
260+T}@T{
261+T}@T{
262+T}@T{
263+Videos are not currently supported
264+T}
265+T{
266+:checked
267+T}@T{
268+X
269+T}@T{
270+testSelector
271+T}@T{
272+testSelector can match a element with a pseudo class
273+T}@T{
274+tests/css_selector.cc
275+T}@T{
276+T}
277+T{
278+:default
279+T}@T{
280+T}@T{
281+T}@T{
282+T}@T{
283+T}@T{
284+Will be added when inputs are added
285+T}
286+T{
287+:defined
288+T}@T{
289+T}@T{
290+T}@T{
291+T}@T{
292+T}@T{
293+T}
294+T{
295+:dir()
296+T}@T{
297+T}@T{
298+T}@T{
299+T}@T{
300+T}@T{
301+T}
302+T{
303+:disabled
304+T}@T{
305+X
306+T}@T{
307+testSelector
308+T}@T{
309+testSelector can match a element with a pseudo class
310+T}@T{
311+tests/css_selector.cc
312+T}@T{
313+T}
314+T{
315+:empty
316+T}@T{
317+T}@T{
318+T}@T{
319+T}@T{
320+T}@T{
321+Will be added when inputs are added
322+T}
323+T{
324+:enabled
325+T}@T{
326+X
327+T}@T{
328+testSelector
329+T}@T{
330+testSelector can match a element with a pseudo class
331+T}@T{
332+tests/css_selector.cc
333+T}@T{
334+T}
335+T{
336+:first
337+T}@T{
338+/
339+T}@T{
340+T}@T{
341+T}@T{
342+T}@T{
343+Will not be supported, currently there are no plans to support printing
344+T}
345+T{
346+:first-child
347+T}@T{
348+X
349+T}@T{
350+testSelector
351+T}@T{
352+testSelector can match a element with first-child
353+T}@T{
354+tests/css_selector.cc
355+T}@T{
356+T}
357+T{
358+:first-of-type
359+T}@T{
360+X
361+T}@T{
362+testSelector
363+T}@T{
364+testSelector can match a element with first-of-type
365+T}@T{
366+tests/css_selector.cc
367+T}@T{
368+T}
369+T{
370+:focus
371+T}@T{
372+T}@T{
373+T}@T{
374+T}@T{
375+T}@T{
376+T}
377+T{
378+:focus-visible
379+T}@T{
380+T}@T{
381+T}@T{
382+T}@T{
383+T}@T{
384+T}
385+T{
386+:focus-within
387+T}@T{
388+T}@T{
389+T}@T{
390+T}@T{
391+T}@T{
392+T}
393+T{
394+:fullscreen
395+T}@T{
396+T}@T{
397+T}@T{
398+T}@T{
399+T}@T{
400+Videos are not currently supported
401+T}
402+T{
403+:future
404+T}@T{
405+T}@T{
406+T}@T{
407+T}@T{
408+T}@T{
409+T}
410+T{
411+:has-slotted
412+T}@T{
413+T}@T{
414+T}@T{
415+T}@T{
416+T}@T{
417+T}
418+T{
419+:has()
420+T}@T{
421+X
422+T}@T{
423+testSelector
424+T}@T{
425+testSelector can match a :has() selector with a child combinator,
426+testSelector can match a :has() selector with a next-sibling combinator,
427+testSelector can match a :has() selector with a subsequent-sibling
428+combinator, testSelector can match a :has() selector with a decendent
429+combinator
430+T}@T{
431+tests/css_selector.cc
432+T}@T{
433+T}
434+T{
435+:host
436+T}@T{
437+T}@T{
438+T}@T{
439+T}@T{
440+T}@T{
441+T}
442+T{
443+:host-context()
444+T}@T{
445+T}@T{
446+T}@T{
447+T}@T{
448+T}@T{
449+T}
450+T{
451+:host()
452+T}@T{
453+T}@T{
454+T}@T{
455+T}@T{
456+T}@T{
457+T}
458+T{
459+:hover
460+T}@T{
461+T}@T{
462+T}@T{
463+T}@T{
464+T}@T{
465+T}
466+T{
467+:in-range
468+T}@T{
469+T}@T{
470+T}@T{
471+T}@T{
472+T}@T{
473+Will be added when inputs are added
474+T}
475+T{
476+:indeterminate
477+T}@T{
478+T}@T{
479+T}@T{
480+T}@T{
481+T}@T{
482+Will be added when inputs are added
483+T}
484+T{
485+:invalid
486+T}@T{
487+T}@T{
488+T}@T{
489+T}@T{
490+T}@T{
491+Will be added when inputs are added
492+T}
493+T{
494+:is()
495+T}@T{
496+X
497+T}@T{
498+testSelector
499+T}@T{
500+testSelector can match :is() selectors
501+T}@T{
502+tests/css_selector.cc
503+T}@T{
504+T}
505+T{
506+:lang()
507+T}@T{
508+T}@T{
509+T}@T{
510+T}@T{
511+T}@T{
512+T}
513+T{
514+:last-child
515+T}@T{
516+X
517+T}@T{
518+testSelector
519+T}@T{
520+testSelector can match a element with last-child
521+T}@T{
522+tests/css_selector.cc
523+T}@T{
524+T}
525+T{
526+:last-of-type
527+T}@T{
528+X
529+T}@T{
530+testSelector
531+T}@T{
532+testSelector can match a element with last-of-type
533+T}@T{
534+tests/css_selector.cc
535+T}@T{
536+T}
537+T{
538+:left
539+T}@T{
540+/
541+T}@T{
542+T}@T{
543+T}@T{
544+T}@T{
545+Will not be supported, currently there are no plans to support printing
546+T}
547+T{
548+:local-link
549+T}@T{
550+/
551+T}@T{
552+T}@T{
553+T}@T{
554+T}@T{
555+Doesn\[cq]t make sense to add because all links will be local
556+T}
557+T{
558+:modal
559+T}@T{
560+T}@T{
561+T}@T{
562+T}@T{
563+T}@T{
564+T}
565+T{
566+:muted
567+T}@T{
568+T}@T{
569+T}@T{
570+T}@T{
571+T}@T{
572+Videos are not currently supported
573+T}
574+T{
575+:not()
576+T}@T{
577+X
578+T}@T{
579+testSelector
580+T}@T{
581+testSelector can match :not() selectors
582+T}@T{
583+tests/css_selector.cc
584+T}@T{
585+T}
586+T{
587+:nth-child()
588+T}@T{
589+X
590+T}@T{
591+testSelector
592+T}@T{
593+testSelector can match a :nth-child(even|odd), testSelector can match a
594+:nth-child(A), testSelector can match a :nth-child(An), testSelector can
595+match a :nth-child(An+B), testSelector can match a :nth-child(An+B of
596+type), testSelector can match a :nth-child(n+B), testSelector can match
597+a :nth-child(A of type), testSelector can match a :nth-child(An of
598+type), testSelector can match a :nth-child(n+B of type)
599+T}@T{
600+tests/css_selector.cc
601+T}@T{
602+when A is 0 it is changed to a 1, the only case this will cause breaking
603+behavior is if you are trying :nth-child(0n+B) which is the same as
604+calling :nth-child(B).
605+This behavior applies to all nth-*
606+T}
607+T{
608+:nth-last-child()
609+T}@T{
610+X
611+T}@T{
612+testSelector
613+T}@T{
614+testSelector can match a :nth-last-child(even|odd), testSelector can
615+match a :nth-last-child(A), testSelector can match a
616+:nth-last-child(An), testSelector can match a :nth-last-child(An+B),
617+testSelector can match a :nth-last-child(n+B), testSelector can match a
618+:nth-last-child(An+B of type), testSelector can match a
619+:nth-last-child(A of type), testSelector can match a :nth-last-child(An
620+of type), testSelector can match a :nth-last-child(n+B of type)
621+T}@T{
622+tests/css_selector.cc
623+T}@T{
624+T}
625+T{
626+:nth-last-of-type()
627+T}@T{
628+X
629+T}@T{
630+testSelector
631+T}@T{
632+testSelector can match a :nth-last-of-type(even|odd), testSelector can
633+match a :nth-last-of-type(A), testSelector can match a
634+:nth-last-of-type(An), testSelector can match a :nth-last-of-type(An+B),
635+testSelector can match a :nth-last-of-type(n+B),
636+T}@T{
637+tests/css_selector.cc
638+T}@T{
639+T}
640+T{
641+:nth-of-type()
642+T}@T{
643+X
644+T}@T{
645+testSelector
646+T}@T{
647+testSelector can match a :nth-of-type(even|odd), testSelector can match
648+a :nth-of-type(A), testSelector can match a :nth-of-type(An),
649+testSelector can match a :nth-of-type(An+B), testSelector can match a
650+:nth-of-type(n+B),
651+T}@T{
652+tests/css_selector.cc
653+T}@T{
654+T}
655+T{
656+:only-child
657+T}@T{
658+X
659+T}@T{
660+testSelector
661+T}@T{
662+testSelector can match :only-child
663+T}@T{
664+tests/css_selector.cc
665+T}@T{
666+T}
667+T{
668+:only-of-type
669+T}@T{
670+X
671+T}@T{
672+testSelector
673+T}@T{
674+testSelector can match :only-of-type
675+T}@T{
676+tests/css_selector.cc
677+T}@T{
678+T}
679+T{
680+:open
681+T}@T{
682+T}@T{
683+T}@T{
684+T}@T{
685+T}@T{
686+T}
687+T{
688+:optional
689+T}@T{
690+T}@T{
691+T}@T{
692+T}@T{
693+T}@T{
694+T}
695+T{
696+:out-of-range
697+T}@T{
698+T}@T{
699+T}@T{
700+T}@T{
701+T}@T{
702+Will be added when inputs are added
703+T}
704+T{
705+:past
706+T}@T{
707+T}@T{
708+T}@T{
709+T}@T{
710+T}@T{
711+T}
712+T{
713+:paused
714+T}@T{
715+T}@T{
716+T}@T{
717+T}@T{
718+T}@T{
719+Videos are not currently supported
720+T}
721+T{
722+:picture-in-picture
723+T}@T{
724+T}@T{
725+T}@T{
726+T}@T{
727+T}@T{
728+Videos are not currently supported
729+T}
730+T{
731+:placeholder-shown
732+T}@T{
733+T}@T{
734+T}@T{
735+T}@T{
736+T}@T{
737+Will be added when inputs are added
738+T}
739+T{
740+:playing
741+T}@T{
742+T}@T{
743+T}@T{
744+T}@T{
745+T}@T{
746+Videos are not currently supported
747+T}
748+T{
749+:popover-open
750+T}@T{
751+T}@T{
752+T}@T{
753+T}@T{
754+T}@T{
755+T}
756+T{
757+:read-only
758+T}@T{
759+X
760+T}@T{
761+testSelector
762+T}@T{
763+testSelector can match :read-only normal element, testSelector can match
764+:read-only on a radio input, testSelector can match :read-only on a
765+readonly text input, testSelector can match :read-only on a disabled
766+text input, testSelector can match :read-only on a readonly textarea,
767+testSelector can match :read-only on a disabled textarea
768+T}@T{
769+tests/css_selector.cc
770+T}@T{
771+T}
772+T{
773+:read-write
774+T}@T{
775+X
776+T}@T{
777+testSelector
778+T}@T{
779+testSelector can match :read-write on a text input, testSelector can
780+match :read-write on a textarea, testSelector can match :read-write on a
781+contenteditable div
782+T}@T{
783+tests/css_selector.cc
784+T}@T{
785+T}
786+T{
787+:required
788+T}@T{
789+X
790+T}@T{
791+testSelector
792+T}@T{
793+testSelector can match a element with a pseudo class
794+T}@T{
795+tests/css_selector.cc
796+T}@T{
797+T}
798+T{
799+:right
800+T}@T{
801+/
802+T}@T{
803+T}@T{
804+T}@T{
805+T}@T{
806+Will not be supported, currently there are no plans to support printing
807+T}
808+T{
809+:root
810+T}@T{
811+X
812+T}@T{
813+testSelector
814+T}@T{
815+testSelector can match :root
816+T}@T{
817+tests/css_selector.cc
818+T}@T{
819+T}
820+T{
821+:scope
822+T}@T{
823+T}@T{
824+T}@T{
825+T}@T{
826+T}@T{
827+T}
828+T{
829+:seeking
830+T}@T{
831+T}@T{
832+T}@T{
833+T}@T{
834+T}@T{
835+Videos are not currently supported
836+T}
837+T{
838+:stalled
839+T}@T{
840+T}@T{
841+T}@T{
842+T}@T{
843+T}@T{
844+Video and Audio are not currently supported
845+T}
846+T{
847+:state()
848+T}@T{
849+T}@T{
850+T}@T{
851+T}@T{
852+T}@T{
853+Shadow DOM
854+T}
855+T{
856+:target
857+T}@T{
858+T}@T{
859+T}@T{
860+T}@T{
861+T}@T{
862+T}
863+T{
864+:target-current
865+T}@T{
866+T}@T{
867+T}@T{
868+T}@T{
869+T}@T{
870+T}
871+T{
872+:target-within
873+T}@T{
874+T}@T{
875+T}@T{
876+T}@T{
877+T}@T{
878+T}
879+T{
880+:user-invalid
881+T}@T{
882+T}@T{
883+T}@T{
884+T}@T{
885+T}@T{
886+T}
887+T{
888+:user-valid
889+T}@T{
890+T}@T{
891+T}@T{
892+T}@T{
893+T}@T{
894+T}
895+T{
896+:valid
897+T}@T{
898+T}@T{
899+T}@T{
900+T}@T{
901+T}@T{
902+T}
903+T{
904+:visited
905+T}@T{
906+T}@T{
907+T}@T{
908+T}@T{
909+T}@T{
910+T}
911+T{
912+:volume-locked
913+T}@T{
914+T}@T{
915+T}@T{
916+T}@T{
917+T}@T{
918+Video and Audio are not currently supported
919+T}
920+T{
921+:where()
922+T}@T{
923+X
924+T}@T{
925+testSelector
926+T}@T{
927+testSelector can match :where() selectors
928+T}@T{
929+tests/css_selector.cc
930+T}@T{
931+T}
932+.TE
933+.SS Pseudo Elements
934+.SS At-rules
935+.PP
936+.TS
937+tab(@);
938+lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n) lw(11.7n).
939+T{
940+Name
941+T}@T{
942+Support
943+T}@T{
944+Test Case
945+T}@T{
946+Section
947+T}@T{
948+Test File
949+T}@T{
950+Note
951+T}
952+_
953+T{
954+\[at]charset
955+T}@T{
956+/
957+T}@T{
958+T}@T{
959+T}@T{
960+T}@T{
961+UTF-8/ASCII are the only encodings supported
962+T}
963+T{
964+\[at]color-profile
965+T}@T{
966+/
967+T}@T{
968+T}@T{
969+T}@T{
970+T}@T{
971+Too new to support
972+T}
973+T{
974+\[at]container
975+T}@T{
976+T}@T{
977+T}@T{
978+T}@T{
979+T}@T{
980+T}
981+T{
982+\[at]counter-style
983+T}@T{
984+T}@T{
985+T}@T{
986+T}@T{
987+T}@T{
988+T}
989+T{
990+\[at]font-face
991+T}@T{
992+T}@T{
993+T}@T{
994+T}@T{
995+T}@T{
996+T}
997+T{
998+\[at]font-feature-values
999+T}@T{
1000+T}@T{
1001+T}@T{
1002+T}@T{
1003+T}@T{
1004+T}
1005+T{
1006+\[at]swash
1007+T}@T{
1008+/
1009+T}@T{
1010+T}@T{
1011+T}@T{
1012+T}@T{
1013+Subset of \[at]font-feature-values
1014+T}
1015+T{
1016+\[at]annotation
1017+T}@T{
1018+/
1019+T}@T{
1020+T}@T{
1021+T}@T{
1022+T}@T{
1023+Subset of \[at]font-feature-values
1024+T}
1025+T{
1026+\[at]ornaments
1027+T}@T{
1028+/
1029+T}@T{
1030+T}@T{
1031+T}@T{
1032+T}@T{
1033+Subset of \[at]font-feature-values
1034+T}
1035+T{
1036+\[at]stylistic
1037+T}@T{
1038+/
1039+T}@T{
1040+T}@T{
1041+T}@T{
1042+T}@T{
1043+Subset of \[at]font-feature-values
1044+T}
1045+T{
1046+\[at]styleset
1047+T}@T{
1048+/
1049+T}@T{
1050+T}@T{
1051+T}@T{
1052+T}@T{
1053+Subset of \[at]font-feature-values
1054+T}
1055+T{
1056+\[at]character-varient
1057+T}@T{
1058+/
1059+T}@T{
1060+T}@T{
1061+T}@T{
1062+T}@T{
1063+Subset of \[at]font-feature-values
1064+T}
1065+T{
1066+\[at]font-palette-values
1067+T}@T{
1068+T}@T{
1069+T}@T{
1070+T}@T{
1071+T}@T{
1072+T}
1073+T{
1074+\[at]import
1075+T}@T{
1076+T}@T{
1077+T}@T{
1078+T}@T{
1079+T}@T{
1080+Parsed where the first argument after \[at]import is the url and the
1081+last non parenthesized value if present is the layer name.
1082+Inbetween the url and the layer is the media queries.
1083+T}
1084+T{
1085+\[at]keyframes
1086+T}@T{
1087+T}@T{
1088+T}@T{
1089+T}@T{
1090+T}@T{
1091+T}
1092+T{
1093+\[at]layer
1094+T}@T{
1095+T}@T{
1096+T}@T{
1097+T}@T{
1098+T}@T{
1099+Currently setting the layer order via \[at]layer l1, l2; is not
1100+supported
1101+T}
1102+T{
1103+\[at]media
1104+T}@T{
1105+T}@T{
1106+T}@T{
1107+T}@T{
1108+T}@T{
1109+T}
1110+T{
1111+\[at]namespace
1112+T}@T{
1113+T}@T{
1114+T}@T{
1115+T}@T{
1116+T}@T{
1117+T}
1118+T{
1119+\[at]page
1120+T}@T{
1121+/
1122+T}@T{
1123+T}@T{
1124+T}@T{
1125+T}@T{
1126+Will not be supported, currently there are no plans to support printing
1127+T}
1128+T{
1129+\[at]position-try
1130+T}@T{
1131+T}@T{
1132+T}@T{
1133+T}@T{
1134+T}@T{
1135+Use this document to check support of features
1136+T}
1137+T{
1138+\[at]property
1139+T}@T{
1140+T}@T{
1141+T}@T{
1142+T}@T{
1143+T}@T{
1144+T}
1145+T{
1146+\[at]scope
1147+T}@T{
1148+T}@T{
1149+T}@T{
1150+T}@T{
1151+T}@T{
1152+Implementing this would cause some overhead
1153+T}
1154+T{
1155+\[at]starting-style
1156+T}@T{
1157+T}@T{
1158+T}@T{
1159+T}@T{
1160+T}@T{
1161+T}
1162+T{
1163+\[at]supports
1164+T}@T{
1165+/
1166+T}@T{
1167+T}@T{
1168+T}@T{
1169+T}@T{
1170+Use this document to check support of features
1171+T}
1172+T{
1173+\[at]view-transition
1174+T}@T{
1175+T}@T{
1176+T}@T{
1177+T}@T{
1178+T}@T{
1179+This is useful but will not be implemented until later
1180+T}
1181+.TE
1182+.SS Functions
1183+.SS Types
1184+.PP
1185+.TS
1186+tab(@);
1187+l l l l.
1188+T{
1189+Name
1190+T}@T{
1191+Support
1192+T}@T{
1193+Values
1194+T}@T{
1195+Note
1196+T}
1197+_
1198+T{
1199+AnyHover
1200+T}@T{
1201+X
1202+T}@T{
1203+None, Hover
1204+T}@T{
1205+T}
1206+T{
1207+AnyPointer
1208+T}@T{
1209+X
1210+T}@T{
1211+None, Fine, Coarse
1212+T}@T{
1213+T}
1214+T{
1215+Orientation
1216+T}@T{
1217+X
1218+T}@T{
1219+Landscape, Portrait
1220+T}@T{
1221+T}
1222+T{
1223+ColorScheme
1224+T}@T{
1225+X
1226+T}@T{
1227+Light, Dark
1228+T}@T{
1229+T}
1230+T{
1231+Contrast
1232+T}@T{
1233+X
1234+T}@T{
1235+NoPreference, More, Less
1236+T}@T{
1237+T}
1238+T{
1239+ReducedMotion
1240+T}@T{
1241+X
1242+T}@T{
1243+NoPreference, Reduce
1244+T}@T{
1245+T}
1246+T{
1247+ReducedTranparency
1248+T}@T{
1249+X
1250+T}@T{
1251+NoPreference, Reduce
1252+T}@T{
1253+T}
1254+T{
1255+Update
1256+T}@T{
1257+X
1258+T}@T{
1259+Fast, Slow
1260+T}@T{
1261+T}
1262+.TE
1263+.SS Descriptors
1264+.PP
1265+.TS
1266+tab(@);
1267+l l l l.
1268+T{
1269+Name
1270+T}@T{
1271+Support
1272+T}@T{
1273+Used by
1274+T}@T{
1275+Note
1276+T}
1277+_
1278+T{
1279+style
1280+T}@T{
1281+T}@T{
1282+\[at]container
1283+T}@T{
1284+T}
1285+T{
1286+scroll-state
1287+T}@T{
1288+\[at]container
1289+T}@T{
1290+T}@T{
1291+T}
1292+T{
1293+container
1294+T}@T{
1295+T}@T{
1296+\[at]container
1297+T}@T{
1298+T}
1299+.TE
1300+.SS Media Queries
1301+.PP
1302+.TS
1303+tab(@);
1304+lw(17.5n) lw(17.5n) lw(17.5n) lw(17.5n).
1305+T{
1306+Name
1307+T}@T{
1308+Support
1309+T}@T{
1310+Usage
1311+T}@T{
1312+Note
1313+T}
1314+_
1315+T{
1316+any-hover
1317+T}@T{
1318+X
1319+T}@T{
1320+window.setMouse(AnyPointer::Fine)
1321+T}@T{
1322+Will be set to AnyHover::Hover if AnyPointer is not AnyPointer::None,
1323+default AnyHover::Hover
1324+T}
1325+T{
1326+any-pointer
1327+T}@T{
1328+X
1329+T}@T{
1330+window.setMouse(AnyPointer::Coarse)
1331+T}@T{
1332+Default AnyPointer::Fine
1333+T}
1334+T{
1335+aspect-ratio
1336+T}@T{
1337+X
1338+T}@T{
1339+window.getAspectRatio()
1340+T}@T{
1341+Derived from width and height, returned as a double
1342+T}
1343+T{
1344+color
1345+T}@T{
1346+*
1347+T}@T{
1348+T}@T{
1349+All colors are stored as RGBA values
1350+T}
1351+T{
1352+color-gamut
1353+T}@T{
1354+*
1355+T}@T{
1356+T}@T{
1357+Only matches on \[lq]srgb\[rq]
1358+T}
1359+T{
1360+color-index
1361+T}@T{
1362+*
1363+T}@T{
1364+T}@T{
1365+Only matches on 0
1366+T}
1367+T{
1368+device-posture
1369+T}@T{
1370+*
1371+T}@T{
1372+T}@T{
1373+Only matches on \[lq]continuous\[rq]
1374+T}
1375+T{
1376+display-mode
1377+T}@T{
1378+*
1379+T}@T{
1380+T}@T{
1381+All applications will be \[lq]standalone\[rq]
1382+T}
1383+T{
1384+dynamic-range
1385+T}@T{
1386+*
1387+T}@T{
1388+T}@T{
1389+Only matches on \[lq]standard\[rq]
1390+T}
1391+T{
1392+forced-colors
1393+T}@T{
1394+*
1395+T}@T{
1396+T}@T{
1397+Only matches on \[lq]none\[rq]
1398+T}
1399+T{
1400+grid
1401+T}@T{
1402+*
1403+T}@T{
1404+T}@T{
1405+Only matches on 0
1406+T}
1407+T{
1408+height
1409+T}@T{
1410+X
1411+T}@T{
1412+window.setHeight(int)
1413+T}@T{
1414+Supports height, min-height, max-height
1415+T}
1416+T{
1417+hover
1418+T}@T{
1419+X
1420+T}@T{
1421+window.setMouse(AnyPointer::Fine)
1422+T}@T{
1423+Will match any-hover
1424+T}
1425+T{
1426+inverted-colors
1427+T}@T{
1428+*
1429+T}@T{
1430+T}@T{
1431+Only matches on \[lq]none\[rq]
1432+T}
1433+T{
1434+monochrome
1435+T}@T{
1436+*
1437+T}@T{
1438+T}@T{
1439+Only matches on 0
1440+T}
1441+T{
1442+orientation
1443+T}@T{
1444+X
1445+T}@T{
1446+window.setOrientation(Orientation::Portrait)
1447+T}@T{
1448+Defaults to Orientation::Landscape
1449+T}
1450+T{
1451+overflow-block
1452+T}@T{
1453+*
1454+T}@T{
1455+T}@T{
1456+Only matches on \[lq]scroll\[rq]
1457+T}
1458+T{
1459+overflow-inline
1460+T}@T{
1461+*
1462+T}@T{
1463+T}@T{
1464+Only matches on \[lq]scroll\[rq]
1465+T}
1466+T{
1467+pointer
1468+T}@T{
1469+X
1470+T}@T{
1471+window.setMouse(AnyPointer)
1472+T}@T{
1473+Will match any-pointer
1474+T}
1475+T{
1476+prefers-color-scheme
1477+T}@T{
1478+X
1479+T}@T{
1480+window.setColorScheme(ColorScheme::Dark)
1481+T}@T{
1482+Defaults to ColorScheme::Light
1483+T}
1484+T{
1485+prefers-contrast
1486+T}@T{
1487+X
1488+T}@T{
1489+window.setContrast(Contrast::Less)
1490+T}@T{
1491+Defaults to ColorScheme::NoPreference
1492+T}
1493+T{
1494+prefers-reduced-motion
1495+T}@T{
1496+X
1497+T}@T{
1498+window.setReducedMotion(ReducedMotion::Reduce)
1499+T}@T{
1500+Defaults to ReducedMotion::NoPreference
1501+T}
1502+T{
1503+prefers-reduced-transparency
1504+T}@T{
1505+X
1506+T}@T{
1507+window.setReducedTransparency(ReducedTransparency::Reduce)
1508+T}@T{
1509+Defaults to ReducedTransparency::NoPreference
1510+T}
1511+T{
1512+resolution
1513+T}@T{
1514+X
1515+T}@T{
1516+window.setResolution(int)
1517+T}@T{
1518+Defaults to 72dpi, accepts a int in dpi
1519+T}
1520+T{
1521+scripting
1522+T}@T{
1523+/
1524+T}@T{
1525+T}@T{
1526+Not needed
1527+T}
1528+T{
1529+update
1530+T}@T{
1531+X
1532+T}@T{
1533+window.setUpdate(Update::Slow)
1534+T}@T{
1535+Defaults to Update::Fast
1536+T}
1537+T{
1538+video-dynamic-range
1539+T}@T{
1540+*
1541+T}@T{
1542+T}@T{
1543+Only matches on \[lq]standard\[rq]
1544+T}
1545+T{
1546+width
1547+T}@T{
1548+X
1549+T}@T{
1550+window.setWidth(int)
1551+T}@T{
1552+Supports width, min-width, max-width
1553+T}
1554+.TE
1555+.SS Colors
1556+.PP
1557+.TS
1558+tab(@);
1559+lw(17.5n) lw(17.5n) lw(17.5n) lw(17.5n).
1560+T{
1561+Name
1562+T}@T{
1563+Support
1564+T}@T{
1565+Usage
1566+T}@T{
1567+Note
1568+T}
1569+_
1570+T{
1571+rgb
1572+T}@T{
1573+X
1574+T}@T{
1575+rgb(0-255, 0-255, 0-255)
1576+T}@T{
1577+You may use spaces instead of commas
1578+T}
1579+T{
1580+rgba
1581+T}@T{
1582+X
1583+T}@T{
1584+rgba(0-255, 0-255, 0-255 / 0-100%)
1585+T}@T{
1586+The alpha value MUST be a perent ranging from 0-100.
1587+You may also use spaces instead of commas
1588+T}
1589+T{
1590+hsl
1591+T}@T{
1592+X
1593+T}@T{
1594+hsl(0-360deg, 0-100%, 0-100%)
1595+T}@T{
1596+You may use spaces instead of commas
1597+T}
1598+T{
1599+hsla
1600+T}@T{
1601+X
1602+T}@T{
1603+hsla(0-360deg, 0-100%, 0-100% / 0-100%)
1604+T}@T{
1605+The alpha value MUST be a perent ranging from 0-100.
1606+You may also use spaces instead of commas
1607+T}
1608+T{
1609+hwb
1610+T}@T{
1611+X
1612+T}@T{
1613+hwb(0-360deg, 0-100%, 0-100% / 0-100%)
1614+T}@T{
1615+The alpha value MUST be a perent ranging from 0-100.
1616+You may also use spaces instead of commas
1617+T}
1618+T{
1619+lab
1620+T}@T{
1621+T}@T{
1622+T}@T{
1623+T}
1624+T{
1625+lch
1626+T}@T{
1627+T}@T{
1628+T}@T{
1629+T}
1630+T{
1631+oklab
1632+T}@T{
1633+T}@T{
1634+T}@T{
1635+T}
1636+T{
1637+oklch
1638+T}@T{
1639+T}@T{
1640+T}@T{
1641+T}
1642+T{
1643+color-mix
1644+T}@T{
1645+T}@T{
1646+T}@T{
1647+T}
1648+.TE
1649+.SS Types
1650+.PP
1651+.TS
1652+tab(@);
1653+lw(17.5n) lw(17.5n) lw(17.5n) lw(17.5n).
1654+T{
1655+Name
1656+T}@T{
1657+Support
1658+T}@T{
1659+Usage
1660+T}@T{
1661+Note
1662+T}
1663+_
1664+T{
1665+T}@T{
1666+X
1667+T}@T{
1668+xx-small, x-small, small, medium, large, x-large, xx-large, xxx-large
1669+T}@T{
1670+Based off of relative EM value
1671+T}
1672+T{
1673+T}@T{
1674+T}@T{
1675+T}@T{
1676+T}
1677+T{
1678+T}@T{
1679+T}@T{
1680+T}@T{
1681+T}
1682+T{
1683+T}@T{
1684+T}@T{
1685+T}@T{
1686+T}
1687+T{
1688+T}@T{
1689+X
1690+T}@T{
1691+baseline, first baseline, last baseline
1692+T}@T{
1693+Singular baseline computes to first baseline
1694+T}
1695+T{
1696+T}@T{
1697+/
1698+T}@T{
1699+T}@T{
1700+Will be impleamented in the future
1701+T}
1702+T{
1703+T}@T{
1704+/
1705+T}@T{
1706+T}@T{
1707+Will be impleamented in the future
1708+T}
1709+T{
1710+T}@T{
1711+X
1712+T}@T{
1713+content-box, padding-box, border-box, margin-box, fill-box, stroke-box,
1714+view-box
1715+T}@T{
1716+T}
1717+.TE
1718+.SS Other
1719+.PP
1720+.TS
1721+tab(@);
1722+l l l l.
1723+T{
1724+Name
1725+T}@T{
1726+Support
1727+T}@T{
1728+Usage
1729+T}@T{
1730+Note
1731+T}
1732+_
1733+T{
1734+Variables
1735+T}@T{
1736+X
1737+T}@T{
1738+\[en]
1739+T}@T{
1740+T}
1741+.TE
1742diff --git a/docs/content/features/supported-css-selectors.md b/docs/content/features/supported-css-selectors.md
1743index bba1024..fdc74ab 100755
1744--- a/docs/content/features/supported-css-selectors.md
1745+++ b/docs/content/features/supported-css-selectors.md
1746@@ -204,6 +204,10 @@
1747 | <basic-shape> | / | | Will be impleamented in the future |
1748 | <blend-mode> | / | | Will be impleamented in the future |
1749 | <box-edge> | X | content-box, padding-box, border-box, margin-box, fill-box, stroke-box, view-box  | |
1750+| <calc-keyword> | X | calc(NUMBER | PX | PERCENT | OPERATOR) | |
1751+| <color> | X | | See Colors |
1752+| <content-distribution> | space-between, space-around, space-evenly, stretch | |
1753+
1754 
1755 ## Other
1756 | Name | Support | Usage | Note |
1757diff --git a/include/.grim.h.swp b/include/.grim.h.swp
1758deleted file mode 100644
1759index 8bc5a6d..0000000
1760Binary files a/include/.grim.h.swp and /dev/null differ
1761diff --git a/include/grim.h b/include/grim.h
1762index 2322226..fe50ffb 100755
1763--- a/include/grim.h
1764+++ b/include/grim.h
1765@@ -158,15 +158,19 @@ enum class UnitType {
1766 	// Angle
1767 		DEG, RAD, GRAD, TURN,
1768 	// Non-unit numbers
1769-		NUMBER, E, PI, INF, NEGINF, NaN,
1770+		NUMBER, INF, NEGINF, NaN, E, PI,
1771 	// Baseline Position
1772 		FIRST, LAST,
1773 	// Box Edge
1774 		BOX_EDGE, CONTENT, PADDING, BORDER, MARGIN, FILL, STROKE, VIEW,
1775+	// Content-distribution
1776+		CONTENT_DISTRIBUTION, BETWEEN, AROUND, EVENLY, STRETCH,
1777+	// Content-position
1778+		CONTENT_POSITION, CENTER, START, FLEX_START, FLEX_END,
1779 	// Function
1780 		CALC, MIN,
1781 	// Keyword
1782-		PRINT, SCREEN, TOKEN, FUNC, OPERATOR, GROUP,
1783+		PRINT, SCREEN, TOKEN, FUNC, OPERATOR, GROUP, END,
1784 	// Property
1785 		BACKGROUND_COLOR, BASELINE
1786 };
1787@@ -184,7 +188,6 @@ union UnitValue {
1788 struct Unit {
1789 	UnitType type;
1790 	UnitValue value;
1791-	std::vector<Unit> children;
1792 };
1793 
1794 enum class SheetType {
1795diff --git a/src/.parser.cc.swp b/src/.parser.cc.swp
1796deleted file mode 100644
1797index 7e2ab09..0000000
1798Binary files a/src/.parser.cc.swp and /dev/null differ
1799diff --git a/src/parser.cc b/src/parser.cc
1800index 3d514b6..5a1429b 100755
1801--- a/src/parser.cc
1802+++ b/src/parser.cc
1803@@ -336,7 +336,7 @@ std::unique_ptr<Node> parseHTML(std::istream& inputStream) {
1804 	return root;
1805 }
1806 
1807-
1808+/*
1809 void typeCheck(std::string key, std::string value, Unit* property, std::vector<UnitType> allowedTypes) {
1810 	for (size_t i = 0; i < property->children.size(); i++) {
1811 		bool allowed = false;
1812@@ -353,6 +353,7 @@ void typeCheck(std::string key, std::string value, Unit* property, std::vector<U
1813 		}
1814 	}	
1815 }
1816+*/
1817 
1818 struct SuffixParse {
1819 	std::string_view suffix;
1820@@ -399,12 +400,37 @@ static constexpr SuffixParse table[] = {
1821 	{"q",     UnitType::Q,     1},
1822 };
1823 
1824-static const std::unordered_map<std::string_view, UnitType> kOp{
1825-	{"+", UnitType::ADD}, {"-", UnitType::SUB}, {"*", UnitType::MULT},
1826-	{"/", UnitType::DIV}, {"==",UnitType::EQ}, {">", UnitType::GT},
1827-	{"<", UnitType::LT}, {">=",UnitType::GE}, {"<=",UnitType::LE},
1828-	{"e", UnitType::E}, {"pi", UnitType::PI}, {"infinity", UnitType::INF},
1829-	{"-infinity", UnitType::NEGINF}, {"NaN", UnitType::NaN}
1830+static const std::unordered_map<std::string_view, std::pair<UnitType, UnitType>> kMatch{
1831+	{"+",{UnitType::OPERATOR, UnitType::ADD}},
1832+	{"-",{UnitType::OPERATOR, UnitType::SUB}},
1833+	{"*",{UnitType::OPERATOR, UnitType::MULT}},
1834+	{"/",{UnitType::OPERATOR, UnitType::DIV}},
1835+	{"==", {UnitType::OPERATOR, UnitType::EQ}},
1836+	{">",{UnitType::OPERATOR, UnitType::GT}},
1837+	{"<",{UnitType::OPERATOR, UnitType::LT}},
1838+	{">=",{UnitType::OPERATOR, UnitType::GE}},
1839+	{"<=",{UnitType::OPERATOR, UnitType::LE}},
1840+	{"infinity",{UnitType::TOKEN, UnitType::INF}},
1841+	{"-infinity",{UnitType::TOKEN, UnitType::NEGINF}},
1842+	{"NaN",{UnitType::TOKEN, UnitType::NaN}},
1843+	{"e",{UnitType::TOKEN, UnitType::E}},
1844+	{"pi",{UnitType::TOKEN, UnitType::PI}},
1845+	{"content-box",{UnitType::BOX_EDGE, UnitType::CONTENT}},
1846+	{"padding-box",{UnitType::BOX_EDGE, UnitType::PADDING}},
1847+	{"border-box",{UnitType::BOX_EDGE, UnitType::BORDER}},
1848+	{"margin-box",{UnitType::BOX_EDGE, UnitType::MARGIN}},
1849+	{"fill-box",{UnitType::BOX_EDGE, UnitType::FILL}},
1850+	{"stroke-box",{UnitType::BOX_EDGE, UnitType::STROKE}},
1851+	{"view-box",{UnitType::BOX_EDGE, UnitType::VIEW}},
1852+	{"space-between",{UnitType::CONTENT_DISTRIBUTION, UnitType::BETWEEN}},
1853+	{"space-around",{UnitType::CONTENT_DISTRIBUTION, UnitType::AROUND}},
1854+	{"space-evenly",{UnitType::CONTENT_DISTRIBUTION, UnitType::EVENLY}},
1855+	{"stretch",{UnitType::CONTENT_DISTRIBUTION, UnitType::STRETCH}},
1856+	{"center",{UnitType::CONTENT_POSITION, UnitType::CENTER}},
1857+	{"start",{UnitType::CONTENT_POSITION, UnitType::START}},
1858+	{"end",{UnitType::CONTENT_POSITION, UnitType::END}},
1859+	{"flex-start",{UnitType::CONTENT_POSITION, UnitType::FLEX_START}},
1860+	{"flex-end",{UnitType::CONTENT_POSITION, UnitType::FLEX_END}},
1861 };
1862 
1863 static const std::unordered_map<std::string_view, float> kAbsSize{
1864@@ -459,23 +485,31 @@ std::vector<Unit> getUnit(std::string value) {
1865 			}
1866 
1867 			std::vector<Unit> children = getUnit(value);
1868+			
1869 			Unit unit;
1870-			unit.type = UnitType::FUNC;
1871 
1872 			if (name == "calc") {
1873-				unit.value.ENUM = UnitType::CALC;
1874+				unit.type = UnitType::CALC;
1875 			} else if (name == "min") {
1876-				unit.value.ENUM = UnitType::MIN;
1877+				unit.type = UnitType::MIN;
1878+			} else if (name == "rgb") {
1879+				unit.type = UnitType::RGB;
1880+			} else if (name == "rgba") {
1881+				unit.type = UnitType::RGBA;
1882+			} else if (name == "hsl") {
1883+				unit.type = UnitType::HSL;
1884+			} else if (name == "hwb") {
1885+				unit.type = UnitType::HWB;
1886 			} else if (name == "") {
1887-				unit.value.ENUM = UnitType::GROUP;
1888+				unit.type = UnitType::GROUP;
1889 			}
1890 
1891-			if (children.size() > 0) {
1892-				unit.children = children;
1893-				children.clear();
1894-			}
1895+			unit.value.INT = children.size();
1896 
1897 			units.push_back(unit);
1898+			units.insert(units.end(), children.begin(), children.end());
1899+			// Add a end value for the function
1900+
1901 			buffer.clear();
1902 		} else if ((!inQuotes && (v == ',' ||  std::isspace(v))) || i >= value.length()-1) {
1903 			if (v != ',' && !std::isspace(v)) buffer.push_back(v);
1904@@ -485,13 +519,18 @@ std::vector<Unit> getUnit(std::string value) {
1905 			// Split by spaces into parts
1906 
1907 			bool found = false;
1908-
1909-			for (const auto& [suffix, type, trim] : table) {
1910-				if (buffer.ends_with(suffix)) {
1911-					unit.value.FLOAT = std::stof(std::string(buffer.substr(0, buffer.size() - trim)));
1912-					unit.type = type;
1913-					found = true;
1914-					break;
1915+			if (auto it = kMatch.find(buffer); it != kMatch.end()) { 
1916+				unit.type = it->second.first;
1917+				unit.value.ENUM = it->second.second;
1918+				found = true;
1919+			} else {
1920+				for (const auto& [suffix, type, trim] : table) {
1921+					if (buffer.ends_with(suffix)) {
1922+						unit.value.FLOAT = std::stof(std::string(buffer.substr(0, buffer.size() - trim)));
1923+						unit.type = type;
1924+						found = true;
1925+						break;
1926+					}
1927 				}
1928 			}
1929 
1930@@ -500,10 +539,6 @@ std::vector<Unit> getUnit(std::string value) {
1931 					unit.type = UnitType::HEX;
1932 					unit.value.UINT = std::stoul(buffer.substr(1), nullptr, 16);
1933 					found = true;
1934-				} else if (auto it = kOp.find(buffer); it != kOp.end()) { 
1935-					unit.type = UnitType::OPERATOR;
1936-					unit.value.ENUM = it->second;
1937-					found = true;
1938 				} else if (auto it = kAbsSize.find(buffer); it != kAbsSize.end()) { 
1939 					unit.type = UnitType::EM;
1940 					unit.value.FLOAT = it->second;
1941@@ -514,17 +549,6 @@ std::vector<Unit> getUnit(std::string value) {
1942 					else if (buffer.starts_with("last")) unit.value.ENUM = UnitType::LAST;
1943 					else unit.value.ENUM = UnitType::FIRST;
1944 					found = true;
1945-				} else if (buffer.ends_with("-box")) {
1946-					unit.type = UnitType::BOX_EDGE;
1947-
1948-					if (buffer.starts_with("content")) unit.value.ENUM = UnitType::CONTENT;
1949-					else if (buffer.starts_with("padding")) unit.value.ENUM = UnitType::PADDING;
1950-					else if (buffer.starts_with("border")) unit.value.ENUM = UnitType::BORDER;
1951-					else if (buffer.starts_with("margin")) unit.value.ENUM = UnitType::MARGIN;
1952-					else if (buffer.starts_with("fill")) unit.value.ENUM = UnitType::FILL;
1953-					else if (buffer.starts_with("stroke")) unit.value.ENUM = UnitType::STROKE;
1954-					else if (buffer.starts_with("view")) unit.value.ENUM = UnitType::VIEW;
1955-					found = true;
1956 				} else {
1957 					// Maybe its a number?
1958 					try {
1959diff --git a/tests/.css_unit.cc.swp b/tests/.css_unit.cc.swp
1960index bc83178..9fda70f 100644
1961Binary files a/tests/.css_unit.cc.swp and b/tests/.css_unit.cc.swp differ
1962diff --git a/tests/css_unit.cc b/tests/css_unit.cc
1963index 0198810..ca96159 100644
1964--- a/tests/css_unit.cc
1965+++ b/tests/css_unit.cc
1966@@ -6,49 +6,85 @@
1967 
1968 
1969 TEST_CASE("getUnit can parse color values") {
1970-/*
1971-	unsigned int base = 0xff7dff1a;
1972-
1973 	SECTION("getUnit can parse hex") {
1974-		Unit test = getUnit("#ff7dff1a");
1975-		INFO(test.value.UINT);
1976-		REQUIRE(base == test.value.UINT);
1977+		std::vector<Unit> test = getUnit("#ff7dff1a");
1978+		INFO(test[0].value.UINT);
1979+		REQUIRE(0xff7dff1a == test[0].value.UINT);
1980 	};
1981 
1982 	SECTION("getUnit can parse rgba") {
1983-		Unit test = getUnit("rgba(255 125 255 / 10%)");
1984-		INFO(test.value.UINT);
1985-		// Due to type casting 0.1 will return 25 not 26 or 19 vs 1a
1986-		REQUIRE(0xff7dff19 == test.value.UINT);
1987-	}
1988+		std::vector<Unit> test = getUnit("rgba(255 125 255 / 10%)");
1989+		REQUIRE(test[0].type == UnitType::RGBA);
1990+		REQUIRE(test[0].value.INT == 5);
1991+		REQUIRE(test[1].type == UnitType::NUMBER);
1992+		REQUIRE(test[1].value.FLOAT == 255.0f);
1993+		REQUIRE(test[2].type == UnitType::NUMBER);
1994+		REQUIRE(test[2].value.FLOAT == 125.0f);
1995+		REQUIRE(test[3].type == UnitType::NUMBER);
1996+		REQUIRE(test[3].value.FLOAT == 255.0f);
1997+		REQUIRE(test[4].type == UnitType::OPERATOR);
1998+		REQUIRE(test[4].value.ENUM == UnitType::DIV);
1999+		REQUIRE(test[5].type == UnitType::PERCENT);
2000+		REQUIRE(test[5].value.FLOAT == 10.0f);
2001+	};
2002 
2003 	SECTION("getUnit can parse rgb") {
2004-		Unit test = getUnit("rgb(255 125 255)");
2005-		INFO(test.value.UINT);
2006-		// Due to type casting 0.1 will return 25 not 26 or 19 vs 1a
2007-		REQUIRE(0xff7dff00 == test.value.UINT);
2008+		std::vector<Unit> test = getUnit("rgb(255, 125, 255)");
2009+		REQUIRE(test[0].type == UnitType::RGB);
2010+		REQUIRE(test[0].value.INT == 3);
2011+		REQUIRE(test[1].type == UnitType::NUMBER);
2012+		REQUIRE(test[1].value.FLOAT == 255.0f);
2013+		REQUIRE(test[2].type == UnitType::NUMBER);
2014+		REQUIRE(test[2].value.FLOAT == 125.0f);
2015+		REQUIRE(test[3].type == UnitType::NUMBER);
2016+		REQUIRE(test[3].value.FLOAT == 255.0f);
2017 	}
2018 
2019 	SECTION("getUnit can parse hsl") {
2020-		Unit test = getUnit("hsl(300deg 100% 74.51%)");
2021-		INFO(test.value.UINT);
2022-		// Due to type casting 0.1 will return 25 not 26 or 19 vs 1a
2023-		REQUIRE(0xff7afe00 == test.value.UINT);
2024+		std::vector<Unit> t = getUnit("hsl(300deg 100% 74.51%)");
2025+		REQUIRE(t[0].type == UnitType::HSL);
2026+		REQUIRE(t[0].value.INT == 3);
2027+		REQUIRE(t[1].type == UnitType::DEG);
2028+		REQUIRE(t[1].value.FLOAT == 300.0f);
2029+		REQUIRE(t[2].type == UnitType::PERCENT);
2030+		REQUIRE(t[2].value.FLOAT == 100.0f);
2031+		REQUIRE(t[3].type == UnitType::PERCENT);
2032+		REQUIRE(t[3].value.FLOAT == 74.51f);
2033+
2034 	}
2035 
2036 	SECTION("getUnit can parse hsla") {
2037-		Unit test = getUnit("hsl(300deg 100% 74.51% / 10%)");
2038-		INFO(test.value.UINT);
2039-		// Due to type casting 0.1 will return 25 not 26 or 19 vs 1a
2040-		REQUIRE(0xff7afe19 == test.value.UINT);
2041+		std::vector<Unit> t = getUnit("hsl(300deg 100% 74.51% / 10%)");
2042+		REQUIRE(t[0].type == UnitType::HSL);
2043+		REQUIRE(t[0].value.INT == 5);
2044+		REQUIRE(t[1].type == UnitType::DEG);
2045+		REQUIRE(t[1].value.FLOAT == 300.0f);
2046+		REQUIRE(t[2].type == UnitType::PERCENT);
2047+		REQUIRE(t[2].value.FLOAT == 100.0f);
2048+		REQUIRE(t[3].type == UnitType::PERCENT);
2049+		REQUIRE(t[3].value.FLOAT == 74.51f);
2050+		REQUIRE(t[4].type == UnitType::OPERATOR);
2051+		REQUIRE(t[4].value.ENUM == UnitType::DIV);
2052+		REQUIRE(t[5].type == UnitType::PERCENT);
2053+		REQUIRE(t[5].value.FLOAT == 10.0f);
2054 	}
2055 
2056 	SECTION("getUnit can parse hwb") {
2057-		Unit test = getUnit("hwb(80deg 20 50 / 50%)");
2058-		INFO(test.value.UINT);
2059-		// Due to type casting 0.1 will return 25 not 26 or 19 vs 1a
2060-		REQUIRE(0x667f337f == test.value.UINT);
2061-	}*/
2062+		std::vector<Unit> t = getUnit("hwb(80deg 20 50 / 50%)");
2063+		REQUIRE(t[0].type == UnitType::HWB);
2064+		REQUIRE(t[0].value.INT == 5);
2065+		REQUIRE(t[1].type == UnitType::DEG);
2066+		REQUIRE(t[1].value.FLOAT == 80.0f);
2067+		REQUIRE(t[2].type == UnitType::NUMBER);
2068+		REQUIRE(t[2].value.FLOAT == 20.0f);
2069+		REQUIRE(t[3].type == UnitType::NUMBER);
2070+		REQUIRE(t[3].value.FLOAT == 50.0f);
2071+		REQUIRE(t[4].type == UnitType::OPERATOR);
2072+		REQUIRE(t[4].value.ENUM == UnitType::DIV);
2073+		REQUIRE(t[5].type == UnitType::PERCENT);
2074+		REQUIRE(t[5].value.FLOAT == 50.0f);
2075+	}
2076+
2077 	// px
2078 	SECTION("getUnit can parse px") {
2079 		std::vector<Unit> test = getUnit("10px 10.5px");
2080@@ -498,138 +534,202 @@ TEST_CASE("getUnit can parse color values") {
2081 	// calc
2082 	SECTION("getUnit can parse calc") {
2083 		std::vector<Unit> test = getUnit("calc(10px)");
2084-		REQUIRE(UnitType::CALC == test[0].value.ENUM);
2085-		REQUIRE(UnitType::FUNC == test[0].type);
2086+		REQUIRE(UnitType::CALC == test[0].type);
2087+		REQUIRE(1 == test[0].value.INT);
2088 
2089-		REQUIRE(10.0f == test[0].children[0].value.FLOAT);
2090-		REQUIRE(UnitType::PX == test[0].children[0].type);
2091+		REQUIRE(10.0f == test[1].value.FLOAT);
2092+		REQUIRE(UnitType::PX == test[1].type);
2093 	}
2094 
2095 	SECTION("getUnit can parse calc with add") {
2096 		std::vector<Unit> test = getUnit("calc(10px + 14%)");
2097-		REQUIRE(UnitType::CALC == test[0].value.ENUM);
2098-		REQUIRE(UnitType::FUNC == test[0].type);
2099+		REQUIRE(UnitType::CALC == test[0].type);
2100+		REQUIRE(3 == test[0].value.INT);
2101 
2102-		REQUIRE(10.0f == test[0].children[0].value.FLOAT);
2103-		REQUIRE(UnitType::PX == test[0].children[0].type);
2104+		REQUIRE(10.0f == test[1].value.FLOAT);
2105+		REQUIRE(UnitType::PX == test[1].type);
2106 
2107-		REQUIRE(UnitType::ADD == test[0].children[1].value.ENUM);
2108-		REQUIRE(UnitType::OPERATOR == test[0].children[1].type);
2109+		REQUIRE(UnitType::ADD == test[2].value.ENUM);
2110+		REQUIRE(UnitType::OPERATOR == test[2].type);
2111 
2112-		REQUIRE(14.0f == test[0].children[2].value.FLOAT);
2113-		REQUIRE(UnitType::PERCENT == test[0].children[2].type);
2114+		REQUIRE(14.0f == test[3].value.FLOAT);
2115+		REQUIRE(UnitType::PERCENT == test[3].type);
2116 	}
2117 
2118 
2119 	// ---------- 1.  Whitespace handling ----------
2120 	SECTION("calc ignores leading / trailing spaces and tabs") {
2121 		std::vector<Unit> t = getUnit("  calc(  50vmin  )  ");
2122-		REQUIRE(t[0].type == UnitType::FUNC);
2123-		REQUIRE(t[0].value.ENUM == UnitType::CALC);
2124-		REQUIRE(t[0].children[0].value.FLOAT == 50.0f);
2125-		REQUIRE(t[0].children[0].type == UnitType::VMIN);
2126+		REQUIRE(t[0].type == UnitType::CALC);
2127+		REQUIRE(t[0].value.INT == 1);
2128+		REQUIRE(t[1].value.FLOAT == 50.0f);
2129+		REQUIRE(t[1].type == UnitType::VMIN);
2130 	}
2131 
2132 	// ---------- 2.  Subtraction ----------
2133 	SECTION("calc with subtraction") {
2134 		std::vector<Unit> t = getUnit("calc(100% - 2em)");
2135-		REQUIRE(t[0].value.ENUM == UnitType::CALC);
2136-		REQUIRE(t[0].children[1].value.ENUM == UnitType::SUB);
2137-		REQUIRE(t[0].children[1].type == UnitType::OPERATOR);
2138-		REQUIRE(t[0].children[2].value.FLOAT == 2.0f);
2139-		REQUIRE(t[0].children[2].type == UnitType::EM);
2140+		REQUIRE(t[0].type == UnitType::CALC);
2141+		REQUIRE(t[2].value.ENUM == UnitType::SUB);
2142+		REQUIRE(t[2].type == UnitType::OPERATOR);
2143+		REQUIRE(t[3].value.FLOAT == 2.0f);
2144+		REQUIRE(t[3].type == UnitType::EM);
2145 	}
2146 
2147 	// ---------- 3.  Multiplication ----------
2148 	SECTION("calc with multiply") {
2149 		std::vector<Unit> t = getUnit("calc(3 * 4.5rem)");
2150-		REQUIRE(t[0].children[1].value.ENUM == UnitType::MULT);
2151-		REQUIRE(t[0].children[2].value.FLOAT == 4.5f);
2152-		REQUIRE(t[0].children[2].type == UnitType::REM);
2153+		REQUIRE(t[2].value.ENUM == UnitType::MULT);
2154+		REQUIRE(t[3].value.FLOAT == 4.5f);
2155+		REQUIRE(t[3].type == UnitType::REM);
2156 	}
2157 
2158 	// ---------- 4.  Division ----------
2159 	SECTION("calc with divide") {
2160 		std::vector<Unit> t = getUnit("calc(90deg / 3)");
2161-		REQUIRE(t[0].children[1].value.ENUM == UnitType::DIV);
2162-		REQUIRE(t[0].children[2].value.FLOAT == 3.0f);
2163-		REQUIRE(t[0].children[0].type == UnitType::DEG);
2164+		REQUIRE(t[2].value.ENUM == UnitType::DIV);
2165+		REQUIRE(t[3].value.FLOAT == 3.0f);
2166+		REQUIRE(t[1].type == UnitType::DEG);
2167 	}
2168 
2169 	// ---------- 5.  Chained operators ----------
2170 	SECTION("calc with three terms and two ops") {
2171 		std::vector<Unit> t = getUnit("calc(10px + 20px - 5px)");
2172-		REQUIRE(t[0].children.size() == 5);          // px  +  px  -  px
2173-		REQUIRE(t[0].children[1].value.ENUM == UnitType::ADD);
2174-		REQUIRE(t[0].children[3].value.ENUM == UnitType::SUB);
2175+		REQUIRE(t[0].value.INT == 5); // px  +  px  -  px
2176+		REQUIRE(t[2].value.ENUM == UnitType::ADD);
2177+		REQUIRE(t[4].value.ENUM == UnitType::SUB);
2178 	}
2179 
2180 	// ---------- 6.  Parentheses ----------
2181 	SECTION("calc nested parentheses") {
2182 		std::vector<Unit> t = getUnit("calc((2 * 3em) + 4px)");
2183 		// The first child should be the subtree for the parens
2184-		REQUIRE(t[0].type == UnitType::FUNC);
2185-		REQUIRE(t[0].children[0].value.ENUM == UnitType::GROUP);
2186-		REQUIRE(t[0].children[2].type == UnitType::PX);
2187+		REQUIRE(t[0].type == UnitType::CALC);
2188+		REQUIRE(t[0].value.INT == 6);
2189+		REQUIRE(t[0].type == UnitType::CALC);
2190+		REQUIRE(t[1].value.INT == 3);
2191+		REQUIRE(t[6].type == UnitType::PX);
2192 	}
2193 
2194 	// ---------- 7.  Constants ----------
2195 	SECTION("calc with pi") {
2196 		std::vector<Unit> t = getUnit("calc(pi * 30px)");
2197-		REQUIRE(t[0].children[0].value.ENUM == UnitType::PI);
2198-		REQUIRE(t[0].children[1].value.ENUM == UnitType::MULT);
2199-		REQUIRE(t[0].children[2].value.FLOAT == 30.0f);
2200+		REQUIRE(t[1].value.ENUM == UnitType::PI);
2201+		REQUIRE(t[2].value.ENUM == UnitType::MULT);
2202+		REQUIRE(t[3].value.FLOAT == 30.0f);
2203 	}
2204 
2205 	// ---------- 8.  Negative numbers ----------
2206 	SECTION("calc with negative value") {
2207 		std::vector<Unit> t = getUnit("calc(-15vw + 10vw)");
2208-		REQUIRE(t[0].children[0].value.FLOAT == -15.0f);
2209-		REQUIRE(t[0].children[0].type == UnitType::VW);
2210+		REQUIRE(t[1].value.FLOAT == -15.0f);
2211+		REQUIRE(t[1].type == UnitType::VW);
2212 	}
2213 
2214 	// ---------- 9.  Zero unit ----------
2215 	SECTION("calc with zero px") {
2216 		std::vector<Unit> t = getUnit("calc(0px + 5px)");
2217-		REQUIRE(t[0].children[0].value.FLOAT == 0.0f);
2218-		REQUIRE(t[0].children[0].type == UnitType::PX);
2219+		REQUIRE(t[1].value.FLOAT == 0.0f);
2220+		REQUIRE(t[1].type == UnitType::PX);
2221 	}
2222 
2223 	// ---------- 10.  Scientific notation ----------
2224 	SECTION("calc with scientific notation") {
2225 		std::vector<Unit> t = getUnit("calc(1.2e3px)");
2226-		REQUIRE(t[0].children[0].value.FLOAT == 1200.0f);
2227-		REQUIRE(t[0].children[0].type == UnitType::PX);
2228+		REQUIRE(t[1].value.FLOAT == 1200.0f);
2229+		REQUIRE(t[1].type == UnitType::PX);
2230 	}
2231 
2232 	// ---------- 11.  Many spaces around operator ----------
2233 	SECTION("calc with huge whitespace gap") {
2234 		std::vector<Unit> t = getUnit("calc(50px     *     2)");
2235-		REQUIRE(t[0].children[1].value.ENUM == UnitType::MULT);
2236+		REQUIRE(t[2].value.ENUM == UnitType::MULT);
2237 	}
2238 
2239 	// ---------- 12.  Double negation ----------
2240 	SECTION("calc with double negation") {
2241 		std::vector<Unit> t = getUnit("calc(10px - -5px)");
2242-		REQUIRE(t[0].children[2].value.FLOAT == -5.0f);
2243-		REQUIRE(t[0].children[1].value.ENUM == UnitType::SUB);
2244+		REQUIRE(t[3].value.FLOAT == -5.0f);
2245+		REQUIRE(t[2].value.ENUM == UnitType::SUB);
2246 	}
2247 
2248 	// ---------- 13.  Mixed units ----------
2249 	SECTION("calc mixed vw and px") {
2250 		std::vector<Unit> t = getUnit("calc(100vw - 20px)");
2251-		REQUIRE(t[0].children[0].type == UnitType::VW);
2252-		REQUIRE(t[0].children[2].type == UnitType::PX);
2253+		REQUIRE(t[1].type == UnitType::VW);
2254+		REQUIRE(t[3].type == UnitType::PX);
2255 	}
2256 
2257 	// ---------- 14.  Functions inside calc ----------
2258 	SECTION("calc with nested function") {
2259 		std::vector<Unit> t = getUnit("calc(min(10px, 20px) + 5px)");
2260 		// first child should be the min() subtree
2261-		REQUIRE(t[0].children[0].type == UnitType::FUNC);
2262-		REQUIRE(t[0].children[2].value.FLOAT == 5.0f);
2263+		REQUIRE(t[1].type == UnitType::MIN);
2264+		REQUIRE(t[5].value.FLOAT == 5.0f);
2265+	}
2266+
2267+	SECTION("calc with infinity") {
2268+		std::vector<Unit> t = getUnit("calc(infinity)");
2269+		REQUIRE(t[1].type == UnitType::TOKEN);
2270+		REQUIRE(t[1].value.ENUM == UnitType::INF);
2271+	}
2272+
2273+	SECTION("calc with negative infinity") {
2274+		std::vector<Unit> t = getUnit("calc(-infinity)");
2275+		REQUIRE(t[1].type == UnitType::TOKEN);
2276+		REQUIRE(t[1].value.ENUM == UnitType::NEGINF);
2277+		t = getUnit("calc(1 - -infinity)");
2278+		REQUIRE(t[1].type == UnitType::NUMBER);
2279+		REQUIRE(t[2].type == UnitType::OPERATOR);
2280+		REQUIRE(t[3].type == UnitType::TOKEN);
2281+		REQUIRE(t[3].value.ENUM == UnitType::NEGINF);
2282+	}
2283+
2284+	SECTION("calc with NaN") {
2285+		std::vector<Unit> t = getUnit("calc(NaN)");
2286+		REQUIRE(t[1].type == UnitType::TOKEN);
2287+		REQUIRE(t[1].value.ENUM == UnitType::NaN);
2288+	}
2289+	
2290+	SECTION("calc with E") {
2291+		std::vector<Unit> t = getUnit("calc(e)");
2292+		REQUIRE(t[1].type == UnitType::TOKEN);
2293+		REQUIRE(t[1].value.ENUM == UnitType::E);
2294 	}
2295 
2296+	SECTION("content-distribution space-between") {
2297+		std::vector<Unit> t = getUnit("space-between");
2298+		REQUIRE(t[0].type == UnitType::CONTENT_DISTRIBUTION);
2299+		REQUIRE(t[0].value.ENUM == UnitType::BETWEEN);
2300+	}
2301 
2302+	SECTION("content-distribution space-around") {
2303+		std::vector<Unit> t = getUnit("space-around");
2304+		REQUIRE(t[0].type == UnitType::CONTENT_DISTRIBUTION);
2305+		REQUIRE(t[0].value.ENUM == UnitType::AROUND);
2306+	}
2307+	SECTION("content-distribution space-between") {
2308+		std::vector<Unit> t = getUnit("space-evenly");
2309+		REQUIRE(t[0].type == UnitType::CONTENT_DISTRIBUTION);
2310+		REQUIRE(t[0].value.ENUM == UnitType::EVENLY);
2311+	}
2312+	SECTION("content-distribution stretch") {
2313+		std::vector<Unit> t = getUnit("stretch");
2314+		REQUIRE(t[0].type == UnitType::CONTENT_DISTRIBUTION);
2315+		REQUIRE(t[0].value.ENUM == UnitType::STRETCH);
2316+	}
2317 
2318 }
2319+
2320+/*
2321+TEST_CASE("BENCHMARKS") {
2322+BENCHMARK("number") {
2323+	std::vector<Unit> t = getUnit("10");
2324+//	std::cout << sizeof(t) << std::endl;
2325+	std::cout << sizeof(t[0].type) << std::endl;
2326+};
2327+BENCHMARK("calc") {
2328+	std::vector<Unit> t = getUnit("calc(10 + 100%)");
2329+//	std::cout << sizeof(t) << std::endl;
2330+};
2331+}*/