···
+
(* Generate index.html page linking to all examples *)
+
let classes_attr tailwind_classes =
+
At.class' (Tailwind.to_string tailwind_classes)
+
("hello_tailwind_01.html", "01. Hello Tailwind",
+
"Your first Tailwind OCaml program. Learn the basics of creating and using type-safe Tailwind classes.",
+
["Basic concepts"; "Type safety"; "Class composition"]);
+
("colors_and_typography_02.html", "02. Colors and Typography",
+
"Explore the comprehensive color system and typography utilities with compile-time validation.",
+
["Color variants"; "Typography scale"; "Font weights"]);
+
("layout_and_spacing_03.html", "03. Layout and Spacing",
+
"Master the box model, flexbox layouts, and spacing utilities for building structured interfaces.",
+
["Box model"; "Flexbox"; "Spacing system"]);
+
("responsive_design_04.html", "04. Responsive Design",
+
"Learn responsive design patterns with breakpoints and mobile-first utilities.",
+
["Breakpoints"; "Mobile-first"; "Responsive utilities"]);
+
("effects_and_variants_05.html", "05. Effects and Variants",
+
"Add visual effects and interactive states with shadows, borders, and hover variants.",
+
["Visual effects"; "Interactive states"; "Hover variants"]);
+
("patterns_and_components_06.html", "06. Patterns and Components",
+
"Build reusable layout patterns and component compositions for consistent design.",
+
["Layout patterns"; "Component composition"; "Reusable utilities"]);
+
("comprehensive_showcase_07.html", "07. Comprehensive Showcase",
+
"Complete application demo showcasing all library features in a real-world context.",
+
["Complete application"; "All features"; "Best practices"]);
+
let create_index_page () =
+
let page_classes = tw [
+
Layout.(to_class (min_height Size.screen));
+
Color.bg (Color.make `Gray ~variant:`V50 ());
+
let container_classes = tw [
+
Layout.(to_class (max_width (Size.rem 72.0))); (* max-w-6xl *)
+
Spacing.(to_class (mx `Auto));
+
Spacing.(to_class (p (Size.rem 2.0)));
+
let header_classes = tw [
+
Typography.(to_class (font_size `Xl4));
+
Typography.(to_class (font_weight `Bold));
+
Color.text (Color.make `Gray ~variant:`V900 ());
+
Spacing.(to_class (mb (Size.rem 2.0)));
+
Typography.(to_class (text_align `Center));
+
let subtitle_classes = tw [
+
Typography.(to_class (font_size `Xl));
+
Color.text (Color.make `Gray ~variant:`V600 ());
+
Typography.(to_class (text_align `Center));
+
Spacing.(to_class (mb (Size.rem 3.0)));
+
let grid_classes = tw [
+
Grid.(to_class (template_cols (`Cols 1)));
+
Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 2))))));
+
Spacing.(to_class (gap `All (Size.rem 1.5)));
+
Spacing.(to_class (mb (Size.rem 3.0)));
+
let card_classes = tw [
+
Spacing.(to_class (p (Size.rem 1.5)));
+
Color.border (Color.make `Gray ~variant:`V200 ());
+
Effects.transition `All;
+
Variants.hover Effects.shadow_md;
+
Variants.hover (Color.border (Color.make `Blue ~variant:`V300 ()));
+
let card_title_classes = tw [
+
Typography.(to_class (font_size `Lg));
+
Typography.(to_class (font_weight `Semibold));
+
Color.text (Color.make `Gray ~variant:`V900 ());
+
Spacing.(to_class (mb (Size.rem 0.75)));
+
let card_description_classes = tw [
+
Color.text (Color.make `Gray ~variant:`V600 ());
+
Spacing.(to_class (mb (Size.rem 1.0)));
+
Typography.(to_class (line_height `Relaxed));
+
let features_classes = tw [
+
Flexbox.(to_class (wrap `Wrap));
+
Spacing.(to_class (gap `All (Size.rem 0.5)));
+
Spacing.(to_class (mb (Size.rem 1.0)));
+
let feature_tag_classes = tw [
+
Color.bg (Color.make `Blue ~variant:`V50 ());
+
Color.text (Color.make `Blue ~variant:`V700 ());
+
Typography.(to_class (font_size `Xs));
+
Spacing.(to_class (px (Size.rem 0.5)));
+
Spacing.(to_class (py (Size.rem 0.25)));
+
let link_classes = tw [
+
Color.text (Color.make `Blue ~variant:`V600 ());
+
Typography.(to_class (font_weight `Medium));
+
Variants.hover (Color.text (Color.make `Blue ~variant:`V800 ()));
+
Effects.transition `Colors;
+
let footer_classes = tw [
+
Typography.(to_class (text_align `Center));
+
Spacing.(to_class (mt (Size.rem 3.0)));
+
Color.text (Color.make `Gray ~variant:`V500 ());
+
Typography.(to_class (font_size `Sm));
+
let html_doc = El.html [
+
El.meta ~at:[At.charset "utf-8"] ();
+
El.meta ~at:[At.name "viewport"; At.content "width=device-width, initial-scale=1"] ();
+
El.title [El.txt "Tailwind OCaml Examples"];
+
El.link ~at:[At.rel "stylesheet"; At.href "hello_tailwind_01.css"] (); (* Reuse CSS from first example *)
+
body { font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; }
+
a { text-decoration: none; }
+
.example-card { display: block; }
+
El.body ~at:[classes_attr page_classes] [
+
El.div ~at:[classes_attr container_classes] [
+
El.h1 ~at:[classes_attr header_classes] [
+
El.txt "Tailwind OCaml Examples"
+
El.p ~at:[classes_attr subtitle_classes] [
+
El.txt "A progressive tutorial series demonstrating type-safe Tailwind CSS generation in OCaml"
+
El.div ~at:[classes_attr grid_classes] (
+
List.map (fun (href, title, description, features) ->
+
El.a ~at:[At.href href; At.class' "example-card"] [
+
El.div ~at:[classes_attr card_classes] [
+
El.h2 ~at:[classes_attr card_title_classes] [El.txt title];
+
El.p ~at:[classes_attr card_description_classes] [El.txt description];
+
El.div ~at:[classes_attr features_classes] (
+
List.map (fun feature ->
+
El.span ~at:[classes_attr feature_tag_classes] [El.txt feature]
+
El.div ~at:[classes_attr link_classes] [
+
El.txt "View Example →"
+
El.div ~at:[classes_attr footer_classes] [
+
El.a ~at:[At.href "https://github.com/dbuenzli/htmlit"; classes_attr link_classes] [El.txt "Htmlit"];
+
El.txt " and type-safe Tailwind CSS generation"
+
(* Output HTML to stdout *)
+
let html_doc = create_index_page () in
+
let html_string = El.to_string ~doctype:true html_doc in
+
print_string html_string