(define tw-sizes {:xs "font-size:0.75rem;line-height:1rem" :3xl "font-size:1.875rem;line-height:2.25rem" :7xl "font-size:4.5rem;line-height:1" :sm "font-size:0.875rem;line-height:1.25rem" :8xl "font-size:6rem;line-height:1" :xl "font-size:1.25rem;line-height:1.75rem" :6xl "font-size:3.75rem;line-height:1" :9xl "font-size:8rem;line-height:1" :5xl "font-size:3rem;line-height:1" :lg "font-size:1.125rem;line-height:1.75rem" :2xl "font-size:1.5rem;line-height:2rem" :base "font-size:1rem;line-height:1.5rem" :4xl "font-size:2.25rem;line-height:2.5rem"})

(define tw-weights {:light "300" :semibold "600" :bold "700" :extrabold "800" :black "900" :extralight "200" :thin "100" :medium "500" :normal "400"})

(define tw-families {:mono "ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace" :sans "ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif" :serif "ui-serif,Georgia,Cambria,\"Times New Roman\",Times,serif"})

(define tw-alignments {:center true :end true :left true :right true :start true :justify true})

(define tw-leading {:tight "1.25" :9 "2.25rem" :loose "2" :relaxed "1.625" :3 "0.75rem" :8 "2rem" :5 "1.25rem" :4 "1rem" :6 "1.5rem" :snug "1.375" :none "1" :normal "1.5" :7 "1.75rem" :10 "2.5rem"})

(define tw-tracking {:wide "0.025em" :tight "-0.025em" :tighter "-0.05em" :wider "0.05em" :widest "0.1em" :normal "0em"})

(define
  tw-resolve-type
  (fn
    (token)
    (let
      ((parts (split token "-"))
        (head (first parts))
        (rest (slice parts 1)))
      (cond
        (and
          (= head "text")
          (= (len rest) 1)
          (not (nil? (get tw-sizes (first rest)))))
        (get tw-sizes (first rest))
        (and
          (= head "text")
          (= (len rest) 1)
          (get tw-alignments (first rest)))
        (str "text-align:" (first rest))
        (and
          (= (len parts) 1)
          (or
            (= head "uppercase")
            (= head "lowercase")
            (= head "capitalize")))
        (str "text-transform:" head)
        (and (= (len parts) 2) (= head "normal") (= (first rest) "case"))
        "text-transform:none"
        (and
          (= head "font")
          (= (len rest) 1)
          (not (nil? (get tw-weights (first rest)))))
        (str "font-weight:" (get tw-weights (first rest)))
        (and
          (= head "font")
          (= (len rest) 1)
          (not (nil? (get tw-families (first rest)))))
        (str "font-family:" (get tw-families (first rest)))
        (and (= (len parts) 1) (= head "italic"))
        "font-style:italic"
        (and (= (len parts) 2) (= head "not") (= (first rest) "italic"))
        "font-style:normal"
        (and (= head "leading") (= (len rest) 1))
        (let
          ((val (get tw-leading (first rest))))
          (if (nil? val) nil (str "line-height:" val)))
        (and (= head "tracking") (= (len rest) 1))
        (let
          ((val (get tw-tracking (first rest))))
          (if (nil? val) nil (str "letter-spacing:" val)))
        (and (= head "whitespace") (= (len rest) 1))
        (case
          (first rest)
          "normal"
          "white-space:normal"
          "nowrap"
          "white-space:nowrap"
          "pre"
          "white-space:pre"
          "pre-line"
          "white-space:pre-line"
          "pre-wrap"
          "white-space:pre-wrap"
          "break-spaces"
          "white-space:break-spaces"
          :else nil)
        (and (= head "whitespace") (= (len rest) 2))
        (let
          ((val (join "-" rest)))
          (case
            val
            "pre-line"
            "white-space:pre-line"
            "pre-wrap"
            "white-space:pre-wrap"
            "break-spaces"
            "white-space:break-spaces"
            :else nil))
        (and (= head "break") (= (len rest) 1))
        (case
          (first rest)
          "normal"
          "overflow-wrap:normal;word-break:normal"
          "words"
          "overflow-wrap:break-word"
          "all"
          "word-break:break-all"
          "keep"
          "word-break:keep-all"
          :else nil)
        (and (= (len parts) 1) (= head "truncate"))
        "overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
        (and (= head "line") (= (len rest) 2) (= (first rest) "clamp"))
        (let
          ((val (nth rest 1)))
          (if
            (= val "none")
            "overflow:visible;display:block;-webkit-line-clamp:unset"
            (let
              ((n (parse-int val nil)))
              (if
                (nil? n)
                nil
                (str
                  "overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:"
                  n)))))
        (and (= head "indent") (= (len rest) 1))
        (let
          ((v (tw-spacing-value (first rest))))
          (if (nil? v) nil (str "text-indent:" v)))
        (and (= head "align") (= (len rest) 1))
        (case
          (first rest)
          "baseline"
          "vertical-align:baseline"
          "top"
          "vertical-align:top"
          "middle"
          "vertical-align:middle"
          "bottom"
          "vertical-align:bottom"
          "text-top"
          "vertical-align:text-top"
          "text-bottom"
          "vertical-align:text-bottom"
          "sub"
          "vertical-align:sub"
          "super"
          "vertical-align:super"
          :else nil)
        (and (= head "align") (= (len rest) 2))
        (let
          ((val (join "-" rest)))
          (case
            val
            "text-top"
            "vertical-align:text-top"
            "text-bottom"
            "vertical-align:text-bottom"
            :else nil))
        (and (= head "list") (= (len rest) 1))
        (case
          (first rest)
          "none"
          "list-style-type:none"
          "disc"
          "list-style-type:disc"
          "decimal"
          "list-style-type:decimal"
          "inside"
          "list-style-position:inside"
          "outside"
          "list-style-position:outside"
          :else nil)
        (and
          (= head "text")
          (= (len rest) 1)
          (or
            (= (first rest) "wrap")
            (= (first rest) "nowrap")
            (= (first rest) "balance")
            (= (first rest) "pretty")))
        (str "text-wrap:" (first rest))
        (and (= head "hyphens") (= (len rest) 1))
        (str "hyphens:" (first rest))
        (and (= head "content") (= (len rest) 1) (= (first rest) "none"))
        "content:none"
        (and (= (len parts) 1) (= head "antialiased"))
        "-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale"
        (and
          (= (len parts) 2)
          (= head "subpixel")
          (= (first rest) "antialiased"))
        "-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto"
        (and (= (len parts) 2) (= (first rest) "nums"))
        (case
          head
          "tabular"
          "font-variant-numeric:tabular-nums"
          "proportional"
          "font-variant-numeric:proportional-nums"
          "lining"
          "font-variant-numeric:lining-nums"
          "oldstyle"
          "font-variant-numeric:oldstyle-nums"
          :else nil)
        (and (= (len parts) 2) (= (first rest) "fractions"))
        (case
          head
          "diagonal"
          "font-variant-numeric:diagonal-fractions"
          "stacked"
          "font-variant-numeric:stacked-fractions"
          :else nil)
        (and (= (len parts) 2) (= head "normal") (= (first rest) "nums"))
        "font-variant-numeric:normal"
        (and (= (len parts) 1) (= head "ordinal"))
        "font-variant-numeric:ordinal"
        (and (= (len parts) 2) (= head "slashed") (= (first rest) "zero"))
        "font-variant-numeric:slashed-zero"
        :else nil))))
