First public release. Cascade was extracted from the tw (Tailwind CSS v4 in OCaml) project as a standalone CSS command-line tool and library, then stabilised over several internal milestones.
Single warning-aware parse entry point:
Css.of_string runs CSS Syntax Level 3 recovery and returns (parse, Error.t) result, where parse = { stylesheet; warnings }.~strict:true promotes the first warning to Error _.Css.of_string_exn returns the recovered stylesheet directly and raises Error.Parse_error on Error.Css.to_string ?minify), with several typed printers exposed (pp_color, pp_length, ...).fold, map, sort, flatten_nesting, inline_imports) and structural CSS diff utilities via the cascade.diff sub-library.all reset folding. Rule merging is order-independent: rules are scheduled through a conflict DAG so cascade-safe reorderings converge on the same output regardless of source order.~objective:\Raw(CLI--objective=raw`) to optimise raw bytes instead, for output that ships uncompressed.Spec coverage:
:has(), :is(), :where(), :not(), nesting &, and full attribute syntax.calc(), clamp(), min(), max(), minmax(), the modern length units, durations, angles.oklch(), oklab(), lch(), hwb(), color-mix(), plus the 148 named colours.@media, @supports, @container (including typed style()/scroll-state() queries with range operators), @when / @else.@layer declarations and blocks, CSS-wide keywords, and all reset semantics in the optimizer.var() parsing/printing, typed fallbacks, theme/default substitution, @property registration.@font-face descriptors), Animations Level 1 (@keyframes, @starting-style).grid-template-areas validation), logical properties, typography (font-variant-*, text-emphasis-*, text-decoration-skip-*, initial-letter*), borders and border-image, backgrounds and gradients, transforms (translate, scale, rotate, transform), transitions, animations (animation-range*, scroll-driven timelines), filters, masks, scroll snap, anchor positioning (position-anchor, position-area, position-try-fallbacks), view transitions, and the common vendor-prefixed properties.<syntax> parsing for @property, registered-property substitution against an explicit Css.Context.t, and round-trip-stable var() serialisation with literal fallbacks.cascade -- pretty-print and minify CSS files. It accepts stdin via - or a missing file argument, and writes output to stdout.cascade --minify applies the standard safe transforms, including deduplication, rule merging, selector grouping, empty-rule elimination, and nested-rule flattening, optimising estimated gzip transfer size by default (--objective=raw optimises raw bytes instead).cascade --inline-imports resolves local @import rules relative to the input file, and cascade --inline-vars substitutes static custom-property references. --keep-vars=NAMES preserves selected custom properties.cascade diff provides structural CSS diffing between two files with auto, tree, string, and canonical modes; respects NO_COLOR, CASCADE_COLOR, and --color, and colours only when stdout is a tty. Identical files exit 0 and differing files exit 1, so the command slots into CI checks and git hooks. The canonical mode projects both sheets to a normal form first, so equivalent factorings -- different rule grouping, cascade-safe rule and declaration order -- compare identical rather than as spurious changes.samoht/tap/cascade, with opam installation still available for OCaml users.cascade parses already-decoded UTF-8 strings. The CSS Syntax Level 3 byte-stream decoding step (BOM handling, @charset byte sniffing, HTTP/environment charset fallback) is the caller's responsibility.@import rules are preserved by default. Use --inline-imports for explicit closed-world filesystem inlining.