diff --git a/assets/about/alek.avif b/assets/about/alek.avif new file mode 100644 index 0000000000..ea24123da4 Binary files /dev/null and b/assets/about/alek.avif differ diff --git a/assets/about/companies/dark/abstract.svg b/assets/about/companies/dark/abstract.svg new file mode 100644 index 0000000000..5306e156d6 --- /dev/null +++ b/assets/about/companies/dark/abstract.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/dark/box_group.svg b/assets/about/companies/dark/box_group.svg new file mode 100644 index 0000000000..48c7d7e298 --- /dev/null +++ b/assets/about/companies/dark/box_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/dark/lux.svg b/assets/about/companies/dark/lux.svg new file mode 100644 index 0000000000..02e7477635 --- /dev/null +++ b/assets/about/companies/dark/lux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/dark/outset.svg b/assets/about/companies/dark/outset.svg new file mode 100644 index 0000000000..4a2e9583f5 --- /dev/null +++ b/assets/about/companies/dark/outset.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/dark/picus.svg b/assets/about/companies/dark/picus.svg new file mode 100644 index 0000000000..99af8f1a5d --- /dev/null +++ b/assets/about/companies/dark/picus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/dark/y_combinator.svg b/assets/about/companies/dark/y_combinator.svg new file mode 100644 index 0000000000..6e3b7a047d --- /dev/null +++ b/assets/about/companies/dark/y_combinator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/abstract.svg b/assets/about/companies/light/abstract.svg new file mode 100644 index 0000000000..1e622745be --- /dev/null +++ b/assets/about/companies/light/abstract.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/box_group.svg b/assets/about/companies/light/box_group.svg new file mode 100644 index 0000000000..59599ffb1a --- /dev/null +++ b/assets/about/companies/light/box_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/lux.svg b/assets/about/companies/light/lux.svg new file mode 100644 index 0000000000..0db7121291 --- /dev/null +++ b/assets/about/companies/light/lux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/outset.svg b/assets/about/companies/light/outset.svg new file mode 100644 index 0000000000..5c0f7c574e --- /dev/null +++ b/assets/about/companies/light/outset.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/picus.svg b/assets/about/companies/light/picus.svg new file mode 100644 index 0000000000..24173395f2 --- /dev/null +++ b/assets/about/companies/light/picus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/companies/light/y_combinator.svg b/assets/about/companies/light/y_combinator.svg new file mode 100644 index 0000000000..7dc365987d --- /dev/null +++ b/assets/about/companies/light/y_combinator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/about/nikhil.avif b/assets/about/nikhil.avif new file mode 100644 index 0000000000..6d8ccda939 Binary files /dev/null and b/assets/about/nikhil.avif differ diff --git a/assets/about/team_1.avif b/assets/about/team_1.avif new file mode 100644 index 0000000000..6131ed6c98 Binary files /dev/null and b/assets/about/team_1.avif differ diff --git a/assets/about/team_2.avif b/assets/about/team_2.avif new file mode 100644 index 0000000000..d354c64308 Binary files /dev/null and b/assets/about/team_2.avif differ diff --git a/assets/about/team_3.avif b/assets/about/team_3.avif new file mode 100644 index 0000000000..7858065dee Binary files /dev/null and b/assets/about/team_3.avif differ diff --git a/assets/common/dark/ai_builder_pattern.svg b/assets/common/dark/ai_builder_pattern.svg new file mode 100644 index 0000000000..956d589c2c --- /dev/null +++ b/assets/common/dark/ai_builder_pattern.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/dark/cloud_pixel.svg b/assets/common/dark/cloud_pixel.svg new file mode 100644 index 0000000000..c35261b024 --- /dev/null +++ b/assets/common/dark/cloud_pixel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/framework_pixel.svg b/assets/common/dark/framework_pixel.svg new file mode 100644 index 0000000000..17d27bfda8 --- /dev/null +++ b/assets/common/dark/framework_pixel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/square_logo_lines.svg b/assets/common/dark/square_logo_lines.svg new file mode 100644 index 0000000000..18dffe068c --- /dev/null +++ b/assets/common/dark/square_logo_lines.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/common/dark/squares_banner.svg b/assets/common/dark/squares_banner.svg new file mode 100644 index 0000000000..41e77b8c00 --- /dev/null +++ b/assets/common/dark/squares_banner.svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/common/dark/squares_blog.svg b/assets/common/dark/squares_blog.svg new file mode 100644 index 0000000000..b38e1966b6 --- /dev/null +++ b/assets/common/dark/squares_blog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/squares_docs_logo.svg b/assets/common/dark/squares_docs_logo.svg new file mode 100644 index 0000000000..7eef2f0a99 --- /dev/null +++ b/assets/common/dark/squares_docs_logo.svg @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/dark/squares_logo.svg b/assets/common/dark/squares_logo.svg new file mode 100644 index 0000000000..ec7cee319e --- /dev/null +++ b/assets/common/dark/squares_logo.svg @@ -0,0 +1,1135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/dark/squares_navbar.svg b/assets/common/dark/squares_navbar.svg new file mode 100644 index 0000000000..5801ad2c75 --- /dev/null +++ b/assets/common/dark/squares_navbar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/squares_rectangle.svg b/assets/common/dark/squares_rectangle.svg new file mode 100644 index 0000000000..a22500aa05 --- /dev/null +++ b/assets/common/dark/squares_rectangle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/squares_rectangle_small.svg b/assets/common/dark/squares_rectangle_small.svg new file mode 100644 index 0000000000..7c06fb6bec --- /dev/null +++ b/assets/common/dark/squares_rectangle_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/squares_rectangle_xs.svg b/assets/common/dark/squares_rectangle_xs.svg new file mode 100644 index 0000000000..00ffb4df25 --- /dev/null +++ b/assets/common/dark/squares_rectangle_xs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/dark/squares_vertical_docs.svg b/assets/common/dark/squares_vertical_docs.svg new file mode 100644 index 0000000000..b582af9440 --- /dev/null +++ b/assets/common/dark/squares_vertical_docs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/ai_builder_pattern.svg b/assets/common/light/ai_builder_pattern.svg new file mode 100644 index 0000000000..0074491b84 --- /dev/null +++ b/assets/common/light/ai_builder_pattern.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/light/cloud_pixel.svg b/assets/common/light/cloud_pixel.svg new file mode 100644 index 0000000000..ee02d266cc --- /dev/null +++ b/assets/common/light/cloud_pixel.svg @@ -0,0 +1,1077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/common/light/framework_pixel.svg b/assets/common/light/framework_pixel.svg new file mode 100644 index 0000000000..15a99ba61e --- /dev/null +++ b/assets/common/light/framework_pixel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/square_logo_lines.svg b/assets/common/light/square_logo_lines.svg new file mode 100644 index 0000000000..18dffe068c --- /dev/null +++ b/assets/common/light/square_logo_lines.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/common/light/squares_banner.svg b/assets/common/light/squares_banner.svg new file mode 100644 index 0000000000..fa4354accc --- /dev/null +++ b/assets/common/light/squares_banner.svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/common/light/squares_blog.svg b/assets/common/light/squares_blog.svg new file mode 100644 index 0000000000..b38e1966b6 --- /dev/null +++ b/assets/common/light/squares_blog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/squares_docs_logo.svg b/assets/common/light/squares_docs_logo.svg new file mode 100644 index 0000000000..12c281466b --- /dev/null +++ b/assets/common/light/squares_docs_logo.svg @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/light/squares_logo.svg b/assets/common/light/squares_logo.svg new file mode 100644 index 0000000000..1f77888a85 --- /dev/null +++ b/assets/common/light/squares_logo.svg @@ -0,0 +1,1135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/common/light/squares_navbar.svg b/assets/common/light/squares_navbar.svg new file mode 100644 index 0000000000..b03ec4bb3a --- /dev/null +++ b/assets/common/light/squares_navbar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/squares_rectangle.svg b/assets/common/light/squares_rectangle.svg new file mode 100644 index 0000000000..a22500aa05 --- /dev/null +++ b/assets/common/light/squares_rectangle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/squares_rectangle_small.svg b/assets/common/light/squares_rectangle_small.svg new file mode 100644 index 0000000000..dd1b84e59a --- /dev/null +++ b/assets/common/light/squares_rectangle_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/squares_rectangle_xs.svg b/assets/common/light/squares_rectangle_xs.svg new file mode 100644 index 0000000000..1d16ae00ab --- /dev/null +++ b/assets/common/light/squares_rectangle_xs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/common/light/squares_vertical_docs.svg b/assets/common/light/squares_vertical_docs.svg new file mode 100644 index 0000000000..377e261046 --- /dev/null +++ b/assets/common/light/squares_vertical_docs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/accenture_small.svg b/assets/companies/dark/accenture_small.svg new file mode 100644 index 0000000000..968d6a14f7 --- /dev/null +++ b/assets/companies/dark/accenture_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/agricole_small.svg b/assets/companies/dark/agricole_small.svg new file mode 100644 index 0000000000..d5b7a7eb6a --- /dev/null +++ b/assets/companies/dark/agricole_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/apple_small.svg b/assets/companies/dark/apple_small.svg new file mode 100644 index 0000000000..d571a7d6d6 --- /dev/null +++ b/assets/companies/dark/apple_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/dell_small.svg b/assets/companies/dark/dell_small.svg new file mode 100644 index 0000000000..4bc19f7eb4 --- /dev/null +++ b/assets/companies/dark/dell_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/ford_small.svg b/assets/companies/dark/ford_small.svg new file mode 100644 index 0000000000..01a4294d7c --- /dev/null +++ b/assets/companies/dark/ford_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/man_small.svg b/assets/companies/dark/man_small.svg new file mode 100644 index 0000000000..09e0fe3e3c --- /dev/null +++ b/assets/companies/dark/man_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/microsoft_small.svg b/assets/companies/dark/microsoft_small.svg new file mode 100644 index 0000000000..92ceaaf081 --- /dev/null +++ b/assets/companies/dark/microsoft_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/nike_small.svg b/assets/companies/dark/nike_small.svg new file mode 100644 index 0000000000..60fec6f135 --- /dev/null +++ b/assets/companies/dark/nike_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/red_hat_small.svg b/assets/companies/dark/red_hat_small.svg new file mode 100644 index 0000000000..f58b06293e --- /dev/null +++ b/assets/companies/dark/red_hat_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/shell_small.svg b/assets/companies/dark/shell_small.svg new file mode 100644 index 0000000000..1f99a0930a --- /dev/null +++ b/assets/companies/dark/shell_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/unicef_small.svg b/assets/companies/dark/unicef_small.svg new file mode 100644 index 0000000000..f5af4c2db5 --- /dev/null +++ b/assets/companies/dark/unicef_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/dark/world_small.svg b/assets/companies/dark/world_small.svg new file mode 100644 index 0000000000..c6c8fe1031 --- /dev/null +++ b/assets/companies/dark/world_small.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/companies/light/accenture_small.svg b/assets/companies/light/accenture_small.svg new file mode 100644 index 0000000000..569fa01f63 --- /dev/null +++ b/assets/companies/light/accenture_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/agricole_small.svg b/assets/companies/light/agricole_small.svg new file mode 100644 index 0000000000..b5f2d2e7e7 --- /dev/null +++ b/assets/companies/light/agricole_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/apple_small.svg b/assets/companies/light/apple_small.svg new file mode 100644 index 0000000000..bea41db78b --- /dev/null +++ b/assets/companies/light/apple_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/dell_small.svg b/assets/companies/light/dell_small.svg new file mode 100644 index 0000000000..6d4ef9ced6 --- /dev/null +++ b/assets/companies/light/dell_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/ford_small.svg b/assets/companies/light/ford_small.svg new file mode 100644 index 0000000000..783ad49f55 --- /dev/null +++ b/assets/companies/light/ford_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/man_small.svg b/assets/companies/light/man_small.svg new file mode 100644 index 0000000000..28b92eaf2a --- /dev/null +++ b/assets/companies/light/man_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/microsoft_small.svg b/assets/companies/light/microsoft_small.svg new file mode 100644 index 0000000000..c46996e85e --- /dev/null +++ b/assets/companies/light/microsoft_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/nike_small.svg b/assets/companies/light/nike_small.svg new file mode 100644 index 0000000000..2b927f72e1 --- /dev/null +++ b/assets/companies/light/nike_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/red_hat_small.svg b/assets/companies/light/red_hat_small.svg new file mode 100644 index 0000000000..3351ea0dc9 --- /dev/null +++ b/assets/companies/light/red_hat_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/shell_small.svg b/assets/companies/light/shell_small.svg new file mode 100644 index 0000000000..3bb39a4a09 --- /dev/null +++ b/assets/companies/light/shell_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/unicef_small.svg b/assets/companies/light/unicef_small.svg new file mode 100644 index 0000000000..ad0d79d178 --- /dev/null +++ b/assets/companies/light/unicef_small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/companies/light/world_small.svg b/assets/companies/light/world_small.svg new file mode 100644 index 0000000000..25f6e49af4 --- /dev/null +++ b/assets/companies/light/world_small.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/components/GradientButton.tsx b/assets/components/GradientButton.tsx new file mode 100644 index 0000000000..0c66447192 --- /dev/null +++ b/assets/components/GradientButton.tsx @@ -0,0 +1,112 @@ +'use client' + +import { cn } from 'clsx-for-tailwind' +import React, { useCallback, useState } from 'react' + +type ButtonVariant = 'primary' | 'destructive' | 'outline' | 'ghost' +type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'icon-xs' | 'icon-sm' | 'icon-md' | 'icon-lg' + +interface GradientButtonProps + extends React.ButtonHTMLAttributes { + children: React.ReactNode + variant?: ButtonVariant + size?: ButtonSize + className?: string + nativeButton?: boolean +} + +const BASE_CLASSES = + 'relative inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:border disabled:border-m-slate-4/80 disabled:bg-m-slate-3 disabled:text-m-slate-8 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0 cursor-pointer box-border font-[525] overflow-hidden' + +const VARIANT_CLASSES: Record = { + primary: + 'bg-primary-9 text-primary-2 dark:text-primary-contrast hover:bg-primary-10 shadow-[0_0_1px_var(--primary-9,#6E56CF)_inset,0_2px_0_0_rgba(255,255,255,0.22)_inset]', + destructive: 'bg-destructive-9 hover:bg-destructive-10 text-primary-contrast', + outline: + 'shadow-[0_-1px_0_0_rgba(0,0,0,0.08)_inset,0_0_0_1px_rgba(0,0,0,0.08)_inset,0_1px_2px_0_rgba(0,0,0,0.02),0_1px_4px_0_rgba(0,0,0,0.02)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.16)_inset] bg-white dark:bg-m-slate-10 hover:bg-m-slate-2 dark:hover:bg-m-slate-9 text-m-slate-12 dark:text-m-slate-3', + ghost: 'text-m-slate-12 dark:text-m-slate-3 hover:text-primary-10 dark:hover:text-primary-9', +} + +const SIZE_CLASSES: Record = { + xs: 'px-1.5 h-7 rounded-lg gap-1.5 text-sm', + sm: 'px-2 h-8 rounded-lg gap-2 text-sm', + md: 'px-2.5 h-9 rounded-[0.625rem] gap-2 text-sm', + lg: 'px-3 h-10 rounded-[0.625rem] gap-2.5 text-base', + 'icon-xs': 'size-7 rounded-lg', + 'icon-sm': 'size-8 rounded-lg', + 'icon-md': 'size-9 rounded-[0.625rem]', + 'icon-lg': 'size-10 rounded-[0.625rem]', +} + +export function GradientButton({ + children, + variant = 'primary', + size = 'md', + className, + nativeButton = true, + ...props +}: GradientButtonProps) { + const [isMouseOver, setIsMouseOver] = useState(false) + const [x, setX] = useState(0) + const [y, setY] = useState(0) + + const handleMouseMove = useCallback< + React.MouseEventHandler + >((e) => { + const button = e.currentTarget + const rect = button.getBoundingClientRect() + setX(e.clientX - rect.left) + setY(e.clientY - rect.top) + }, []) + + const handleMouseEnter = useCallback(() => { + setIsMouseOver(true) + }, []) + + const handleMouseLeave = useCallback(() => { + setIsMouseOver(false) + }, []) + + const Component = nativeButton ? 'button' : 'div' + + return ( + + {variant === 'primary' ? ( + <> + + {children} + + ) : ( + children + )} + + ) +} + +export default GradientButton diff --git a/assets/components/LogoReveal.tsx b/assets/components/LogoReveal.tsx new file mode 100644 index 0000000000..24e05f048c --- /dev/null +++ b/assets/components/LogoReveal.tsx @@ -0,0 +1,160 @@ +"use client" + +import { cn } from "clsx-for-tailwind"; +import { useCallback, useEffect, useId, useRef, useState } from "react"; + +const GRID_PATH = + "M96.5 -47.5V47.5H192.5M336.5 47.5H432.5V287.5M336.5 47.5V-47.5M336.5 47.5V95.5H192.5M432.5 287.5H336.5V432.5M432.5 287.5V432.5M432.5 287.5H480.5H576.5M0.5 -47.5V95.5H48.5V191.5H192.5V432.5M192.5 95.5H144.5V287.5H0.5V432.5M192.5 95.5V47.5M192.5 -47.5V47.5M240.5 95.5V143.5V335.5H480.5V432.5M576.5 95.5V-47.5M576.5 95.5H720.5V-47.5M576.5 95.5V239.5M576.5 432.5V287.5M576.5 239.5H720.5V432.5M576.5 239.5V287.5"; + +// Path viewBox dimensions +const PATH_W = 721; +const PATH_H = 432; + +interface LogoRevealProps { + gridBgSrc?: string; + className?: string; + revealRadius?: number; + strokeWidth?: number; +} + +export function LogoReveal({ + gridBgSrc = "/common/light/squares_logo.svg", + className, + revealRadius = 180, + strokeWidth = 2, +}: LogoRevealProps) { + const containerRef = useRef(null); + const [mouse, setMouse] = useState({ x: -9999, y: -9999 }); + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); + const uniqueId = useId(); + + // Calculate offsets to center the path within the background + const offsetX = (dimensions.width - PATH_W) / 2; + const offsetY = (dimensions.height - PATH_H) / 2; + + const updateDimensions = useCallback(() => { + const img = containerRef.current?.querySelector("img"); + if (img && img.naturalWidth && img.naturalHeight) { + setDimensions({ width: img.naturalWidth, height: img.naturalHeight }); + } + }, []); + + const handleMouseMove = useCallback( + (e: MouseEvent) => { + const el = containerRef.current; + if (!el || !dimensions.width || !dimensions.height) return; + const rect = el.getBoundingClientRect(); + const scaleX = dimensions.width / rect.width; + const scaleY = dimensions.height / rect.height; + setMouse({ + x: (e.clientX - rect.left) * scaleX, + y: (e.clientY - rect.top) * scaleY, + }); + }, + [dimensions] + ); + + const handleMouseLeave = useCallback(() => { + setMouse({ x: -9999, y: -9999 }); + }, []); + + useEffect(() => { + const el = containerRef.current; + if (!el) return; + + el.addEventListener("mousemove", handleMouseMove); + el.addEventListener("mouseleave", handleMouseLeave); + + return () => { + el.removeEventListener("mousemove", handleMouseMove); + el.removeEventListener("mouseleave", handleMouseLeave); + }; + }, [handleMouseMove, handleMouseLeave]); + + // Unique IDs for SVG elements to avoid conflicts with multiple instances + const revealGradId = `revealGrad-${uniqueId}`; + const revealMaskId = `revealMask-${uniqueId}`; + const purpleStrokeId = `purpleStroke-${uniqueId}`; + const lineGlowId = `lineGlow-${uniqueId}`; + + return ( +
+ {/* Background squares grid */} + + + {/* Foreground SVG with reveal effect */} + {dimensions.width > 0 && dimensions.height > 0 && ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} +
+ ); +} + +export default LogoReveal; diff --git a/assets/custom-colors.css b/assets/custom-colors.css index 06b1dba0a0..dfa230cb75 100644 --- a/assets/custom-colors.css +++ b/assets/custom-colors.css @@ -41,17 +41,17 @@ --wave-line-2: #EBE4FF; /* Marketing Colors */ --m-slate-1: #FCFCFD; - --m-slate-2: #F9F9FB; - --m-slate-3: #F0F0F3; - --m-slate-4: #E8E8EC; - --m-slate-5: #E0E1E6; - --m-slate-6: #D9D9E0; - --m-slate-7: #CDCED6; - --m-slate-8: #B9BBC6; - --m-slate-9: #8B8D98; - --m-slate-10: #80838D; - --m-slate-11: #60646C; - --m-slate-12: #262B31; + --m-slate-2: #F6F7F9; + --m-slate-3: #EEEFF2; + --m-slate-4: #E5E8EB; + --m-slate-5: #CACDD4; + --m-slate-6: #979FAA; + --m-slate-7: #67707E; + --m-slate-8: #3C434E; + --m-slate-9: #2A3037; + --m-slate-10: #21252B; + --m-slate-11: #1D2025; + --m-slate-12: #151618; --m-slate-13: #1C2024; --m-slate-14: #1A1B1D; --m-slate-15: #151618; @@ -72,7 +72,6 @@ .dark, .dark-theme { /* Slate */ - --c-slate-1: #151618; /* #151618 */ --c-slate-2: #1A1B1D; /* #1A1B1D */ @@ -121,20 +120,17 @@ --wave-line-1: #2F1C78; --wave-line-2: #261958; --m-slate-1: #FCFCFD; - --m-slate-2: #F9F9FB; - --m-slate-3: #F0F0F3; - --m-slate-4: #E8E8EC; - --m-slate-5: #E0E1E6; - --m-slate-6: #D9D9E0; - --m-slate-7: #CDCED6; - --m-slate-8: #B9BBC6; - --m-slate-9: #8B8D98; - --m-slate-10: #80838D; - --m-slate-11: #60646C; - --m-slate-12: #262B31; - --m-slate-13: #1C2024; - --m-slate-14: #1A1B1D; - --m-slate-15: #151618; + --m-slate-2: #F6F7F9; + --m-slate-3: #EEEFF2; + --m-slate-4: #E5E8EB; + --m-slate-5: #CACDD4; + --m-slate-6: #979FAA; + --m-slate-7: #67707E; + --m-slate-8: #3C434E; + --m-slate-9: #2A3037; + --m-slate-10: #21252B; + --m-slate-11: #1D2025; + --m-slate-12: #151618; --m-violet-1: #FDFCFE; --m-violet-2: #FAF8FF; --m-violet-3: #F4F0FE; diff --git a/assets/docs/dark/getting_started.svg b/assets/docs/dark/getting_started.svg new file mode 100644 index 0000000000..7828777b52 --- /dev/null +++ b/assets/docs/dark/getting_started.svg @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/docs/dark/mcp.svg b/assets/docs/dark/mcp.svg new file mode 100644 index 0000000000..9fe508a88c --- /dev/null +++ b/assets/docs/dark/mcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/docs/light/getting_started.svg b/assets/docs/light/getting_started.svg new file mode 100644 index 0000000000..48d441b53a --- /dev/null +++ b/assets/docs/light/getting_started.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/docs/light/mcp.svg b/assets/docs/light/mcp.svg new file mode 100644 index 0000000000..fbaaec7b03 --- /dev/null +++ b/assets/docs/light/mcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/logos/dark/docs.svg b/assets/logos/dark/docs.svg new file mode 100644 index 0000000000..89669a4b09 --- /dev/null +++ b/assets/logos/dark/docs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/logos/dark/reflex.svg b/assets/logos/dark/reflex.svg index 8cd6fcd64b..75da2ffc82 100644 --- a/assets/logos/dark/reflex.svg +++ b/assets/logos/dark/reflex.svg @@ -1,6 +1 @@ - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/assets/logos/light/docs.svg b/assets/logos/light/docs.svg new file mode 100644 index 0000000000..89669a4b09 --- /dev/null +++ b/assets/logos/light/docs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/logos/light/reflex.svg b/assets/logos/light/reflex.svg index 516019628d..bcde2660b9 100644 --- a/assets/logos/light/reflex.svg +++ b/assets/logos/light/reflex.svg @@ -1,6 +1 @@ - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/assets/tailwind-theme.css b/assets/tailwind-theme.css index 7da33a25db..6694224d21 100644 --- a/assets/tailwind-theme.css +++ b/assets/tailwind-theme.css @@ -1115,34 +1115,33 @@ 0px -24px 12px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)), 0px -8px 8px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)), 0px -2px 6px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)); - + --shadow-card: 0 0 0 1px rgba(0, 0, 0, 0.04), + 0 4px 8px 0 rgba(0, 0, 0, 0.07), + 0 1px 1px 0 rgba(0, 0, 0, 0.01), + 0 0 0 1px #FFF inset; + --shadow-card-dark: 0 0 0 1px var(--m-slate-9, #2A3037); --text-xs: 0.75rem; --text-xs--line-height: 1rem; - --text-xs--letter-spacing: -0.00375rem; --text-sm: 0.875rem; - --text-sm--line-height: 1.25rem; - --text-sm--letter-spacing: -0.01rem; + --text-sm--line-height: 1.5rem; --text-base: 1rem; - --text-base--line-height: 1.5rem; - --text-base--letter-spacing: -0.015rem; + --text-base--line-height: 1.625rem; + --text-base--letter-spacing: -0.0025rem; --text-lg: 1.125rem; --text-lg--line-height: 1.625rem; - --text-lg--letter-spacing: -0.01625rem; --text-xl: 1.25rem; --text-xl--line-height: 1.75rem; - --text-xl--letter-spacing: -0.028125rem; --text-2xl: 1.5rem; - --text-2xl--line-height: 2rem; - --text-2xl--letter-spacing: -0.0375rem; + --text-2xl--line-height: 2.25rem; + --text-2xl--letter-spacing: -0.0225rem; --text-3xl: 2rem; --text-3xl--line-height: 2.5rem; - --text-3xl--letter-spacing: -0.07rem; --text-4xl: 2.5rem; --text-4xl--line-height: 3rem; - --text-4xl--letter-spacing: -0.125rem; + --text-4xl--letter-spacing: -0.075rem; --text-5xl: 3rem; --text-5xl--line-height: 3.5rem; - --text-5xl--letter-spacing: -0.1575rem; + --text-5xl--letter-spacing: -0.0975rem; --text-6xl: 3.5rem; --text-6xl--line-height: 4rem; --text-6xl--letter-spacing: -0.1925rem; @@ -1175,6 +1174,9 @@ --radius-ui-lg: calc(var(--radius) + 0.25rem); --radius-ui-xl: calc(var(--radius) + 0.375rem); --radius-ui-2xl: calc(var(--radius) + 0.5rem); + /* Width */ + --layout-max-width: 81rem; + --docs-layout-max-width: 69rem; @keyframes accordion-down { from { @@ -1734,6 +1736,7 @@ color: var(--c-slate-12) !important; background-color: transparent !important; } + @media (max-width: 768px) { .code-block { padding: 1rem !important; @@ -1755,6 +1758,27 @@ color: var(--c-slate-11); } + .hover-card-shadow:hover { + background: var(0 3px 6px 0 rgba(0, 0, 0, 0.03), + 0 1px 0 0 #FFF inset, + 0 1px 0 0 rgba(0, 0, 0, 0.04), + 0 0 0 1px rgba(0, 0, 0, 0.08), linear-gradient(180deg, var(--secondary-1, #FCFCFD) 0%, var(--white-1, #FFF) 100%)); + box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.03), 0 1px 0 0 #FFF inset, 0 1px 0 0 rgba(0, 0, 0, 0.04), 0 0 0 1px rgba(0, 0, 0, 0.08); + } + + :where(.dark, .dark *) .hover-card-shadow:hover { + background: var(--m-slate-10, #21252B); + box-shadow: 0 0 0 1px var(--m-slate-9, #2A3037); + } + + .navbar-shadow { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.03), 0 -1px 1px 0 rgba(0, 0, 0, 0.04), 0 16px 32px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.08), 0 4px 8px 0 rgba(0, 0, 0, 0.03); + } + + :where(.dark, .dark *) .navbar-shadow { + box-shadow: 0 0 0 1px var(--m-slate-9, #2A3037); + } + .tab-style[data-state='active'] { color: var(--c-violet-9); } @@ -1931,6 +1955,16 @@ scrollbar-width: none; /* Firefox */ } + + @supports ((-webkit-touch-callout: none) or (font: -apple-system-body) or (-moz-appearance: none)) { + + .safari-nav-positioner, + .safari-nav-positioner[data-slot='navigation-menu-positioner'] { + transition: none !important; + transition-property: none !important; + transition-duration: 0ms !important; + } + } } @property --border-angle { diff --git a/blog/2024-03-27-structuring-a-large-app.md b/blog/2024-03-27-structuring-a-large-app.md index 1653604fc0..a698e4287d 100644 --- a/blog/2024-03-27-structuring-a-large-app.md +++ b/blog/2024-03-27-structuring-a-large-app.md @@ -362,6 +362,7 @@ example-big-app/ │ │ ├─ footer.py │ │ ├─ menu.py │ │ ├─ navbar.py +│ │ ├─ settings.py │ ├─ pages/ │ │ ├─ __init__.py │ │ ├─ index.py diff --git a/pcweb/components/docpage/navbar/buttons/sidebar.py b/pcweb/components/docpage/navbar/buttons/sidebar.py index f8bf1e59b0..2da5dd101d 100644 --- a/pcweb/components/docpage/navbar/buttons/sidebar.py +++ b/pcweb/components/docpage/navbar/buttons/sidebar.py @@ -1,10 +1,12 @@ import reflex as rx +import reflex_ui as ui from reflex.style import toggle_color_mode +from pcweb.components.hosting_banner import HostingBannerState from pcweb.components.icons.icons import get_icon +from pcweb.components.marketing_button import button from pcweb.constants import DISCORD_URL, GITHUB_URL, TWITTER_URL from pcweb.pages.blog import blogs -from pcweb.pages.docs import getting_started from pcweb.pages.docs.library import library from pcweb.pages.framework.framework import framework from pcweb.pages.gallery import gallery @@ -76,7 +78,7 @@ def navbar_sidebar_drawer(trigger) -> rx.Component: rx.drawer.portal( rx.drawer.content( rx.box( - drawer_item("Docs", getting_started.introduction.path, "docs"), + drawer_item("Docs", "/docs", "docs"), drawer_item("Templates", gallery.path, "gallery"), drawer_item("Blog", blogs.path, "blog"), drawer_item("Case Studies", "/customers", "customers"), @@ -98,9 +100,16 @@ def navbar_sidebar_drawer(trigger) -> rx.Component: class_name="flex flex-row justify-center items-center px-3 py-0.5 w-full h-[47px]", custom_attrs={"aria-label": "Toggle color mode"}, ), - class_name="flex flex-col items-center bg-slate-1 w-full h-full", + class_name="flex flex-col items-center dark:bg-m-slate-12 bg-m-slate-1 w-full h-full", + ), + class_name=ui.cn( + "dark:!bg-m-slate-12 !bg-m-slate-1 w-full h-full !outline-none", + rx.cond( + HostingBannerState.is_banner_visible, + "!top-[137px]", + "!top-[74px]", + ), ), - class_name="!bg-transparent w-full h-full !outline-none !top-[47px]", ) ), direction="bottom", @@ -134,34 +143,33 @@ def docs_sidebar_drawer(sidebar: rx.Component, trigger) -> rx.Component: def navbar_sidebar_button() -> rx.Component: return rx.box( navbar_sidebar_drawer( - rx.el.button( - rx.icon( - "x", - size=24, + button( + ui.icon( + "Menu01Icon", style={ "[data-state=open] &": { - "display": "flex", + "display": "none", }, "[data-state=closed] &": { - "display": "none", + "display": "flex", }, }, - class_name="!text-slate-9 shrink-0", ), - rx.icon( - "menu", - size=24, + ui.icon( + "Cancel01Icon", style={ "[data-state=open] &": { - "display": "none", + "display": "flex", }, "[data-state=closed] &": { - "display": "flex", + "display": "none", }, }, - class_name="!text-slate-9 shrink-0", ), + size="icon-sm", + variant="outline", custom_attrs={"aria-label": "Open sidebar"}, + native_button=False, ), ), class_name="flex justify-center items-center size-8", diff --git a/pcweb/components/docpage/navbar/navbar.py b/pcweb/components/docpage/navbar/navbar.py index de1dd28ddd..6a0b30dd15 100644 --- a/pcweb/components/docpage/navbar/navbar.py +++ b/pcweb/components/docpage/navbar/navbar.py @@ -18,7 +18,7 @@ from pcweb.pages.use_cases.use_cases import use_cases_page from ...link_button import resources_button -from ..sidebar import SidebarState +from ..sidebar.state import SidebarState from .buttons.discord import discord from .buttons.github import github from .buttons.sidebar import navbar_sidebar_button @@ -757,6 +757,7 @@ def new_component_section() -> rx.Component: trigger=ui.button( "Book a Demo", size="sm", + aria_label="Book a Demo", variant="primary", class_name="font-semibold whitespace-nowrap max-xl:hidden", ), diff --git a/pcweb/components/docpage/navbar/typesense.py b/pcweb/components/docpage/navbar/typesense.py index f4b6cae420..c44f7261bb 100644 --- a/pcweb/components/docpage/navbar/typesense.py +++ b/pcweb/components/docpage/navbar/typesense.py @@ -316,23 +316,24 @@ def keyboard_shortcut_script() -> rx.Component: def search_trigger() -> rx.Component: """Render the search trigger button.""" - return ui.button( - rx.html( - """ - -""" - ), + return rx.el.button( + ui.icon(icon="Search01Icon", class_name="shrink-0"), rx.el.span( "Search", class_name="hidden md:block text-sm font-medium", ), - rx.el.span( - "⌘ K", - class_name="px-2 bg-slate-4 rounded-sm ml-0.5 hidden md:block h-5 font-medium", + rx.html( + rx.color_mode_cond( + """""", + """ + + + +""", + ), + class_name="ml-auto hidden md:block", ), - variant="outline", - size="sm", - class_name="md:w-full text-secondary-11", + class_name="text-m-slate-7 dark:text-m-slate-6 h-8 px-2 py-1.5 rounded-lg bg-m-slate-1 dark:bg-m-slate-11 flex flex-row items-center justify-start gap-2 lg:w-[10rem] w-full hover:bg-m-slate-2 dark:hover:bg-m-slate-10 dark:shadow-[0_-1px_0_0_rgba(255,_255,_255,_0.06)_inset,_0_0_0_1px_rgba(255,_255,_255,_0.04)_inset] shadow-[0_-1px_0_0_rgba(0,_0,_0,_0.08)_inset,_0_0_0_1px_rgba(0,_0,_0,_0.08)_inset,_0_1px_2px_0_rgba(0,_0,_0,_0.02),_0_1px_4px_0_rgba(0,_0,_0,_0.02)]", id="search-trigger", custom_attrs={"aria-label": "Search documentation"}, ) diff --git a/pcweb/components/hosting_banner.py b/pcweb/components/hosting_banner.py index 47e83185a6..07d490e4dc 100644 --- a/pcweb/components/hosting_banner.py +++ b/pcweb/components/hosting_banner.py @@ -1,6 +1,9 @@ import datetime import reflex as rx +import reflex_ui as ui + +from pcweb.components.marketing_button import button def glow() -> rx.Component: @@ -67,40 +70,59 @@ def hosting_banner() -> rx.Component: rx.el.div( rx.el.a( rx.box( + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_banner.svg", + alt="Square Banner", + class_name="pointer-events-none absolute -left-[16rem] max-lg:hidden", + ), rx.box( # Header text with responsive spans rx.el.span( "New", - class_name="items-center font-medium px-1.5 h-5 rounded-md text-xs bg-violet-9 text-slate-1 z-[1] max-lg:hidden lg:inline-flex", + class_name="items-center font-[525] px-2.5 h-7 rounded-lg text-sm text-m-slate-3 z-[1] max-lg:hidden lg:inline-flex border border-white/16", ), - rx.text( + rx.el.span( + "Reflex Build On-Prem: A Secure Builder Running in Your Environment", rx.el.span( - "Reflex Build On-Prem - A secure builder running in your environment. ", - rx.el.span( - "Learn more", - class_name="text-slate-11 font-semibold text-sm underline decoration-slate-11 lg:pl-2", - ), - class_name="inline-block text-slate-12 font-semibold text-sm", + ". Learn more", + class_name="lg:hidden text-m-slate-6 dark:text-m-slate-2", ), - class_name="text-slate-12 font-semibold text-sm z-[1]", + class_name="text-m-slate-3 font-[525] text-sm lg:text-nowrap inline-block", + ), + rx.el.span( + class_name="w-px h-7 bg-gradient-to-b from-transparent via-white/24 to-transparent max-lg:hidden", + ), + button( + "Learn more", + ui.icon("ArrowRight01Icon"), + variant="ghost", + size="xs", + aria_label="Learn more", + class_name="text-m-slate-3 dark:hover:text-m-slate-5 max-lg:hidden", ), - class_name="flex items-center md:gap-3.5 gap-2", - ) + class_name="flex flex-row items-center md:gap-4 gap-2", + ), + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_banner.svg", + alt="Square Banner", + class_name="pointer-events-none absolute -right-[16rem] max-lg:hidden", + ), + class_name="flex flex-row items-center relative", ), - glow(), to=BLOG_LINK, is_external=False, - class_name="flex justify-start md:justify-center md:col-start-2", + class_name="flex justify-start md:justify-center md:col-start-2 max-w-[73rem]", ), rx.el.button( - rx.icon( - "x", - size=16, + ui.icon( + "MultiplicationSignIcon", ), - class_name="cursor-pointer hover:!text-slate-11 transition-color !text-slate-9 z-10 size-8 flex items-center justify-center shrink-0 md:col-start-3 justify-self-end ml-auto", + aria_label="Close banner", + type="button", + class_name="cursor-pointer hover:text-m-slate-5 transition-colors text-m-slate-3 z-10 size-10 flex items-center justify-center shrink-0 md:col-start-3 justify-self-end ml-auto", on_click=HostingBannerState.hide_banner, ), - class_name="px-6 lg:px-6 w-screen min-h-[3rem] lg:h-[3.5rem] shadow-[inset_0_-1px_0_0_var(--c-slate-3)] flex md:grid md:grid-cols-[1fr_auto_1fr] items-center bg-slate-1 gap-4 overflow-hidden relative lg:py-0 py-3 max-w-full group", + class_name="px-5 lg:px-0 w-screen min-h-[2rem] lg:h-10 flex md:grid md:grid-cols-[1fr_auto_1fr] items-center bg-m-slate-12 dark:bg-[#6550B9] gap-4 overflow-hidden relative lg:py-0 py-2 max-w-full group", ), ), on_mount=HostingBannerState.show_blog_banner, diff --git a/pcweb/components/logo_reveal.py b/pcweb/components/logo_reveal.py new file mode 100644 index 0000000000..61fe7b8b06 --- /dev/null +++ b/pcweb/components/logo_reveal.py @@ -0,0 +1,30 @@ +"""Logo reveal component with mouse-following gradient effect.""" + +import reflex as rx +from reflex.vars.base import Var + + +class LogoReveal(rx.NoSSRComponent): + """A logo reveal component with mouse-tracking gradient effect.""" + + library = "$/public/components/LogoReveal" + + tag = "LogoReveal" + + # Source URL for the background grid image + grid_bg_src: Var[str] + + # Radius of the reveal circle effect + reveal_radius: Var[int] + + # Stroke width of the revealed lines + stroke_width: Var[int] + + def add_imports(self) -> rx.ImportDict: + """Add imports to the component.""" + return { + "clsx-for-tailwind": "cn", + } + + +logo_reveal = LogoReveal.create diff --git a/pcweb/components/marketing_button.py b/pcweb/components/marketing_button.py new file mode 100644 index 0000000000..2a889f8fbf --- /dev/null +++ b/pcweb/components/marketing_button.py @@ -0,0 +1,37 @@ +"""Custom button component.""" + +from typing import Literal + +import reflex as rx +from reflex.vars.base import Var + +LiteralButtonVariant = Literal["primary", "destructive", "outline", "ghost"] +LiteralButtonSize = Literal[ + "xs", "sm", "md", "lg", "icon-xs", "icon-sm", "icon-md", "icon-lg" +] + + +class Button(rx.Component): + """A custom button component.""" + + library = "$/public/components/GradientButton" + + tag = "GradientButton" + + # Button variant. Defaults to "primary". + variant: Var[LiteralButtonVariant] + + # Button size. Defaults to "md". + size: Var[LiteralButtonSize] + + # Whether to use a native button element. Defaults to True. If False, the button will be rendered as a div element. + native_button: Var[bool] = rx.Var.create(True) + + def add_imports(self) -> rx.ImportDict: + """Add imports to the component.""" + return { + "clsx-for-tailwind": "cn", + } + + +button = Button.create diff --git a/pcweb/constants.py b/pcweb/constants.py index 459f9aa1df..06f8299618 100644 --- a/pcweb/constants.py +++ b/pcweb/constants.py @@ -20,6 +20,10 @@ PYNECONE_URL = "https://pynecone.io" REFLEX_CLOUD_URL = os.getenv("REFLEX_CLOUD_URL", "https://cloud.reflex.dev/") REFLEX_BUILD_URL = os.getenv("REFLEX_BUILD_URL", "https://build.reflex.dev/") +JOBS_BOARD_URL = "https://www.ycombinator.com/companies/reflex/jobs" +CHANGELOG_URL = "https://github.com/reflex-dev/reflex/releases" +CONTRIBUTING_URL = "https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md" +DISCUSSIONS_URL = "https://github.com/orgs/reflex-dev/discussions" PIP_URL = "https://pypi.org/project/reflex" GITHUB_URL = "https://github.com/reflex-dev/reflex" diff --git a/pcweb/pages/__init__.py b/pcweb/pages/__init__.py index 7df352554d..15c76d6195 100644 --- a/pcweb/pages/__init__.py +++ b/pcweb/pages/__init__.py @@ -1,5 +1,6 @@ from pcweb.route import Route +from .about import about # noqa: F401 from .blog import blog_routes from .booked import booked as booked from .check_your_email_demo import page_thank_you as page_thank_you @@ -8,6 +9,7 @@ from .databricks.databricks import databricks_page as databricks_page from .demo.book_demo import book_demo as book_demo from .docs import doc_routes +from .docs_landing import docs_landing as docs_landing from .errors import errors as errors from .faq import faq as faq from .framework.framework import framework as framework diff --git a/pcweb/pages/about/__init__.py b/pcweb/pages/about/__init__.py new file mode 100644 index 0000000000..fbaeb814e0 --- /dev/null +++ b/pcweb/pages/about/__init__.py @@ -0,0 +1,47 @@ +import reflex as rx + +from pcweb.meta.meta import create_meta_tags +from pcweb.pages.about.views import ( + cards, + companies, + divider, + hero, + hiring, + news, + square_logo, + team, +) +from pcweb.pages.framework.views.footer_index import footer_index +from pcweb.views.marketing_navbar import marketing_navbar + + +@rx.page( + route="/about", + title="Reflex · About", + meta=create_meta_tags( + title="Reflex · About", + description="About Reflex - The platform to build and scale enterprise apps", + image="/previews/index_preview.webp", + ), +) +def about() -> rx.Component: + return rx.el.div( + marketing_navbar(), + rx.el.main( + rx.el.div( + hero(), + companies(), + square_logo(), + cards(), + divider(), + hiring(), + team(), + news(), + divider(), + footer_index(), + class_name="flex flex-col relative justify-center items-center w-full", + ), + class_name="flex flex-col w-full relative h-full justify-center items-center", + ), + class_name="flex flex-col w-full justify-center items-center relative dark:bg-m-slate-12 bg-m-slate-1", + ) diff --git a/pcweb/pages/about/views/__init__.py b/pcweb/pages/about/views/__init__.py new file mode 100644 index 0000000000..d3f3993d18 --- /dev/null +++ b/pcweb/pages/about/views/__init__.py @@ -0,0 +1,19 @@ +from .cards import cards +from .companies import companies +from .divider import divider +from .hero import hero +from .hiring import hiring +from .news import news +from .square_logo import square_logo +from .team import team + +__all__ = [ + "cards", + "companies", + "divider", + "hero", + "hiring", + "news", + "square_logo", + "team", +] diff --git a/pcweb/pages/about/views/cards.py b/pcweb/pages/about/views/cards.py new file mode 100644 index 0000000000..9213c9d572 --- /dev/null +++ b/pcweb/pages/about/views/cards.py @@ -0,0 +1,66 @@ +import reflex as rx +import reflex_ui as ui + + +def squares_rectangle_small() -> rx.Component: + return rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_rectangle_small.svg", + alt="Squares Rectangle Small", + class_name="pointer-events-none", + ) + + +def card(title: str, description: rx.Component, icon: str) -> rx.Component: + return rx.el.div( + rx.el.div( + squares_rectangle_small(), + class_name="absolute top-1 left-4.5", + ), + ui.icon( + icon, + class_name="text-m-slate-12 dark:text-m-slate-3 size-10 mb-8", + stroke_width=1, + ), + rx.el.h2( + title, + class_name="text-m-slate-12 dark:text-m-slate-3 text-2xl font-semibold mb-4", + ), + description, + class_name="flex flex-col rounded-xl shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_12px_24px_0_rgba(0,0,0,0.08),0_1px_1px_0_rgba(0,0,0,0.01),0_4px_8px_0_rgba(0,0,0,0.03),0_0_0_1px_#FFF_inset] lg:px-12 lg:pt-16 lg:pb-12 px-10 pt-14 pb-10 relative isolate backdrop-blur-[6px] bg-white/96 dark:bg-m-slate-11 dark:shadow-none dark:border-t dark:border-m-slate-9", + ) + + +def cards() -> rx.Component: + return rx.el.section( + card( + title="How It Started", + description=rx.el.p( + "Reflex began as a simple idea: ", + rx.el.b( + " building web apps in Python should feel effortless. ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + " What started as an internal experiment quickly grew into a community-driven framework used to ship real products fast.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-base font-medium", + ), + icon="Plant04Icon", + ), + card( + title="Core Values", + description=rx.el.p( + rx.el.b( + "Open source is at the core of Reflex. ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + " We build in the open, listen to our community, and believe the best developer tools are shaped by the people who use them. ", + rx.el.b( + "Transparency, collaboration, and craft ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + " come first.", + class_name="text-m-slate-11 dark:text-m-slate-6 text-base font-medium", + ), + icon="OpenSourceIcon", + ), + class_name="grid grid-cols-1 lg:grid-cols-2 gap-10 max-w-[69rem] w-full mx-auto lg:pb-36 pb-24 max-lg:px-6", + ) diff --git a/pcweb/pages/about/views/companies.py b/pcweb/pages/about/views/companies.py new file mode 100644 index 0000000000..712a4d751b --- /dev/null +++ b/pcweb/pages/about/views/companies.py @@ -0,0 +1,83 @@ +import reflex as rx + +color_mode = rx.color_mode_cond("light", "dark") +COMPANIES = [ + { + "src": f"/about/companies/{color_mode}/y_combinator.svg", + "alt": "Y Combinator", + }, + { + "src": f"/about/companies/{color_mode}/abstract.svg", + "alt": "Abstract", + }, + { + "src": f"/about/companies/{color_mode}/outset.svg", + "alt": "Outset", + }, + { + "src": f"/about/companies/{color_mode}/lux.svg", + "alt": "Lux Capital", + }, + { + "src": f"/about/companies/{color_mode}/box_group.svg", + "alt": "Box Group", + }, + { + "src": f"/about/companies/{color_mode}/picus.svg", + "alt": "Picus Capital", + }, +] + + +def company_image(src: str, alt: str) -> rx.Component: + return rx.el.div( + rx.image( + src=src, + alt=alt, + loading="lazy", + class_name="pointer-events-none", + ), + class_name="flex justify-center items-center h-12 w-auto", + ) + + +def companies() -> rx.Component: + return rx.el.section( + rx.el.div( + *[company_image(company["src"], company["alt"]) for company in COMPANIES], + class_name="flex flex-row lg:gap-18 max-lg:gap-x-6 max-lg:gap-y-4 flex-wrap justify-center items-center", + ), + rx.el.p( + "Reflex is backed by YC, venture capital firms, and angel investors, including ", + rx.el.br(class_name="max-lg:hidden"), + rx.el.b( + " Qasar Younis", + class_name="text-m-slate-12 font-semibold dark:text-m-slate-3", + ), + " (Applied Intuition), ", + rx.el.b( + " Jack Altman ", + class_name="text-m-slate-12 font-semibold dark:text-m-slate-3", + ), + " (Lattice), ", + rx.el.b( + " Paul Copplestone ", + class_name="text-m-slate-12 font-semibold dark:text-m-slate-3", + ), + " (Supabase), ", + rx.el.b( + " Matt Kraning", + class_name="text-m-slate-12 font-semibold dark:text-m-slate-3", + ), + " (Palo ", + rx.el.br(class_name="max-lg:hidden"), + " Alto Networks, ", + rx.el.b( + " Alfredo Andere ", + class_name="text-m-slate-12 font-semibold dark:text-m-slate-3", + ), + " (Latch Bio), and others.", + class_name="text-m-slate-8 dark:text-m-slate-6 font-medium text-sm max-w-[45.125rem] text-balance text-center leading-6", + ), + class_name="flex flex-col gap-8 max-w-[69rem] mx-auto pt-24 justify-center items-center max-lg:px-6", + ) diff --git a/pcweb/pages/about/views/divider.py b/pcweb/pages/about/views/divider.py new file mode 100644 index 0000000000..181284ceb0 --- /dev/null +++ b/pcweb/pages/about/views/divider.py @@ -0,0 +1,7 @@ +import reflex as rx + + +def divider() -> rx.Component: + return rx.el.hr( + class_name="h-[1px] w-full bg-m-slate-4 dark:bg-m-slate-10", + ) diff --git a/pcweb/pages/about/views/hero.py b/pcweb/pages/about/views/hero.py new file mode 100644 index 0000000000..76c2b17efb --- /dev/null +++ b/pcweb/pages/about/views/hero.py @@ -0,0 +1,104 @@ +import reflex as rx +import reflex_ui as ui + +from pcweb.components.hosting_banner import HostingBannerState + + +def hero() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.p( + "About Reflex", + class_name="text-sm font-[525] text-primary-10 dark:text-m-slate-6", + ), + rx.el.h1( + "The Operating System ", + rx.el.br(class_name="max-lg:hidden"), + " for Most Critical ", + rx.el.br(class_name="max-lg:hidden"), + " Enterprise ", + rx.el.br(class_name="max-lg:hidden"), + " Applications ", + class_name="text-secondary-12 lg:text-5xl text-3xl font-[575]", + ), + rx.el.div( + class_name="absolute -bottom-px -left-24 w-24 h-px bg-gradient-to-r from-transparent to-current text-secondary-4" + ), + class_name="flex flex-col gap-6 border-b border-secondary-4 max-lg:pb-10 xl:pr-16 max-lg:text-center relative", + ), + rx.el.div( + rx.el.div( + rx.el.p( + "Right now, the ", + rx.el.b( + "enterprise stack is fragmented and requires multiple tools and roles to ship an app. ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + "Teams face organizational bottlenecks at every turn—waiting on infrastructure, coordinating between specialists, juggling disconnected platforms. ", + rx.el.b( + " This slows everything down ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + " and makes building production apps unnecessarily complex.", + ), + rx.el.p( + rx.el.b( + "Reflex is the operating system on which enterprises build mission-critical applications. ", + class_name="font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + "We're the only platform that owns the underlying framework and handles the full lifecycle of your app. Our platform lets teams connect securely with company data, use AI to build standardized apps powered by our open source framework, and deploy with a single click to share with their company.", + ), + rx.el.p( + "We're empowering teams to finish the whole production app themselves, without needing to get multiple roles and tools involved. We do this by building solid reusable abstractions at both the framework and infrastructure level. Reflex replaces the fragmented stack, letting teams build, deploy, and manage their apps in a unified platform.", + ), + rx.el.div( + rx.el.div( + rx.image( + src="/about/alek.avif", + alt="Alek", + custom_attrs={"fetchPriority": "high"}, + class_name="size-8 rounded-full pointer-events-none", + ), + rx.image( + src="/about/nikhil.avif", + alt="Nikhil", + custom_attrs={"fetchPriority": "high"}, + class_name="size-8 rounded-full pointer-events-none", + ), + class_name="flex flex-row items-center -space-x-1", + ), + rx.el.div( + rx.el.p( + "Alek Petuskey & Nikhil Rao", + class_name="text-sm font-semibold text-m-slate-12 dark:text-m-slate-3", + ), + rx.el.span( + "Founders", + class_name="text-sm font-[475] text-m-slate-7 dark:text-m-slate-6", + ), + class_name="flex flex-col", + ), + class_name="flex flex-row gap-4", + ), + class_name="flex flex-col gap-4 text-base text-m-slate-7 font-[475] dark:text-m-slate-6", + ), + rx.el.div( + class_name="absolute -top-24 -right-px w-px h-24 bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute -top-24 -left-px w-px h-24 bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute -bottom-px -right-24 w-24 h-px bg-gradient-to-l from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + class_name="flex flex-col gap-8 lg:p-12 p-6 border border-m-slate-4 dark:border-m-slate-10 shadow-[0_6px_16px_0_rgba(0,0,0,0.04)_inset] dark:shadow-none dark:bg-[linear-gradient(212deg,var(--m-slate-12)_0%,var(--m-slate-11)_100%)] lg:max-w-[34.5rem] w-full relative", + ), + class_name=ui.cn( + "flex lg:flex-row flex-col max-w-(--layout-max-width) mx-auto lg:px-24 px-6 overflow-hidden", + rx.cond( + HostingBannerState.is_banner_visible, + "lg:pt-[14.5rem] pt-[12.5rem]", + "lg:pt-[10.5rem] pt-[7.5rem]", + ), + ), + ) diff --git a/pcweb/pages/about/views/hiring.py b/pcweb/pages/about/views/hiring.py new file mode 100644 index 0000000000..5717668173 --- /dev/null +++ b/pcweb/pages/about/views/hiring.py @@ -0,0 +1,53 @@ +import reflex as rx + +from pcweb.components.marketing_button import button +from pcweb.constants import JOBS_BOARD_URL + + +def hiring() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.div( + rx.el.p( + "We're Hiring", + class_name="text-sm font-[525] text-primary-10 max-lg:text-center dark:text-m-slate-6", + ), + rx.el.div( + rx.el.h1( + "Join the team behind the platform trusted by the next generation", + class_name="text-m-slate-12 dark:text-m-slate-3 lg:text-4xl text-3xl font-[575]", + ), + rx.el.div( + rx.el.p( + "Reflex is growing and we're looking for people who care deeply about developer experience, clean abstractions, and shipping things that matter.", + class_name="text-base text-m-slate-7 dark:text-m-slate-6 font-[475]", + ), + rx.el.a( + button( + "See Open Positions", + variant="primary", + size="lg", + class_name="w-fit", + ), + to=JOBS_BOARD_URL, + target="_blank", + ), + class_name="flex flex-col gap-6 lg:pr-12 pt-2", + ), + class_name="flex lg:flex-row flex-col gap-8 lg:gap-36", + ), + rx.el.div( + class_name="absolute right-0 top-0 w-px h-full bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10 from-[-20%] to-100%" + ), + class_name="relative flex flex-col gap-6 lg:py-24 py-16", + ), + rx.el.div( + class_name="absolute -bottom-px right-0 w-24 h-px bg-gradient-to-l from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute -bottom-px left-0 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + class_name="flex max-w-(--layout-max-width) mx-auto lg:px-24 px-6 max-lg:text-center relative", + ), + class_name="bg-gradient-to-b from-white-1 to-m-slate-1 dark:from-m-slate-11 dark:to-m-slate-12 w-full", + ) diff --git a/pcweb/pages/about/views/news.py b/pcweb/pages/about/views/news.py new file mode 100644 index 0000000000..4b31b8edad --- /dev/null +++ b/pcweb/pages/about/views/news.py @@ -0,0 +1,88 @@ +import reflex as rx +import reflex_ui as ui + +from pcweb.components.marketing_button import button +from pcweb.pages.blog import blogs +from pcweb.pages.blog.paths import blog_data + + +def news_item(title: str, date: str, description: str, url: str) -> rx.Component: + return rx.el.div( + rx.el.div( + rx.moment( + rx.Var.create(date).to(str), + format="MMM DD YYYY", + class_name="text-m-slate-7 dark:text-m-slate-6 text-xs font-[415] font-mono uppercase", + ), + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_rectangle_xs.svg", + class_name="pointer-events-none", + alt="Squares Rectangle XS", + loading="lazy", + ), + class_name="flex flex-row items-center lg:gap-6 gap-4 mb-6", + ), + rx.el.p( + title, + class_name="text-m-slate-12 dark:text-m-slate-3 text-2xl leading-9 font-semibold mb-4", + ), + rx.el.p( + description, + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475] mb-6", + ), + rx.el.a( + button( + "Read More", + ui.icon( + "ArrowRight01Icon", + ), + variant="ghost", + size="xs", + class_name="font-[525] w-fit text-m-slate-12 dark:text-m-slate-3 px-0", + ), + to=f"/blog/{url}", + class_name="mt-auto w-fit", + ), + class_name="flex flex-col relative", + ) + + +def news() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.div( + ui.icon( + "NotificationSquareIcon", + class_name="text-primary-10 dark:text-m-slate-6", + ), + rx.el.h2( + "What's New In Reflex", + class_name="text-primary-10 dark:text-m-slate-6 text-sm font-medium", + ), + class_name="flex flex-row items-center gap-2", + ), + rx.el.a( + button( + "Browse All", + variant="outline", + size="sm", + class_name="w-fit", + ), + to=blogs.path, + ), + class_name="flex flex-row justify-between items-center", + ), + rx.el.div( + *[ + news_item( + blog.metadata["title"], + blog.metadata["date"], + blog.metadata["description"], + path, + ) + for path, blog in list(blog_data.items())[:3] + ], + class_name="grid lg:grid-cols-3 grid-cols-1 gap-12", + ), + class_name="flex flex-col gap-12 w-[69rem] max-w-[calc(100vw-3rem)] mx-auto lg:p-12 p-6 rounded-xl bg-m-slate-1 dark:bg-m-slate-11 backdrop-blur-[16px] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_12px_24px_0_rgba(0,0,0,0.08),0_1px_1px_0_rgba(0,0,0,0.01),0_4px_8px_0_rgba(0,0,0,0.03),0_0_0_1px_#FFF_inset] dark:shadow-none dark:border-t dark:border-m-slate-9 lg:mb-36 mb-24 lg:mt-24 mt-10", + ) diff --git a/pcweb/pages/about/views/square_logo.py b/pcweb/pages/about/views/square_logo.py new file mode 100644 index 0000000000..0ab6f4d923 --- /dev/null +++ b/pcweb/pages/about/views/square_logo.py @@ -0,0 +1,31 @@ +import reflex as rx + +# def square_logo() -> rx.Component: +# return rx.el.section( +# # Light mode +# rx.el.div( +# logo_reveal( +# grid_bg_src="/common/light/squares_logo.svg", +# ), +# class_name="dark:hidden", +# ), +# # Dark mode +# rx.el.div( +# logo_reveal( +# grid_bg_src="/common/dark/squares_logo.svg", +# ), +# class_name="hidden dark:block", +# ), +# class_name="max-w-(--layout-max-width) w-full h-auto", +# ) + + +def square_logo() -> rx.Component: + return rx.el.section( + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_logo.svg", + alt="Square Logo", + loading="lazy", + ), + class_name="max-w-(--layout-max-width) w-fullh-auto", + ) diff --git a/pcweb/pages/about/views/team.py b/pcweb/pages/about/views/team.py new file mode 100644 index 0000000000..5563102eab --- /dev/null +++ b/pcweb/pages/about/views/team.py @@ -0,0 +1,34 @@ +import reflex as rx + + +def team() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.image( + src="/about/team_1.avif", + alt="Team 1", + loading="lazy", + class_name="col-span-1 row-span-2 pointer-events-none", + ), + rx.image( + src="/about/team_2.avif", + alt="Team 2", + loading="lazy", + class_name="pointer-events-none", + ), + rx.image( + src="/about/team_3.avif", + alt="Team 3", + loading="lazy", + class_name="pointer-events-none", + ), + class_name="grid lg:grid-cols-2 grid-cols-1 grid-rows-2 gap-2 lg:p-2 lg:border border-m-slate-4 dark:border-m-slate-10", + ), + rx.el.div( + class_name="absolute bottom-0 right-0 w-24 h-px bg-gradient-to-l from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute bottom-0 left-0 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + class_name="lg:px-24 px-6 max-w-(--layout-max-width) mx-auto relative", + ) diff --git a/pcweb/pages/booked.py b/pcweb/pages/booked.py index 82c4fc2b1a..dcd5b0a78a 100644 --- a/pcweb/pages/booked.py +++ b/pcweb/pages/booked.py @@ -1,11 +1,11 @@ import reflex as rx import reflex_ui as ui -from pcweb.components.docpage.navbar import navbar from pcweb.meta.meta import create_meta_tags from pcweb.pages.docs import getting_started from pcweb.pages.framework.index_colors import index_colors from pcweb.pages.framework.views.footer_index import footer_index +from pcweb.views.marketing_navbar import marketing_navbar def booked_title(): @@ -34,7 +34,7 @@ def booked_title(): def booked() -> rx.Component: return rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.section( booked_title(), rx.box( diff --git a/pcweb/pages/customers/views/footer.py b/pcweb/pages/customers/views/footer.py index 949aa76966..c8c35bf9de 100644 --- a/pcweb/pages/customers/views/footer.py +++ b/pcweb/pages/customers/views/footer.py @@ -177,5 +177,5 @@ def footer_customer() -> rx.Component: news_letter(), class_name="grid grid-cols-1 lg:grid-cols-3 gap-0 grid-rows-2 w-full lg:divide-y divide-slate-3 lg:divide-x border-t border-slate-3", ), - class_name="flex max-w-[64.19rem] justify-center items-center w-full", + class_name="flex max-w-[64.19rem] justify-center items-center w-full mx-auto", ) diff --git a/pcweb/pages/docs_landing/__init__.py b/pcweb/pages/docs_landing/__init__.py new file mode 100644 index 0000000000..b3e8d2950a --- /dev/null +++ b/pcweb/pages/docs_landing/__init__.py @@ -0,0 +1,47 @@ +import reflex as rx + +from pcweb.meta.meta import create_meta_tags +from pcweb.pages.docs_landing.views import ( + ai_builder_section, + divider, + enterprise_section, + framework, + hero, + hosting_section, + other_section, + self_hosting_section, +) +from pcweb.pages.framework.views.footer_index import footer_index +from pcweb.views.docs_navbar import docs_navbar + + +@rx.page( + route="/docs", + title="Reflex · Docs", + meta=create_meta_tags( + title="Reflex · Docs", + description="Docs for Reflex - The platform to build and scale enterprise apps", + image="/previews/index_preview.webp", + ), +) +def docs_landing() -> rx.Component: + return rx.el.div( + docs_navbar(), + rx.el.main( + rx.el.div( + hero(), + divider(), + ai_builder_section(), + framework(), + enterprise_section(), + hosting_section(), + self_hosting_section(), + other_section(), + divider(), + footer_index(), + class_name="flex flex-col relative justify-center items-center w-full overflow-hidden", + ), + class_name="flex flex-col w-full relative h-full justify-center items-center", + ), + class_name="flex flex-col w-full justify-center items-center relative dark:bg-m-slate-12 bg-m-slate-1", + ) diff --git a/pcweb/pages/docs_landing/views/__init__.py b/pcweb/pages/docs_landing/views/__init__.py new file mode 100644 index 0000000000..df1f5efcbb --- /dev/null +++ b/pcweb/pages/docs_landing/views/__init__.py @@ -0,0 +1,21 @@ +from .ai_builder import ai_builder_section +from .divider import divider +from .enterprise import enterprise_section +from .framework import framework +from .hero import hero +from .hosting import hosting_section +from .link_item import link_item +from .other import other_section +from .self_hosting import self_hosting_section + +__all__ = [ + "ai_builder_section", + "divider", + "enterprise_section", + "framework", + "hero", + "hosting_section", + "link_item", + "other_section", + "self_hosting_section", +] diff --git a/pcweb/pages/docs_landing/views/ai_builder.py b/pcweb/pages/docs_landing/views/ai_builder.py new file mode 100644 index 0000000000..a04ecedb1a --- /dev/null +++ b/pcweb/pages/docs_landing/views/ai_builder.py @@ -0,0 +1,131 @@ +import reflex as rx +import reflex_ui as ui + +from pcweb.components.marquee import marquee +from pcweb.constants import INTEGRATIONS_IMAGES_URL +from pcweb.pages.docs import ai_builder as ai_builder_pages +from pcweb.pages.integrations.integration_list import get_integration_path + + +def card( + title: str, description: str, content: str, href: str, enteprise_only: bool = False +) -> rx.Component: + return rx.el.div( + rx.el.span( + "Enterprise-only", + class_name="text-m-slate-12 dark:text-m-slate-3 text-xs font-medium bg-m-slate-1 dark:bg-m-slate-11 px-2.5 h-7 absolute top-0 right-0 border-b border-l rounded-bl-lg border-m-slate-4 dark:border-m-slate-9 flex justify-center items-center", + ) + if enteprise_only + else None, + rx.el.div( + rx.el.span( + title, + class_name="text-m-slate-12 dark:text-m-slate-3 text-xl font-[575]", + ), + rx.el.span( + description, + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + class_name="flex flex-col gap-2 p-8", + ), + content, + rx.el.a(to=href, class_name="absolute inset-0"), + class_name="flex flex-col bg-white/96 dark:bg-m-slate-11 backdrop-blur-[16px] rounded-xl relative cursor-pointer transition-colors overflow-hidden shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_12px_24px_0_rgba(0,0,0,0.08),0_1px_1px_0_rgba(0,0,0,0.01),0_4px_8px_0_rgba(0,0,0,0.03)] dark:shadow-none dark:border-t dark:border-m-slate-9", + ) + + +def integration_icon_marquee(integration_name: str) -> rx.Component: + normalized_name = integration_name.lower().replace(" ", "_") + return ui.avatar.root( + ui.avatar.image( + src=rx.color_mode_cond( + f"{INTEGRATIONS_IMAGES_URL}light/{normalized_name}.svg", + f"{INTEGRATIONS_IMAGES_URL}dark/{normalized_name}.svg", + ), + unstyled=True, + class_name="size-full", + ), + ui.avatar.fallback( + integration_name[0], + class_name="text-m-slate-12 dark:text-m-slate-3 text-base font-semibold uppercase size-full", + unstyled=True, + ), + unstyled=True, + class_name="size-6.5 flex items-center justify-center mx-3", + ) + + +@rx.memo +def integrations_marquee() -> rx.Component: + integration_names = [ + next(iter(item.values()))["name"] for item in get_integration_path() + ] + return rx.el.div( + marquee( + *[integration_icon_marquee(name) for name in reversed(integration_names)], + direction="left", + gradient_color="light-dark(rgba(255, 255, 255, 0.96), var(--m-slate-11))", + class_name="h-auto w-full overflow-hidden", + gradient_width=65, + speed=25, + pause_on_hover=False, + ), + marquee( + *[integration_icon_marquee(name) for name in integration_names], + direction="right", + gradient_color="light-dark(rgba(255, 255, 255, 0.96), var(--m-slate-11))", + class_name="h-auto w-full overflow-hidden", + gradient_width=65, + speed=25, + pause_on_hover=False, + ), + class_name="flex flex-col gap-6.5 px-8 max-lg:pb-6", + ) + + +def ai_builder_section() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.div( + rx.el.h2( + "AI Builder", + class_name="text-m-slate-12 dark:text-m-slate-3 text-3xl font-[575]", + ), + rx.el.p( + "Learn how to build applications with Reflex AI.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + card( + title="Getting Started", + description="A comprehensive guide to working effectively with AI Builder. The key to success is clarity, structure, and iteration.", + content=rx.image( + src=f"/docs/{rx.color_mode_cond('light', 'dark')}/getting_started.svg", + class_name="w-full h-auto pb-8", + ), + href=ai_builder_pages.overview.best_practices.path, + ), + card( + title="Integrations", + description="Easily connect with the tools your team already uses or extend your app with any Python SDK, library, or API.", + content=integrations_marquee(), + href=ai_builder_pages.integrations.overview.path, + ), + card( + title="MCP", + description="The Reflex Model Context Protocol (MCP) provides AI assistants and coding tools with structured access to Reflex documentation and component information.", + content=rx.image( + src=f"/docs/{rx.color_mode_cond('light', 'dark')}/mcp.svg", + class_name="w-full h-auto -mt-4", + ), + href=ai_builder_pages.integrations.mcp_overview.path, + enteprise_only=True, + ), + class_name="grid grid-cols-1 lg:grid-cols-3 gap-12", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto", + ), + class_name="bg-gradient-to-b from-white-1 to-m-slate-1 dark:from-m-slate-11 dark:to-m-slate-12 w-full lg:pt-24 lg:pb-24 pb-10 max-xl:px-6 max-lg:pt-10", + ) diff --git a/pcweb/pages/docs_landing/views/divider.py b/pcweb/pages/docs_landing/views/divider.py new file mode 100644 index 0000000000..181284ceb0 --- /dev/null +++ b/pcweb/pages/docs_landing/views/divider.py @@ -0,0 +1,7 @@ +import reflex as rx + + +def divider() -> rx.Component: + return rx.el.hr( + class_name="h-[1px] w-full bg-m-slate-4 dark:bg-m-slate-10", + ) diff --git a/pcweb/pages/docs_landing/views/enterprise.py b/pcweb/pages/docs_landing/views/enterprise.py new file mode 100644 index 0000000000..b58987f3c2 --- /dev/null +++ b/pcweb/pages/docs_landing/views/enterprise.py @@ -0,0 +1,38 @@ +import reflex as rx + +from pcweb.pages.docs import enterprise as enterprise_page +from pcweb.pages.docs_landing.views.link_item import faded_borders, link_item + + +def enterprise_section() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.h2( + "Enterprise", + class_name="text-secondary-12 text-3xl font-[575]", + ), + rx.el.p( + "Learn how to build enterprise-ready applications with Reflex.", + class_name="text-secondary-11 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + faded_borders(), + link_item( + "MenuSquareIcon", + "Components", + "Explore reusable enterprise-grade Reflex UI components designed for scalability, security, and efficient development in complex business environments.", + enterprise_page.ag_grid.index.path, + ), + link_item( + "SquareLockPasswordIcon", + "Extensible Auth", + "Implement flexible and secure authentication and authorization systems tailored for enterprise requirements, with support for SSO, OAuth, and advanced access controls.", + enterprise_page.overview.path, + has_padding_left=True, + ), + class_name="grid grid-cols-1 lg:grid-cols-2 border-t border-secondary-4 relative", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto w-full justify-start lg:mb-24 mb-10 max-xl:px-6 overflow-hidden", + ) diff --git a/pcweb/pages/docs_landing/views/framework.py b/pcweb/pages/docs_landing/views/framework.py new file mode 100644 index 0000000000..565c9fe2f2 --- /dev/null +++ b/pcweb/pages/docs_landing/views/framework.py @@ -0,0 +1,190 @@ +import reflex as rx +import reflex_ui as ui + +from pcweb.components.marketing_button import button +from pcweb.pages.docs import authentication, database, getting_started +from pcweb.pages.docs.library import library +from pcweb.pages.library_previews import core_components_dict + + +def docs_item( + icon: str, title: str, description: str, href: str, enterprise_only: bool = False +) -> rx.Component: + return rx.el.div( + rx.el.div( + ui.icon( + icon, + class_name="size-6 group-hover:text-primary-10 group-hover:dark:text-m-slate-5", + stroke_width=1.5, + ), + rx.el.span( + title, + class_name="text-m-slate-12 dark:text-m-slate-3 text-xl font-[575] group-hover:text-primary-10 group-hover:dark:text-m-slate-5", + ), + rx.el.div( + "Enterprise-only", + class_name="text-m-slate-12 dark:text-m-slate-3 text-xs font-medium bg-m-slate-1 dark:bg-m-slate-11 px-2.5 h-7 border-b border rounded-lg border-m-slate-4 dark:border-m-slate-10 flex justify-center items-center ml-1", + ) + if enterprise_only + else None, + ui.icon( + "ArrowRight01Icon", + class_name="size-4 ml-auto group-hover:text-primary-10 group-hover:dark:text-m-slate-5", + ), + class_name="flex row items-center gap-3 h-8", + ), + rx.el.p( + description, + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + rx.el.a(to=href, class_name="absolute inset-0"), + class_name="flex flex-col gap-2 py-8 pr-8 relative group lg:max-w-[21rem] w-full max-lg:text-start hover:bg-[linear-gradient(243deg,var(--m-slate-2,#F6F7F9)_0%,var(--m-slate-1,#FCFCFD)_100%)] dark:hover:bg-[linear-gradient(243deg,var(--m-slate-11,#1D2025)_0%,var(--m-slate-12,#151618)_63.63%)]", + ) + + +def links_section() -> rx.Component: + return rx.el.div( + docs_item( + "SourceCodeSquareIcon", + "How It Works", + "Learn the basics of how Reflex works behind the scenes and how its architecture enables flexible, advanced usage.", + getting_started.introduction.path, + ), + docs_item( + "ShieldUserIcon", + "Auth", + "Implement secure authentication for your apps using Reflex’s built-in features and extensible architecture.", + authentication.authentication_overview.path, + enterprise_only=True, + ), + docs_item( + "DatabaseIcon", + "Database", + "Manage and interact with your data seamlessly using Reflex’s straightforward models and querying approach.", + database.overview.path, + ), + class_name="flex flex-col border-r border-y border-secondary-4 divide-y divide-secondary-4", + ) + + +def component_link(name: str, href: str) -> rx.Component: + return rx.el.a( + button( + name, + ui.icon("ArrowRight01Icon", class_name="ml-auto"), + variant="ghost", + size="xs", + class_name="font-[525] w-full text-m-slate-12 dark:text-m-slate-3 px-0", + ), + to=f"/docs/library/{href.strip('/')}", + class_name="w-full", + ) + + +def components_section() -> rx.Component: + return rx.el.div( + rx.el.div( + rx.el.div( + ui.icon("MenuSquareIcon", class_name="size-6", stroke_width=1.5), + rx.el.span( + "Component Library", + class_name="text-m-slate-12 dark:text-m-slate-3 text-xl font-[575] group-hover:text-primary-10", + ), + class_name="flex row items-center gap-3 h-8", + ), + rx.el.p( + "Build your app with our comprehensive collection of UI components and features.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475] max-w-[16.5rem]", + ), + rx.el.a( + button( + "Browse All Components", + variant="outline", + native_button=False, + class_name="font-[525] w-fit text-m-slate-12 dark:text-m-slate-3", + ), + to=library.path, + class_name="w-fit mt-4", + ), + class_name="flex flex-col gap-2 max-lg:text-start", + ), + rx.el.div( + rx.el.div( + component_link( + "Data Display", core_components_dict["data-display"]["path"] + ), + component_link( + "Disclosure", core_components_dict["disclosure"]["path"] + ), + component_link( + "Dynamic Rendering", + core_components_dict["dynamic_rendering"]["path"], + ), + component_link("Forms", core_components_dict["forms"]["path"]), + component_link("Layout", core_components_dict["layout"]["path"]), + component_link("Media", core_components_dict["media"]["path"]), + class_name="flex flex-col gap-2", + ), + rx.el.div( + component_link("Other", core_components_dict["other"]["path"]), + component_link("Overlays", core_components_dict["overlays"]["path"]), + component_link( + "Tables And Data Grids Rendering", + core_components_dict["tables_and_data_grids"]["path"], + ), + component_link( + "Typography", core_components_dict["typography"]["path"] + ), + class_name="flex flex-col gap-2", + ), + class_name="grid grid-cols-1 lg:grid-cols-2 lg:gap-28 gap-10 mt-auto", + ), + class_name="flex flex-col gap-4 lg:px-8 pt-8 max-lg:pr-8 pb-6 h-auto w-full flex-1 border-r border-m-slate-4 dark:border-m-slate-10 border-y", + ) + + +def squares_divider() -> rx.Component: + return rx.el.div( + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_vertical_docs.svg", + alt="Squares Vertical Docs", + loading="lazy", + class_name="pointer-events-none w-auto h-full", + ), + class_name="flex p-4.5 h-auto border-r border-y border-m-slate-4 dark:border-m-slate-10 max-lg:hidden", + ) + + +def framework() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.h2( + "Framework", + class_name="text-m-slate-12 dark:text-m-slate-3 text-3xl font-[575]", + ), + rx.el.p( + "Learn how to build applications with Reflex Framework.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + rx.el.div( + class_name="absolute bottom-0 -left-24 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute top-0 -left-24 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute bottom-0 -right-24 w-24 h-px bg-gradient-to-l from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute right-0 -top-24 h-24 w-px bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + links_section(), + squares_divider(), + components_section(), + class_name="flex flex-col lg:flex-row relative", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto w-full justify-start lg:mb-24 mb-10 max-xl:px-6 overflow-hidden", + ) diff --git a/pcweb/pages/docs_landing/views/hero.py b/pcweb/pages/docs_landing/views/hero.py new file mode 100644 index 0000000000..ba8e952db3 --- /dev/null +++ b/pcweb/pages/docs_landing/views/hero.py @@ -0,0 +1,65 @@ +import reflex as rx +import reflex_ui as ui + +from pcweb.components.hosting_banner import HostingBannerState +from pcweb.components.marketing_button import button +from pcweb.pages.docs import getting_started + + +def hero() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.p( + "About Reflex", + class_name="text-sm font-[525] text-m-slate-10 dark:text-m-slate-6", + ), + rx.el.h1( + "Reflex Documentation", + class_name="text-m-slate-12 dark:text-m-slate-3 lg:text-5xl text-3xl font-[575] lg:text-nowrap", + ), + rx.el.p( + "Get up and running with Reflex in minutes. A complete set ", + rx.el.br(class_name="max-lg:hidden"), + " of resources to build, deploy, and scale your application. ", + class_name="text-base text-m-slate-7 dark:text-m-slate-6 font-[475]", + ), + rx.el.a( + button( + "Get Started", + ui.icon("ArrowRightIcon"), + variant="primary", + size="md", + native_button=False, + class_name="w-fit", + ), + to=getting_started.introduction.path, + ), + class_name=ui.cn( + "flex flex-col gap-6 max-lg:text-center relative just-start lg:pb-24", + rx.cond( + HostingBannerState.is_banner_visible, + "lg:pt-[14.5rem] pt-[12.5rem]", + "lg:pt-[10.5rem] pt-[7.5rem]", + ), + ), + ), + rx.el.div( + rx.image( + alt="Squares Docs Logo", + custom_attrs={"fetchPriority": "high"}, + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_docs_logo.svg", + class_name="pointer-events-none h-auto w-auto lg:absolute max-lg:hidden", + ), + class_name=ui.cn( + "flex", + rx.cond( + HostingBannerState.is_banner_visible, + "lg:pt-[8.5rem] pt-0", + "lg:pt-[4.5rem] pt-0", + ), + ), + ), + class_name=ui.cn( + "flex lg:flex-row flex-col max-w-(--docs-layout-max-width) mx-auto w-full max-lg:pb-10 max-xl:px-6", + ), + ) diff --git a/pcweb/pages/docs_landing/views/hosting.py b/pcweb/pages/docs_landing/views/hosting.py new file mode 100644 index 0000000000..afe8d14aed --- /dev/null +++ b/pcweb/pages/docs_landing/views/hosting.py @@ -0,0 +1,51 @@ +import reflex as rx + +from pcweb.pages.docs import hosting as hosting_page +from pcweb.pages.docs_landing.views.link_item import faded_borders, link_item + + +def hosting_section() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.h2( + "Cloud", + class_name="text-m-slate-12 dark:text-m-slate-3 text-3xl font-[575]", + ), + rx.el.p( + "Learn how to host your applications with Reflex Hosting.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + faded_borders(), + link_item( + "CloudServerIcon", + "How to Host", + "Step-by-step instructions to deploy your Reflex application to the cloud, including configuration and setup guides.", + hosting_page.deploy_quick_start.path, + ), + link_item( + "LockKeyIcon", + "Secret Management", + "How to securely manage sensitive environment variables, API keys, and secrets in Reflex Hosting.", + hosting_page.secrets_environment_vars.path, + has_padding_left=True, + ), + link_item( + "EyeIcon", + "Observability", + "Monitor your application's health, view logs, and gain insights using Reflex Hosting's integrated observability tools.", + hosting_page.logs.path, + ), + link_item( + "CodeIcon", + "Custom Headers and Advanced Options", + "Configure custom HTTP headers, set caching policies, and explore advanced hosting settings for your Reflex app.", + hosting_page.deploy_quick_start.path, + has_padding_left=True, + ), + class_name="grid grid-cols-1 lg:grid-cols-2 border-t border-m-slate-4 dark:border-m-slate-10 relative", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto w-full justify-start max-xl:px-6 lg:mb-24 overflow-hidden", + ) diff --git a/pcweb/pages/docs_landing/views/link_item.py b/pcweb/pages/docs_landing/views/link_item.py new file mode 100644 index 0000000000..303f05c19a --- /dev/null +++ b/pcweb/pages/docs_landing/views/link_item.py @@ -0,0 +1,51 @@ +import reflex as rx +import reflex_ui as ui + + +def faded_borders() -> rx.Component: + return rx.fragment( + rx.el.div( + class_name="absolute bottom-0 -left-24 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute -top-px -left-24 w-24 h-px bg-gradient-to-r from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute bottom-0 -right-24 w-24 h-px bg-gradient-to-l from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + rx.el.div( + class_name="absolute right-0 -top-24 h-24 w-px bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10" + ), + ) + + +def link_item( + icon: str, title: str, description: str, href: str, has_padding_left: bool = False +) -> rx.Component: + return rx.el.div( + rx.el.div( + ui.icon( + icon, + class_name="size-6 shrink-0 group-hover:text-primary-10 group-hover:dark:text-m-slate-5", + stroke_width=1.5, + ), + rx.el.span( + title, + class_name="text-m-slate-12 dark:text-m-slate-3 text-xl font-[575] group-hover:text-primary-10 group-hover:dark:text-m-slate-5", + ), + ui.icon( + "ArrowRight01Icon", + class_name="size-4 ml-auto group-hover:text-primary-10 group-hover:dark:text-m-slate-5 shrink-0", + ), + class_name="flex flex-row gap-3 items-center max-lg:text-start", + ), + rx.el.span( + description, + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475] text-start", + ), + rx.el.a(to=href, class_name="absolute inset-0"), + class_name=ui.cn( + "flex flex-col gap-2 pr-8 py-8 group border-r border-b border-m-slate-4 dark:border-m-slate-10 relative max-lg:p-6 hover:bg-[linear-gradient(243deg,var(--m-slate-2,#F6F7F9)_0%,var(--m-slate-1,#FCFCFD)_100%)] dark:hover:bg-[linear-gradient(243deg,var(--m-slate-11,#1D2025)_0%,var(--m-slate-12,#151618)_63.63%)]", + "lg:pl-8 pl-6" if has_padding_left else "", + ), + ) diff --git a/pcweb/pages/docs_landing/views/other.py b/pcweb/pages/docs_landing/views/other.py new file mode 100644 index 0000000000..43a0e9cc1c --- /dev/null +++ b/pcweb/pages/docs_landing/views/other.py @@ -0,0 +1,39 @@ +import reflex as rx + +from pcweb.constants import CONTRIBUTING_URL +from pcweb.pages.docs.custom_components import custom_components +from pcweb.pages.docs_landing.views.link_item import faded_borders, link_item + + +def other_section() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.h2( + "Other", + class_name="text-secondary-12 text-3xl font-[575]", + ), + rx.el.p( + "Learn about other features and tools that Reflex offers.", + class_name="text-secondary-11 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + link_item( + "GitCommitIcon", + "Contributing", + "Learn how to contribute code, report issues, and help improve Reflex. Find guidelines and resources to get started with open-source development.", + CONTRIBUTING_URL, + ), + link_item( + "ReactIcon", + "Extending with React Components", + "See how to create and integrate your own React components into Reflex apps, allowing you to customize and extend your project’s capabilities.", + custom_components.path, + has_padding_left=True, + ), + faded_borders(), + class_name="grid grid-cols-1 lg:grid-cols-2 border-t border-secondary-4 relative", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto w-full justify-start lg:mb-24 mb-10 max-xl:px-6 overflow-hidden", + ) diff --git a/pcweb/pages/docs_landing/views/self_hosting.py b/pcweb/pages/docs_landing/views/self_hosting.py new file mode 100644 index 0000000000..609d246813 --- /dev/null +++ b/pcweb/pages/docs_landing/views/self_hosting.py @@ -0,0 +1,38 @@ +import reflex as rx + +from pcweb.pages.docs import hosting as hosting_page +from pcweb.pages.docs_landing.views.link_item import faded_borders, link_item + + +def self_hosting_section() -> rx.Component: + return rx.el.section( + rx.el.div( + rx.el.h2( + "Self-Hosting", + class_name="text-secondary-12 text-3xl font-[575]", + ), + rx.el.p( + "Learn how to self-host your applications with Reflex.", + class_name="text-secondary-11 text-sm font-[475]", + ), + class_name="flex flex-col gap-4", + ), + rx.el.div( + faded_borders(), + link_item( + "ServerStack01Icon", + "Run Reflex App in Dockerized Environment", + "Build and deploy Reflex apps in Docker containers.", + hosting_page.self_hosting.path, + ), + link_item( + "BrowserIcon", + "Deploy to Databricks and Snowflake", + "Integrate and deploy Reflex apps to Databricks or Snowflake.", + hosting_page.databricks.path, + has_padding_left=True, + ), + class_name="grid grid-cols-1 lg:grid-cols-2 border-t border-secondary-4 relative", + ), + class_name="flex flex-col gap-10 max-lg:text-center relative max-w-(--docs-layout-max-width) mx-auto w-full justify-start lg:mb-24 mb-10 max-xl:px-6 overflow-hidden max-lg:pt-10", + ) diff --git a/pcweb/pages/framework/views/footer_index.py b/pcweb/pages/framework/views/footer_index.py index c184e0e5ed..ddc411d557 100644 --- a/pcweb/pages/framework/views/footer_index.py +++ b/pcweb/pages/framework/views/footer_index.py @@ -205,5 +205,5 @@ def footer_index() -> rx.Component: newsletter(), class_name="grid grid-cols-1 lg:grid-cols-3 gap-0 grid-rows-2 w-full divide-y divide-slate-3 lg:divide-x border-t border-slate-3 lg:border-t-0", ), - class_name="flex max-w-[64.19rem] justify-center items-center w-full", + class_name="flex max-w-[64.19rem] justify-center items-center w-full mx-auto", ) diff --git a/pcweb/pages/landing/views/social_marquee.py b/pcweb/pages/landing/views/social_marquee.py index 4747491e9e..3188bca968 100644 --- a/pcweb/pages/landing/views/social_marquee.py +++ b/pcweb/pages/landing/views/social_marquee.py @@ -143,5 +143,5 @@ def social_marquee() -> rx.Component: *[social_card(social) for social in SOCIALS_2], direction="right", ), - class_name="flex flex-col mx-auto w-full max-w-[64.19rem] lg:border-x justify-center items-center relative overflow-hidden border-slate-3 border-b", + class_name="flex flex-col mx-auto w-full max-w-[64.19rem] lg:border-x justify-center items-center relative overflow-hidden border-slate-3 border-b [&>div]:overflow-y-hidden", ) diff --git a/pcweb/pages/pricing/pricing.py b/pcweb/pages/pricing/pricing.py index cbb55c5ce3..660cf2fa58 100644 --- a/pcweb/pages/pricing/pricing.py +++ b/pcweb/pages/pricing/pricing.py @@ -18,11 +18,11 @@ ) def pricing() -> rx.Component: """Get the Pricing landing page.""" - from pcweb.components.docpage.navbar import navbar + from pcweb.views.marketing_navbar import marketing_navbar return rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.main( rx.box( plan_cards(), diff --git a/pcweb/pages/to_be_booked.py b/pcweb/pages/to_be_booked.py index be4c28ae1a..eb4982f87f 100644 --- a/pcweb/pages/to_be_booked.py +++ b/pcweb/pages/to_be_booked.py @@ -1,11 +1,11 @@ import reflex as rx import reflex_ui as ui -from pcweb.components.docpage.navbar import navbar from pcweb.meta.meta import create_meta_tags from pcweb.pages.docs import getting_started from pcweb.pages.framework.index_colors import index_colors from pcweb.pages.framework.views.footer_index import footer_index +from pcweb.views.marketing_navbar import marketing_navbar def to_be_booked_title(): @@ -34,7 +34,7 @@ def to_be_booked_title(): def to_be_booked() -> rx.Component: return rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.section( to_be_booked_title(), rx.box( diff --git a/pcweb/pcweb.py b/pcweb/pcweb.py index c2bedfcadb..950d2fd065 100644 --- a/pcweb/pcweb.py +++ b/pcweb/pcweb.py @@ -99,7 +99,6 @@ ("/docs/ai-builder", "/docs/ai-builder/overview/best-practices"), ("/docs/ai-builder/overview", "/docs/ai-builder/overview/best-practices"), ("/framework", "/open-source"), - ("/docs", "/docs/getting-started/introduction"), ("/docs/getting-started", "/docs/getting-started/introduction"), ("/docs/state", "/docs/state/overview"), ("/docs/styling", "/docs/styling/overview"), diff --git a/pcweb/templates/docpage/docpage.py b/pcweb/templates/docpage/docpage.py index 849d22a598..5a9ebcade3 100644 --- a/pcweb/templates/docpage/docpage.py +++ b/pcweb/templates/docpage/docpage.py @@ -432,11 +432,11 @@ def breadcrumb(path: str, nav_sidebar: rx.Component): class_name="p-[0.563rem] lg:hidden flex", ), class_name=ui.cn( - "relative z-10 flex flex-row justify-between items-center gap-4 lg:gap-0 border-slate-4 bg-slate-1 mt-[110px] mb-6 lg:mb-8 p-[0.5rem_1rem_0.5rem_1rem] lg:p-0 border-b lg:border-none w-full", + "relative z-10 flex flex-row justify-between items-center gap-4 lg:gap-0 border-slate-4 bg-slate-1 mt-[135px] mb-6 lg:mb-8 p-[0.5rem_1rem_0.5rem_1rem] lg:p-0 border-b lg:border-none w-full", rx.cond( HostingBannerState.is_banner_visible, "lg:mt-[175px]", - "lg:mt-[119px] mt-[51px]", + "lg:mt-[145px] mt-[77px]", ), ), ) @@ -549,10 +549,10 @@ def wrapper(*args, **kwargs) -> rx.Component: Returns: The page with the template applied. """ - from pcweb.components.docpage.navbar import navbar from pcweb.components.docpage.sidebar import get_prev_next from pcweb.components.docpage.sidebar import sidebar as sb from pcweb.components.hosting_banner import HostingBannerState + from pcweb.views.docs_navbar import docs_navbar sidebar = sb(url=path, width="300px") @@ -624,9 +624,8 @@ def wrapper(*args, **kwargs) -> rx.Component: toc, comp = comp show_right_sidebar = right_sidebar and len(toc) >= 2 - return rx.box( - navbar(), + docs_navbar(), rx.el.main( rx.box( sidebar, diff --git a/pcweb/templates/gallery_app_page.py b/pcweb/templates/gallery_app_page.py index 4c5837fa29..551397f6c8 100644 --- a/pcweb/templates/gallery_app_page.py +++ b/pcweb/templates/gallery_app_page.py @@ -58,15 +58,15 @@ def wrapper(*children, **props) -> rx.Component: The component with the template applied. """ # Import here to avoid circular imports. - from pcweb.components.docpage.navbar import navbar from pcweb.pages.framework.views.footer_index import footer_index from pcweb.views.bottom_section.bottom_section import bottom_section + from pcweb.views.marketing_navbar import marketing_navbar # Wrap the component in the template. return rx.box( rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.main( contents(*children, **props), class_name="w-full z-[1] relative flex flex-col mx-auto lg:border-x border-slate-3 pt-24 lg:pt-48", diff --git a/pcweb/templates/highlightpage.py b/pcweb/templates/highlightpage.py index a2c5a1fb16..f0ffcaca58 100644 --- a/pcweb/templates/highlightpage.py +++ b/pcweb/templates/highlightpage.py @@ -55,16 +55,16 @@ def wrapper(*children, **props) -> rx.Component: The component with the template applied. """ # Import here to avoid circular imports. - from pcweb.components.docpage.navbar import navbar from pcweb.pages.customers.views.footer import footer_customer from pcweb.pages.framework.index_colors import index_colors from pcweb.views.bottom_section.bottom_section import bottom_section + from pcweb.views.marketing_navbar import marketing_navbar # Wrap the component in the template. return rx.box( rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.main( contents(*children, **props), rx.box(class_name="flex-grow"), diff --git a/pcweb/templates/mainpage.py b/pcweb/templates/mainpage.py index 605bd2b3e8..ca078419f4 100644 --- a/pcweb/templates/mainpage.py +++ b/pcweb/templates/mainpage.py @@ -57,22 +57,22 @@ def wrapper(*children, **props) -> rx.Component: The component with the template applied. """ # Import here to avoid circular imports. - from pcweb.components.docpage.navbar import navbar from pcweb.components.hosting_banner import HostingBannerState from pcweb.pages.framework.index_colors import index_colors from pcweb.pages.framework.views.footer_index import footer_index from pcweb.pages.framework.views.get_started import get_started + from pcweb.views.marketing_navbar import marketing_navbar # Wrap the component in the template. return rx.box( index_colors(), - navbar(), + marketing_navbar(), rx.el.main( contents(*children, **props), get_started(), ), footer_index(), - class_name="flex flex-col w-full max-w-[94.5rem] justify-center items-center mx-auto px-4 lg:px-5 relative overflow-hidden", + class_name="flex flex-col w-full max-w-[94.5rem] justify-center mx-auto px-4 lg:px-5 relative overflow-hidden", padding_top=rx.cond( HostingBannerState.is_banner_visible, "56px", diff --git a/pcweb/templates/storypage.py b/pcweb/templates/storypage.py index 4aee936199..431a5caf68 100644 --- a/pcweb/templates/storypage.py +++ b/pcweb/templates/storypage.py @@ -252,15 +252,15 @@ def wrapper(*children, **props) -> rx.Component: The component with the template applied. """ # Import here to avoid circular imports. - from pcweb.components.docpage.navbar import navbar from pcweb.pages.customers.views.footer import footer_customer from pcweb.views.bottom_section.bottom_section import bottom_section + from pcweb.views.marketing_navbar import marketing_navbar # Wrap the component in the template. return rx.box( rx.box( index_colors(), - navbar(), + marketing_navbar(), company_card(company, founded, investors, domain), rx.el.main( hero(company, description, stats), diff --git a/pcweb/templates/webpage.py b/pcweb/templates/webpage.py index 507f85c58e..bc6fcd713b 100644 --- a/pcweb/templates/webpage.py +++ b/pcweb/templates/webpage.py @@ -58,15 +58,15 @@ def wrapper(*children, **props) -> rx.Component: The component with the template applied. """ # Import here to avoid circular imports. - from pcweb.components.docpage.navbar import navbar from pcweb.components.icons.patterns import default_patterns from pcweb.views.bottom_section.bottom_section import bottom_section from pcweb.views.footer import footer + from pcweb.views.marketing_navbar import marketing_navbar # Wrap the component in the template. return rx.box( *default_patterns(), - navbar(), + marketing_navbar(), rx.el.main( contents(*children, **props), rx.box(class_name="flex-grow"), diff --git a/pcweb/views/docs_navbar.py b/pcweb/views/docs_navbar.py new file mode 100644 index 0000000000..662582264d --- /dev/null +++ b/pcweb/views/docs_navbar.py @@ -0,0 +1,157 @@ +import reflex as rx +import reflex_ui as ui +from reflex_ui.blocks.demo_form import demo_form_dialog + +from pcweb.components.docpage.navbar.buttons.sidebar import navbar_sidebar_button +from pcweb.components.docpage.navbar.search import search_bar +from pcweb.components.marketing_button import button +from pcweb.pages.docs import ai_builder, enterprise, getting_started, hosting + + +def logo() -> rx.Component: + return rx.el.a( + rx.el.div( + rx.image( + src="/logos/light/reflex.svg", + alt="Reflex Logo", + class_name="shrink-0 block dark:hidden", + ), + rx.image( + src="/logos/dark/reflex.svg", + alt="Reflex Logo", + class_name="shrink-0 hidden dark:block", + ), + ), + rx.el.div( + rx.image( + src="/logos/light/docs.svg", + alt="Docs Logo", + class_name="shrink-0 block dark:hidden", + ), + rx.image( + src="/logos/dark/docs.svg", + alt="Docs Logo", + class_name="shrink-0 hidden dark:block", + ), + ), + to="/", + class_name="flex flex-row gap-2.5 items-center shrink-0 mr-10", + ) + + +def menu_item(text: str, href: str, active_str: str = "") -> rx.Component: + router_path = rx.State.router.page.path + active_cn = "shadow-[inset_0_-1px_0_0_var(--primary-10)] [&_button]:text-primary-10 [&_div]:text-primary-10" + + # For paths starting with "/" (like Start), use exact match + # For "framework", it's the default - active when in /docs but not matching other sections + # For other segments (like "ai-builder"), use contains + if active_str.startswith("/"): + active = router_path == active_str + elif active_str == "framework": + # Framework is active when in /docs but not in other specific sections + is_docs = router_path.contains("/docs") + is_ai_builder = router_path.contains("ai-builder") + is_enterprise = router_path.contains("enterprise") + is_hosting = router_path.contains("hosting") + is_start = router_path == "/docs" + active = is_docs & ~is_ai_builder & ~is_enterprise & ~is_hosting & ~is_start + else: + active = router_path.contains(active_str) + + return ui.navigation_menu.item( + rx.el.a( + button( + text, + size="sm", + variant="ghost", + native_button=False, + ), + to=href, + ), + class_name=ui.cn( + "xl:flex hidden h-full items-center justify-center", + rx.cond(active, active_cn, ""), + ), + custom_attrs={"role": "menuitem"}, + ) + + +def navigation_menu() -> rx.Component: + return ui.navigation_menu.root( + ui.navigation_menu.list( + menu_item("Start", "/docs", "/docs"), + menu_item( + "AI Builder", ai_builder.overview.best_practices.path, "ai-builder" + ), + menu_item("Framework", getting_started.introduction.path, "framework"), + menu_item("Enterprise Package", enterprise.overview.path, "enterprise"), + menu_item("Cloud", hosting.deploy_quick_start.path, "hosting"), + class_name="flex flex-row items-center gap-2 m-0 h-full list-none", + custom_attrs={"role": "menubar"}, + ), + ui.navigation_menu.list( + ui.navigation_menu.item( + search_bar(), + unstyled=True, + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + demo_form_dialog( + trigger=button( + "Book a Demo", + size="sm", + variant="primary", + class_name=" whitespace-nowrap max-xl:hidden", + native_button=False, + ), + ), + unstyled=True, + class_name="xl:flex hidden", + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + navbar_sidebar_button(), + class_name="xl:hidden flex", + unstyled=True, + custom_attrs={"role": "menuitem"}, + ), + class_name="flex flex-row lg:gap-4 gap-2 m-0 h-full list-none items-center", + custom_attrs={"role": "menubar"}, + ), + ui.navigation_menu.portal( + ui.navigation_menu.positioner( + ui.navigation_menu.popup( + ui.navigation_menu.viewport(), + unstyled=True, + class_name="relative h-[var(--popup-height)] w-max origin-[var(--transform-origin)] transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:scale-90 data-[starting-style]:opacity-0 min-[500px]:w-[var(--popup-width)] xs:w-[var(--popup-width)] rounded-xl bg-secondary-1 overflow-hidden", + style={ + "box-shadow": "0 0 0 1px rgba(0, 0, 0, 0.03), 0 -1px 1px 0 rgba(0, 0, 0, 0.04), 0 16px 32px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.08), 0 4px 8px 0 rgba(0, 0, 0, 0.03);", + }, + ), + side_offset=30, + align="start", + align_offset=-20, + ), + ), + unstyled=True, + class_name="relative flex w-full items-center h-full justify-between gap-6 mx-auto flex-row", + ) + + +@rx.memo +def docs_navbar() -> rx.Component: + from pcweb.components.hosting_banner import hosting_banner + + return rx.el.div( + hosting_banner(), + rx.el.header( + rx.el.div( + logo(), + navigation_menu(), + class_name="relative flex w-full items-center h-full justify-between gap-6 mx-auto flex-row max-w-[108rem]", + ), + class_name="w-full max-full h-[4.5rem] mx-auto flex flex-row items-center lg:px-16 px-6 backdrop-blur-[16px] shadow-[0_-2px_2px_1px_rgba(0,0,0,0.02),0_1px_1px_0_rgba(0,0,0,0.08),0_4px_8px_0_rgba(0,0,0,0.03),0_0_0_1px_#FFF_inset] dark:shadow-none dark:border-b dark:border-m-slate-10 bg-gradient-to-b from-[light-dark(#FFF,var(--m-slate-11))] to-[light-dark(var(--m-slate-1),var(--m-slate-12))]", + ), + class_name="flex flex-col w-full top-0 z-[9999] fixed self-center", + ) diff --git a/pcweb/views/marketing_navbar.py b/pcweb/views/marketing_navbar.py new file mode 100644 index 0000000000..017784f63f --- /dev/null +++ b/pcweb/views/marketing_navbar.py @@ -0,0 +1,558 @@ +import reflex as rx +import reflex_ui as ui +from reflex_ui.blocks.demo_form import demo_form_dialog + +from pcweb.components.docpage.navbar.buttons.sidebar import navbar_sidebar_button +from pcweb.components.icons.icons import get_icon +from pcweb.components.marketing_button import button +from pcweb.components.marquee import marquee +from pcweb.constants import ( + CHANGELOG_URL, + CONTRIBUTING_URL, + DISCUSSIONS_URL, + GITHUB_STARS, + GITHUB_URL, + JOBS_BOARD_URL, + REFLEX_BUILD_URL, +) +from pcweb.pages.blog import blogs +from pcweb.pages.blog.paths import blog_data +from pcweb.pages.customers.landing import customers +from pcweb.pages.docs import ai_builder +from pcweb.pages.faq import faq +from pcweb.pages.framework.framework import framework +from pcweb.pages.gallery.gallery import gallery +from pcweb.pages.hosting.hosting import hosting_landing +from pcweb.pages.use_cases.consulting import consulting_use_case_page +from pcweb.pages.use_cases.finance import finance_use_case_page +from pcweb.pages.use_cases.government import government_use_case_page +from pcweb.pages.use_cases.healthcare import healthcare_use_case_page +from pcweb.pages.use_cases.use_cases import use_cases_page + + +def social_proof_card(image: str) -> rx.Component: + return rx.el.div( + rx.image( + f"/companies/{rx.color_mode_cond('light', 'dark')}/{image}_small.svg", + loading="lazy", + alt=f"{image} logo", + class_name="w-auto h-fit pointer-events-none", + ), + class_name="flex justify-center items-center px-3", + ) + + +def logos_carousel() -> rx.Component: + logos = [ + "agricole", + "man", + "shell", + "red_hat", + "accenture", + "dell", + "microsoft", + "world", + "ford", + "unicef", + "nike", + ] + return marquee( + *[social_proof_card(logo) for logo in logos], + direction="left", + gradient_color="light-dark(var(--c-white-1), var(--c-m-slate-11))", + class_name="h-[1.625rem] w-full overflow-hidden mt-auto", + gradient_width=65, + speed=25, + pause_on_hover=False, + ) + + +def github() -> rx.Component: + return rx.el.a( + button( + get_icon(icon="github_navbar", class_name="shrink-0"), + f"{GITHUB_STARS // 1000}K", + custom_attrs={ + "aria-label": f"View Reflex on GitHub - {GITHUB_STARS // 1000}K stars" + }, + size="sm", + variant="ghost", + ), + to=GITHUB_URL, + custom_attrs={ + "aria-label": f"View Reflex on GitHub - {GITHUB_STARS // 1000}K stars" + }, + ) + + +def logo() -> rx.Component: + return rx.el.a( + rx.image( + src="/logos/light/reflex.svg", + alt="Reflex Logo", + class_name="shrink-0 block dark:hidden", + ), + rx.image( + src="/logos/dark/reflex.svg", + alt="Reflex Logo", + class_name="shrink-0 hidden dark:block", + ), + to="/", + class_name="block shrink-0 mr-9", + ) + + +def menu_trigger(title: str, content: rx.Component) -> rx.Component: + return ui.navigation_menu.item( + ui.navigation_menu.trigger( + button( + title, + ui.icon( + "ArrowDown01Icon", class_name="chevron transition-all ease-out" + ), + size="sm", + variant="ghost", + class_name="font-[550] menu-button", + native_button=False, + ), + style={ + "&[data-popup-open] .chevron": { + "transform": "rotate(180deg)", + }, + "&[data-popup-open] .menu-button": { + "color": "light-dark(var(--primary-10), var(--primary-9))", + }, + }, + class_name="px-1", + aria_label=f"{title} menu", + unstyled=True, + ), + content, + value=title, + class_name="cursor-pointer xl:flex hidden h-full items-center justify-center", + unstyled=True, + custom_attrs={"role": "menuitem"}, + ) + + +def menu_content(content: rx.Component, class_name: str = "") -> rx.Component: + return ui.navigation_menu.content( + content, + unstyled=True, + class_name=ui.cn( + "data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:duration-300 data-[ending-style]:data-[activation-direction=left]:translate-x-[50%] data-[ending-style]:data-[activation-direction=right]:translate-x-[-50%] data-[starting-style]:data-[activation-direction=left]:translate-x-[-50%] data-[starting-style]:data-[activation-direction=right]:translate-x-[50%] w-max transition-[opacity,transform,translate] duration-[0.35s] data-[ending-style]:opacity-0 data-[starting-style]:opacity-0 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none", + "flex flex-row rounded-xl font-sans p-0", + class_name, + ), + keep_mounted=True, + ) + + +def platform_item(image: str, title: str, description: str, href: str) -> rx.Component: + return rx.el.div( + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/{image}", + alt=title, + class_name="size-18", + ), + rx.el.div( + rx.el.span( + title, + class_name="dark:text-m-slate-3 text-m-slate-12 text-sm font-[525]", + ), + rx.el.span( + description, + class_name="dark:text-m-slate-6 text-m-slate-7 text-sm font-[475]", + ), + class_name="flex flex-col", + ), + rx.el.a(class_name="absolute inset-0", to=href), + class_name="p-4 flex flex-row gap-6 relative cursor-pointer rounded-sm hover-card-shadow", + ) + + +def platform_content() -> rx.Component: + return menu_content( + rx.el.div( + rx.el.div( + rx.el.div( + rx.el.div( + rx.el.span( + "AI Builder", + class_name="dark:text-m-slate-3 text-m-slate-12 text-lg font-semibold mb-2", + ), + rx.el.span( + "Build production-ready web apps for your team in seconds with AI-powered code generation.", + class_name="dark:text-m-slate-6 text-m-slate-7 text-sm font-medium", + ), + class_name="p-4 flex flex-col relative hover-card-shadow rounded-md", + ), + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/ai_builder_pattern.svg", + alt="AI Builder Navbar Pattern", + class_name="pointer-events-none", + ), + rx.el.a( + class_name="absolute inset-0", + to=REFLEX_BUILD_URL, + target="_blank", + ), + class_name="relative flex flex-col hover-card-shadow rounded-md", + ), + class_name="p-4 flex flex-col rounded-xl bg-white-1 dark:bg-m-slate-11 h-full shadow-card dark:shadow-card-dark dark:border-r dark:border-m-slate-9", + ), + rx.el.div( + platform_item( + "framework_pixel.svg", + "Reflex Framework", + "Iterate on full-stack apps in pure Python. No JavaScript required.", + framework.path, + ), + platform_item( + "cloud_pixel.svg", + "Cloud Hosting", + "Deploy your app with a single command to Reflex Cloud.", + hosting_landing.path, + ), + rx.el.div( + rx.el.span( + "Reflex Is The Operating System ", + rx.el.br(), + " for Enterprise Apps", + class_name="dark:text-m-slate-6 text-m-slate-7 font-mono font-[415] text-[0.75rem] leading-4.5 uppercase", + ), + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_navbar.svg", + alt="Squares Navbar", + class_name="absolute bottom-4 right-4 pointer-events-none", + ), + class_name="relative p-4", + ), + class_name="p-4 flex flex-col h-full", + ), + class_name="w-[46.5rem] grid grid-cols-2", + ), + ) + + +def solutions_item(title: str, icon: str, href: str) -> rx.Component: + return rx.el.a( + ui.icon( + icon, + class_name="shrink-0 text-m-slate-7 dark:text-m-slate-6 size-4.5", + ), + title, + to=href, + class_name="flex flex-row px-4 py-2 rounded-sm text-sm font-[525] text-m-slate-12 dark:text-m-slate-3 gap-3 items-center justify-start cursor-pointer hover-card-shadow", + ) + + +def solutions_column(title: str, items: list[tuple[str, str, str]]) -> rx.Component: + return rx.el.div( + rx.el.div( + rx.el.span( + title, + class_name="font-mono font-[415] text-[0.75rem] leading-4 uppercase pb-4 border-b border-dashed dark:border-m-slate-8 border-m-slate-6 dark:text-m-slate-6 text-m-slate-7", + ), + class_name="px-4 pt-4 flex flex-col", + ), + rx.el.div( + *[solutions_item(item[0], item[1], item[2]) for item in items], + class_name="flex flex-col", + ), + class_name="flex flex-col gap-4", + ) + + +def blog_item(blog: dict, path: str) -> rx.Component: + return rx.el.div( + rx.el.div( + rx.moment( + rx.Var.create(blog.metadata["date"]).to(str), + format="MMM DD YYYY", + class_name="text-m-slate-7 dark:text-m-slate-6 text-xs font-[415] font-mono uppercase", + ), + rx.image( + src=f"/common/{rx.color_mode_cond('light', 'dark')}/squares_blog.svg", + class_name="pointer-events-none", + alt="Squares Blog", + ), + class_name="flex flex-row items-center justify-start gap-6", + ), + rx.el.span( + blog.metadata["title"], + class_name="dark:text-m-slate-3 text-m-slate-12 text-sm font-[525] group-hover:text-primary-10 dark:group-hover:text-primary-9 line-clamp-3", + ), + rx.el.a( + to=f"/blog/{path}", + class_name="absolute inset-0", + ), + class_name="relative group flex flex-col gap-2 mb-2", + ) + + +def blog_column() -> rx.Component: + first_blog = next(iter(blog_data.values())) + return rx.el.div( + blog_item(first_blog, next(iter(blog_data.keys()))), + blog_item(list(blog_data.values())[1], list(blog_data.keys())[1]), + rx.el.a( + "Read All in Blog", + ui.icon("ArrowRight01Icon", class_name="ml-auto"), + to=blogs.path, + class_name="dark:text-m-slate-3 text-m-slate-12 text-sm font-[525] h-10 flex items-center justify-start gap-2 hover:text-primary-10 dark:hover:text-primary-9 mt-auto", + ), + class_name="flex flex-col gap-6 p-4 h-full", + ) + + +def customers_column() -> rx.Component: + return rx.el.div( + rx.el.div( + rx.el.div( + rx.el.span( + "Customers", + class_name="font-mono font-[415] text-[0.75rem] leading-4 uppercase pb-4 border-b border-dashed dark:border-m-slate-8 border-m-slate-6 dark:text-m-slate-6 text-m-slate-7", + ), + class_name="px-4 pt-4 flex flex-col", + ), + rx.el.div( + rx.el.span( + "Read Stories How Teams Use Reflex", + class_name="text-m-slate-12 dark:text-m-slate-3 text-lg font-[575]", + ), + rx.el.span( + "Discover how companies build internal tools, AI apps, and production dashboards in pure Python.", + class_name="text-m-slate-7 dark:text-m-slate-6 text-sm font-[475]", + ), + logos_carousel(), + class_name="flex flex-col gap-2 px-4 pb-4 h-full", + ), + rx.el.a(class_name="absolute inset-0", to=customers.path), + class_name="flex flex-col gap-6 hover-card-shadow rounded-lg relative h-full hover:[--m-slate-11:var(--m-slate-10)] hover:shadow-card dark:hover:shadow-card-dark", + ), + class_name="p-4 block rounded-lg shadow-card dark:shadow-card-dark z-[1] bg-white-1 dark:bg-m-slate-11 dark:border-x dark:border-m-slate-9", + ) + + +def solutions_content() -> rx.Component: + return menu_content( + rx.el.div( + rx.el.div( + rx.el.div( + solutions_column( + "Who's It For", + [ + ("Executives", "LocationUser01Icon", use_cases_page.path), + ("Developers", "SourceCodeSquareIcon", use_cases_page.path), + ("Data Teams", "DatabaseIcon", use_cases_page.path), + ( + "Non Technical", + "CursorCircleSelection02Icon", + use_cases_page.path, + ), + ], + ), + solutions_column( + "Industries", + [ + ("Enterprise", "OfficeIcon", use_cases_page.path), + ("Finance", "Wallet05Icon", finance_use_case_page.path), + ("Healthcare", "HealthIcon", healthcare_use_case_page.path), + ( + "Consulting", + "DocumentValidationIcon", + consulting_use_case_page.path, + ), + ( + "Government", + "BankIcon", + government_use_case_page.path, + ), + ], + ), + class_name="grid grid-cols-2", + ), + class_name="p-4 flex flex-col rounded-xl bg-white-1 dark:bg-m-slate-11 h-full w-[28rem] shadow-card dark:shadow-card-dark dark:border-r dark:border-m-slate-9", + ), + rx.el.div( + solutions_column( + "Migration", + [ + ("Switch from No Code", "WebDesign01Icon", use_cases_page.path), + ( + "Switch from Other Frameworks", + "CodeIcon", + use_cases_page.path, + ), + ( + "Switch from Other AI tools", + "ArtificialIntelligence04Icon", + use_cases_page.path, + ), + ], + ), + class_name="p-4 flex flex-col h-full", + ), + class_name="flex flex-row", + ), + ) + + +def resources_content() -> rx.Component: + return menu_content( + rx.el.div( + rx.el.div( + solutions_column( + "Developers", + [ + ("Templates", "Layout02Icon", gallery.path), + ( + "Integrations", + "PlugSocketIcon", + ai_builder.integrations.overview.path, + ), + ("Changelog", "Clock02Icon", CHANGELOG_URL), + ("Contributing", "GitCommitIcon", CONTRIBUTING_URL), + ("Discussion", "BubbleChatIcon", DISCUSSIONS_URL), + ("FAQ", "HelpSquareIcon", faq.path), + ], + ), + class_name="p-4 flex flex-col rounded-xl bg-m-slate-1 dark:bg-m-slate-12 h-full", + ), + customers_column(), + rx.el.div( + blog_column(), + class_name="p-4 flex flex-col h-full bg-m-slate-1 dark:bg-m-slate-12", + ), + class_name="w-[52.5rem] grid grid-cols-3", + ), + ) + + +def about_content() -> rx.Component: + return menu_content( + rx.el.div( + rx.el.div( + solutions_item("Company", "Profile02Icon", "/about"), + solutions_item("Careers", "WorkIcon", JOBS_BOARD_URL), + class_name="p-4 flex flex-col rounded-xl bg-white-1 h-full dark:shadow-none dark:border dark:border-m-slate-9 dark:bg-m-slate-11 shadow-card", + ), + class_name="w-[12.5rem]", + ), + ) + + +def navigation_menu() -> rx.Component: + return ui.navigation_menu.root( + ui.navigation_menu.list( + menu_trigger("Platform", platform_content()), + menu_trigger("Solutions", solutions_content()), + menu_trigger("Resources", resources_content()), + ui.navigation_menu.item( + rx.el.a( + button( + "Pricing", + size="sm", + variant="ghost", + native_button=False, + ), + to="/pricing", + ), + class_name="xl:flex hidden px-1", + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + rx.el.a( + button( + "Docs", + size="sm", + variant="ghost", + ), + to="/docs", + ), + class_name="xl:flex hidden px-1", + custom_attrs={"role": "menuitem"}, + ), + menu_trigger("About", about_content()), + class_name="flex flex-row items-center m-0 h-full list-none", + custom_attrs={"role": "menubar"}, + ), + ui.navigation_menu.list( + ui.navigation_menu.item( + github(), + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + rx.el.a( + button( + "Sign In", + ui.icon("Login01Icon", class_name="scale-x-[-1]"), + size="sm", + variant="outline", + native_button=False, + ), + to=f"{REFLEX_BUILD_URL.strip('/')}/cloud-login?redirect_to={REFLEX_BUILD_URL.strip('/')}/callback/", + target="_blank", + ), + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + demo_form_dialog( + trigger=button( + "Book a Demo", + size="sm", + variant="primary", + class_name=" whitespace-nowrap max-xl:hidden", + native_button=False, + ), + ), + unstyled=True, + class_name="xl:flex hidden", + custom_attrs={"role": "menuitem"}, + ), + ui.navigation_menu.item( + navbar_sidebar_button(), + class_name="xl:hidden flex", + unstyled=True, + custom_attrs={"role": "menuitem"}, + ), + class_name="flex flex-row lg:gap-4 gap-2 m-0 h-full list-none items-center", + custom_attrs={"role": "menubar"}, + ), + ui.navigation_menu.portal( + ui.navigation_menu.positioner( + ui.navigation_menu.popup( + ui.navigation_menu.viewport( + unstyled=True, + class_name="relative h-full w-full overflow-hidden rounded-[inherit]", + ), + unstyled=True, + class_name="relative h-[var(--popup-height)] w-[var(--popup-width)] origin-[var(--transform-origin)] rounded-xl bg-m-slate-1 dark:bg-m-slate-12 navbar-shadow transition-[opacity,transform,width,height,scale,translate] duration-150 ease-[cubic-bezier(0.22,1,0.36,1)] data-[ending-style]:ease-[ease] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:scale-90 data-[starting-style]:opacity-0", + ), + unstyled=True, + class_name="safari-nav-positioner box-border h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-[instant]:transition-none", + side_offset=30, + align="start", + align_offset=-20, + position_method="fixed", + ), + ), + unstyled=True, + class_name="group/navigation-menu relative flex w-full items-center h-full justify-between gap-6 mx-auto flex-row", + ) + + +@rx.memo +def marketing_navbar() -> rx.Component: + from pcweb.components.hosting_banner import hosting_banner + + return rx.el.div( + hosting_banner(), + rx.el.header( + logo(), + navigation_menu(), + class_name="w-full max-w-[71.5rem] h-[4.5rem] mx-auto flex flex-row items-center p-5 rounded-b-xl backdrop-blur-[16px] shadow-[0_-2px_2px_1px_rgba(0,0,0,0.02),0_1px_1px_0_rgba(0,0,0,0.08),0_4px_8px_0_rgba(0,0,0,0.03),0_0_0_1px_#FFF_inset] dark:shadow-none dark:border-x dark:border-b dark:border-m-slate-10 bg-gradient-to-b from-white to-m-slate-1 dark:from-m-slate-11 dark:to-m-slate-12", + ), + class_name="flex flex-col w-full top-0 z-[9999] fixed self-center", + ) diff --git a/uv.lock b/uv.lock index 7702e8417d..08c2d6afe6 100644 --- a/uv.lock +++ b/uv.lock @@ -2548,7 +2548,7 @@ wheels = [ [[package]] name = "reflex-ui" version = "0.0.1" -source = { git = "https://github.com/reflex-dev/reflex-ui?rev=main#9acee2e65cbdf6f6cff4ef6ddf125464e3c79b3a" } +source = { git = "https://github.com/reflex-dev/reflex-ui?rev=main#f537d6a67c32f53f4107c8809a09838be86ada28" } dependencies = [ { name = "reflex" }, ]