复制 curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
-tar zxf swiftly-$(uname -m).tar.gz && \
+ Copy curl -O "https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz" && \
+tar zxf "swiftly-$(uname -m).tar.gz" && \
./swiftly init --quiet-shell-followup && \
-. ~/.local/share/swiftly/env.sh && \
+. ${SWIFTLY_HOME_DIR:-~/.local/share/swiftly}/env.sh && \
hash -r
diff --git a/_includes/install/_older-releases.md b/_includes/install/_older-releases.md
index 185dd02aa..d03f9d131 100644
--- a/_includes/install/_older-releases.md
+++ b/_includes/install/_older-releases.md
@@ -1,4 +1,4 @@
-
+
版本
@@ -18,7 +18,8 @@
{% endunless %}
{% endfor %}
-
+
+
{% if include.platform == "Windows 10" %}
1 Swift {{ include.release.name }} {{ windows_platform.first.name }} 工具链由 Saleem Abdulrasool 提供。Saleem 是 Swift Windows 移植版本的平台负责人,这是 Swift 项目的官方构建版本。
diff --git a/_includes/navigation.html b/_includes/navigation.html
deleted file mode 100644
index 1a40cc44e..000000000
--- a/_includes/navigation.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- {% for nav in site.data.navigation %}
-
- {% if nav.isCta and nav.url %}
- {{ nav.header }}
- {% else %}
-
- {% if nav.url %}
- {{ nav.header }}
- {% else %}
- {{ nav.header }}
- {% endif %}
- {% if nav.pages %}
- ▿
- {% endif %}
-
- {% endif %}
- {% if nav.pages %}
-
- {% endif %}
-
- {% endfor %}
-
-
-
-
-
-
-
- {% for nav in site.data.navigation %}
-
-
- {% if nav.url %}
-
{{ nav.header }}
- {% else %}
- {{ nav.header }}
- {% endif %}
-
- {% if nav.pages %}
-
- ▿
-
- {% endif %}
-
- {% if nav.pages %}
-
- {% endif %}
-
- {% endfor %}
-
-
-
diff --git a/_includes/new-includes/assigns/linux-platform-builds.html b/_includes/new-includes/assigns/linux-platform-builds.html
new file mode 100644
index 000000000..2b7175bb9
--- /dev/null
+++ b/_includes/new-includes/assigns/linux-platform-builds.html
@@ -0,0 +1,21 @@
+{% assign platform=include.platform %}
+{% assign aarch64=include.aarch64 %}
+{% assign branch_dir=include.branch_dir %}
+{% assign development=include.development %}
+{% assign docker_tag=include.docker_tag %}
+{% assign development_builds=include.development_builds %}
+{% assign aarch64_development_builds=include.aarch64_development_builds %}
+{% assign development_2=include.development_2 %}
+{% assign docker_tag_2=include.docker_tag_2 %}
+{% assign development_builds_2=include.development_builds_2 %}
+{% assign aarch64_development_builds_2=include.aarch64_development_builds_2 %}
+{% assign branch_dir_2=include.branch_dir_2 %}
+
+{% assign platform_name_url = platform | remove: '.' | remove: ' ' | downcase %}
+{% assign development_builds_2 = development_builds_2 | sort: 'date' | reverse %}
+{% assign development_builds = development_builds | sort: 'date' | reverse %}
+
+{% if aarch64 %}
+{% assign aarch64_development_builds_2 = aarch64_development_builds_2 | sort: 'date' | reverse %}
+{% assign aarch64_development_builds = aarch64_development_builds | sort: 'date' | reverse %}
+{% endif %}
\ No newline at end of file
diff --git a/_includes/new-includes/components/callout.html b/_includes/new-includes/components/callout.html
new file mode 100644
index 000000000..e055e754e
--- /dev/null
+++ b/_includes/new-includes/components/callout.html
@@ -0,0 +1,29 @@
+{% assign is_even = include.index | modulo: 2 %} {% assign with_code =
+include.code %}
+
+
+ {% if include.title %}
+
{{ include.title }}
+ {% endif %} {% if include.subtitle %}
+
{{ include.subtitle }}
+ {% endif %} {% if include.text %}
+
{{ include.text }}
+ {% endif %}
+
+ {% if include.code %}
+
+
+~~~swift
+{{include.code}}
+~~~
+
+ {% endif %} {% assign links = include.links %} {% if links %}
+
+ {% endif %}
+
diff --git a/_includes/new-includes/components/card-grid.html b/_includes/new-includes/components/card-grid.html
new file mode 100644
index 000000000..bdf69773f
--- /dev/null
+++ b/_includes/new-includes/components/card-grid.html
@@ -0,0 +1,57 @@
+
+
+
{{ include.content.title }}
+ {% if include.content.hero_card %} {% include
+ new-includes/components/hero-card.html image = include.content.hero_card %}
+ {% endif %} {% if include.content.primary_cards %}
+
+ {% for card in include.content.primary_cards %}
+
+
+
+
+ {% endfor %}
+
+ {% endif %} {% if include.content.secondary_cards %}
+
+ {% for card in include.content.secondary_cards %}
+
+
+
+
+ {% endfor %}
+
+ {% endif %} {% if include.content.tertiary_cards %}
+
+ {% for card in include.content.tertiary_cards %}
+
+ {% if card.image %}
+
+ {% endif %}
+
+
+ {% endfor %}
+
+ {% endif %}
+ {% if include.content.text %}
+
{{ include.content.text }}
+ {% endif %}
+ {% if include.content.link %}
+
{{ include.content.link.text }}
+
+ {% endif %}
+
+
diff --git a/_includes/new-includes/components/carousel.html b/_includes/new-includes/components/carousel.html
new file mode 100644
index 000000000..162d4426b
--- /dev/null
+++ b/_includes/new-includes/components/carousel.html
@@ -0,0 +1,20 @@
+
+
+
+ {% for package in include.packages %}
+
+
+
{{ package.title }}
+
{{ package.description }}
+
Learn more ←
+
+ {% endfor %}
+
+
+
+ ←
+ →
+
+
+
+
diff --git a/_includes/new-includes/components/code-box.html b/_includes/new-includes/components/code-box.html
new file mode 100644
index 000000000..3d49a603d
--- /dev/null
+++ b/_includes/new-includes/components/code-box.html
@@ -0,0 +1,44 @@
+
+
{{include.content.headline}}
+ {% if include.content.pre-code-text %}
+
{{include.content.pre-code-text}}
+ {% endif %} {% if include.content.tabs %}
+
+
+ {% for tab in include.content.tabs %}
+
+ {{tab.label}}
+
+ {% endfor %}
+
+
+ {% for tab in include.content.tabs %}
+
{{tab.code | escape}}
+ {% endfor %} {% else %} {% if include.content.code %}
+
{{include.content.code | escape}}
+ {% endif %} {% endif %} {% if include.content.after-code-text %}
+
{{include.content.after-code-text}}
+ {% endif %}{% if include.content.links %}
+
+ {% for link in include.content.links %}
+ {% if link.group %}
+
+ {% for item in link.group %}
+
{{ item.copy }}
+ {% unless forloop.last %}|{% endunless %}
+ {% endfor %}
+
+ {% else %}
+
+ {% endif %}
+ {% endfor %}
+
+{% endif %}
+
diff --git a/_includes/new-includes/components/code-image-column.html b/_includes/new-includes/components/code-image-column.html
new file mode 100644
index 000000000..b3eef77dc
--- /dev/null
+++ b/_includes/new-includes/components/code-image-column.html
@@ -0,0 +1,26 @@
+
+
+ {% if include.content.headline %}
+
{{ include.content.headline }}
+ {% endif %} {% if include.content.body %}
+
{{ include.content.body }}
+ {% endif %} {% if include.content.link %}
+
{{ include.content.link.text }}
+
+ {% endif %}
+
+
+
+
+~~~swift
+{{ include.content.code }}
+~~~
+
+
+
+
+
diff --git a/_includes/new-includes/components/code-text-row.html b/_includes/new-includes/components/code-text-row.html
new file mode 100644
index 000000000..0de3c1139
--- /dev/null
+++ b/_includes/new-includes/components/code-text-row.html
@@ -0,0 +1,20 @@
+
+
{{ include.content.headline }}
+
+
+
+~~~swift
+{{ include.content.code }}
+~~~
+
+
+
+
diff --git a/_includes/new-includes/components/full-width-text-code-column.html b/_includes/new-includes/components/full-width-text-code-column.html
new file mode 100644
index 000000000..afb8ec75f
--- /dev/null
+++ b/_includes/new-includes/components/full-width-text-code-column.html
@@ -0,0 +1,20 @@
+
+
+
{{ include.content.headline }}
+ {% for paragraph in include.content.paragraphs %}
+
{{paragraph}}
+ {% endfor %} {% if include.content.link %}
+
{{ include.content.link.text }}
+
+ {% endif %}
+
+
+
+~~~swift
+{{ include.content.code }}
+~~~
+
+
diff --git a/_includes/new-includes/components/full-width-text-image-column.html b/_includes/new-includes/components/full-width-text-image-column.html
new file mode 100644
index 000000000..b4cb7e3dd
--- /dev/null
+++ b/_includes/new-includes/components/full-width-text-image-column.html
@@ -0,0 +1,16 @@
+
+
+
{{ include.content.headline }}
+ {% for paragraph in include.content.paragraphs %}
+
{{paragraph}}
+ {% endfor %}
+
{{ include.content.link.text }}
+
+
+
+
+
diff --git a/_includes/new-includes/components/get-started-hero.html b/_includes/new-includes/components/get-started-hero.html
new file mode 100644
index 000000000..7d6c635db
--- /dev/null
+++ b/_includes/new-includes/components/get-started-hero.html
@@ -0,0 +1,21 @@
+
+
+
{{include.content.headline}}
+
{{include.content.body}}
+
+ {% for box in include.content.boxes %}
+
+ {{ box.title }}
+ {{ box.text }}
+
+ {% endfor %}
+
+
{{include.content.link.text}}
+
+
+
+
diff --git a/_includes/new-includes/components/headline-section.html b/_includes/new-includes/components/headline-section.html
new file mode 100644
index 000000000..5dcf82881
--- /dev/null
+++ b/_includes/new-includes/components/headline-section.html
@@ -0,0 +1,11 @@
+
diff --git a/_includes/new-includes/components/hero-card.html b/_includes/new-includes/components/hero-card.html
new file mode 100644
index 000000000..77b947fcb
--- /dev/null
+++ b/_includes/new-includes/components/hero-card.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/_includes/new-includes/components/icon.html b/_includes/new-includes/components/icon.html
new file mode 100644
index 000000000..38b444205
--- /dev/null
+++ b/_includes/new-includes/components/icon.html
@@ -0,0 +1,8 @@
+{% assign icon = include.name | append: "." | append: include.type %} {% capture
+path %}assets/images/{{ icon }}{% endcapture %}
+
+ {% include_relative {{ path }} %}
+
diff --git a/_includes/new-includes/components/image-text-row.html b/_includes/new-includes/components/image-text-row.html
new file mode 100644
index 000000000..7af3f2b22
--- /dev/null
+++ b/_includes/new-includes/components/image-text-row.html
@@ -0,0 +1,22 @@
+
+ {% if include.content.headline %}
+
{{ include.content.headline }}
+ {% endif %}
+
+
+
+
+
diff --git a/_includes/new-includes/components/link-columns.html b/_includes/new-includes/components/link-columns.html
new file mode 100644
index 000000000..77cd1c5ae
--- /dev/null
+++ b/_includes/new-includes/components/link-columns.html
@@ -0,0 +1,17 @@
+
+
{{include.content.headline}}
+
+ {% for column in include.content.columns %}
+
+
{{column.headline}}
+
+ {% for link in column.links %}
+
+ {{link.text}}
+
+ {% endfor %}
+
+
+ {% endfor %}
+
+
diff --git a/_includes/new-includes/components/linux-os-selection.html b/_includes/new-includes/components/linux-os-selection.html
new file mode 100644
index 000000000..e19c24240
--- /dev/null
+++ b/_includes/new-includes/components/linux-os-selection.html
@@ -0,0 +1,15 @@
+
+
Alternate Install Options
+
+ {% assign platforms = site.data.new-data.install.linux.os-names %} {% assign
+ url_parts = page.url | split: '/' %} {% assign selected_os = url_parts[3] %}
+ Select Linux platform:
+ {% include new-includes/components/tab-nav.html tabs=platforms class="os"
+ selected=selected_os %} {% assign selected_platform = platforms | where:
+ "slug", selected_os | first %} {% assign selected_version = url_parts[3] |
+ append: url_parts[4] %} {% if selected_platform.versions %}
+ Select {{ selected_platform.name }} version:
+ {% include new-includes/components/tab-nav.html
+ tabs=selected_platform.versions class="version" selected=selected_version %}
+ {% endif %}
+
diff --git a/_includes/new-includes/components/linux-releases.html b/_includes/new-includes/components/linux-releases.html
new file mode 100644
index 000000000..157be40b9
--- /dev/null
+++ b/_includes/new-includes/components/linux-releases.html
@@ -0,0 +1,171 @@
+{% assign tag = site.data.builds.swift_releases.last.tag %}
+{% assign tag_downcase = site.data.builds.swift_releases.last.tag | downcase %}
+{% assign platform_name_url = include.platform | remove: '.' | remove: ' ' | downcase %}
+{% assign platform_name = include.platform | remove : ' ' | downcase %}
+{% assign platform = site.data.builds.swift_releases.last.platforms | where: 'dir', include.platform_name_url | first %}
+{% unless platform %}
+ {% assign platform = site.data.builds.swift_releases.last.platforms | where: 'name', include.platform | first %}
+{% endunless %}
+
+
+
+
+
+
+
Container
+
+ Official container images are available for compiling and running Swift on a variety of distributions.
+
+
+
+
+
+
+
+
+
+
Tarball
+
+ Tarball packages (.tar.gz)
+
+
+ {%- for arch in platform.archs -%}
+
+ {%- endfor -%}
+
+
+
+
+
+
+
+ {% include new-includes/components/static-linux-sdk.html %}
+
+
+ {% if include.rpm %}
+
+
+
+
RPM
+
+ RPM Package Manager (Experimental use only)
+
+
+
+
+
+ {% endif %}
+
+
+
+
+ Previous Releases
+ {% include install/_older-releases.md platform=include.platform %}
+
+
+
+
Development Snapshots
+
+
Swift snapshots are prebuilt binaries that are automatically created from the branch. These snapshots are not official releases. They have gone through automated unit testing, but they have not gone through the full testing that is performed for official releases.
+
+
+
+
+
+
+
+
{{ include.development }}
+
+ {{ development_builds.first.date | date: '%B %-d, %Y' }}
+
+
+
+
+
+
+
+
+
+
+
{{ include.development_2 }}
+
+ {{ development_builds_2.first.date | date: '%B %-d, %Y' }}
+
+
+
+
+
+
+
+
+
+
+
+ Previous Snapshots (main)
+ {% include install/_older_snapshots.md builds=development_builds name=platform platform_dir=platform_name_url branch_dir=branch_dir %}
+
+
+
+
+
+
+ Previous Snapshots (release/6.2)
+ {% include install/_older_snapshots.md builds=development_builds_2 name=platform platform_dir=platform_name_url branch_dir=branch_dir_2 %}
+
+
+
+
Static Linux SDK
+
+ {% include new-includes/components/static-linux-sdk-dev.html %}
+
\ No newline at end of file
diff --git a/_includes/new-includes/components/os-selection.html b/_includes/new-includes/components/os-selection.html
new file mode 100644
index 000000000..568e82bc3
--- /dev/null
+++ b/_includes/new-includes/components/os-selection.html
@@ -0,0 +1,7 @@
+{% assign path_parts = page.url | split: '/' %} {% assign selected =
+path_parts[2] | default: 'macos' %}
+
+
Install Swift
+ {% assign tabs = site.data.new-data.os-versions %} {% include
+ new-includes/components/tab-nav.html tabs=tabs class="os" selected=selected %}
+
diff --git a/_includes/new-includes/components/overlapping-containers.html b/_includes/new-includes/components/overlapping-containers.html
new file mode 100644
index 000000000..30b396d5a
--- /dev/null
+++ b/_includes/new-includes/components/overlapping-containers.html
@@ -0,0 +1,4 @@
+
+
{{ include.left }}
+
{{ include.right }}
+
diff --git a/_includes/new-includes/components/static-linux-sdk-dev.html b/_includes/new-includes/components/static-linux-sdk-dev.html
new file mode 100644
index 000000000..0989d6071
--- /dev/null
+++ b/_includes/new-includes/components/static-linux-sdk-dev.html
@@ -0,0 +1,51 @@
+{% assign static_sdk_dev_builds = site.data.builds.development.static_sdk | sort: 'date' | reverse %}
+{% assign static_sdk_6_1_builds = site.data.builds.swift-6_1-branch.static_sdk | sort: 'date' | reverse %}
+
+
+
+
+
+
main
+
+ {{ static_sdk_dev_builds.first.date | date: '%B %-d, %Y' }}
+ Static Linux SDK - Cross compile to Linux.
+
+ {% assign base_url = "https://download.swift.org/development/static-sdk/" | append: static_sdk_dev_builds.first.dir | append: "/" | append: static_sdk_dev_builds.first.download %}
+ {% assign command = "swift sdk install " | append: base_url | append: " --checksum " | append: static_sdk_dev_builds.first.checksum %}
+
+ Copy install command
+
+
+
+
+
+
+
+
+
+
release/6.1
+
+ {{ static_sdk_6_1_builds.first.date | date: '%B %-d, %Y' }}
+ Static Linux SDK - Cross compile to Linux.
+
+ {% assign base_url = "https://download.swift.org/development/static-sdk/" | append: static_sdk_6_1_builds.first.dir | append: "/" | append: static_sdk_6_1_builds.first.download %}
+ {% assign command = "swift sdk install " | append: base_url | append: " --checksum " | append: static_sdk_6_1_builds.first.checksum %}
+
+ Copy install command
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/components/static-linux-sdk.html b/_includes/new-includes/components/static-linux-sdk.html
new file mode 100644
index 000000000..0288e018d
--- /dev/null
+++ b/_includes/new-includes/components/static-linux-sdk.html
@@ -0,0 +1,25 @@
+{% assign platform = site.data.builds.swift_releases.last.platforms | where: 'name', 'Static SDK'| first %}
+{% assign tag = site.data.builds.swift_releases.last.tag %}
+{% assign tag_downcase = site.data.builds.swift_releases.last.tag | downcase %}
+
+
+
Static Linux SDK
+
+ Static Linux SDK - Cross compile to Linux.
+
+ {% assign base_url = "https://download.swift.org/" | append: tag_downcase | append: "/static-sdk/" | append: tag | append: "/" | append: tag %}
+ {% assign command = "swift sdk install " | append: base_url | append: "_static-linux-0.0.1.artifactbundle.tar.gz --checksum " | append: platform.checksum %}
+
+ Copy install command
+
+
+
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/components/tab-nav.html b/_includes/new-includes/components/tab-nav.html
new file mode 100644
index 000000000..19a0aefa9
--- /dev/null
+++ b/_includes/new-includes/components/tab-nav.html
@@ -0,0 +1,16 @@
+
+
+ {% for tab in include.tabs %} {% assign tab_name = tab.slug | downcase %} {%
+ if tab_name == include.selected %} {% assign is_selected = true %} {% else
+ %} {% assign is_selected = false %} {% endif %}
+
+ {{ tab.name }}
+
+ {% endfor %}
+
+
diff --git a/_includes/new-includes/footer/copyright.html b/_includes/new-includes/footer/copyright.html
new file mode 100644
index 000000000..1bc2bacae
--- /dev/null
+++ b/_includes/new-includes/footer/copyright.html
@@ -0,0 +1,9 @@
+
+ {{ include.licenseinfo }}
+
+ 版权所有 © 2025 SwiftGG 翻译组 | 翻译自 swift.org
+
+
+ Swift 和 Swift 标识是 Apple Inc. 的注册商标。
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/footer.html b/_includes/new-includes/footer/footer.html
new file mode 100644
index 000000000..b97b831b2
--- /dev/null
+++ b/_includes/new-includes/footer/footer.html
@@ -0,0 +1,22 @@
+
diff --git a/_includes/new-includes/footer/navigations/community.html b/_includes/new-includes/footer/navigations/community.html
new file mode 100644
index 000000000..3c2431636
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/community.html
@@ -0,0 +1,10 @@
+
+ 社区
+
+ {% for item in site.data.new-data.footer.community-navigation %}
+
+ {{ item.title }}
+
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/navigations/governance.html b/_includes/new-includes/footer/navigations/governance.html
new file mode 100644
index 000000000..34e6b1fe1
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/governance.html
@@ -0,0 +1,12 @@
+
+ 监管
+
+ {% for item in site.data.new-data.footer.governance-navigation %}
+
+ {{ item.title }}
+
+ {% endfor %}
+
+
+ {% include new-includes/footer/theme-toggle.html %}
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/navigations/legals.html b/_includes/new-includes/footer/navigations/legals.html
new file mode 100644
index 000000000..be488c007
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/legals.html
@@ -0,0 +1,9 @@
+
+
+ {% for item in site.data.new-data.footer.legals-navigation %}
+
+ {{ item.title }}
+
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/navigations/main.html b/_includes/new-includes/footer/navigations/main.html
new file mode 100644
index 000000000..7d904562b
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/main.html
@@ -0,0 +1,11 @@
+
+ {% include new-includes/header/logo.html %}
+
+
+ {% for item in site.data.new-data.footer.main-navigation %}
+
+ {{ item.title }}
+
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/navigations/socials.html b/_includes/new-includes/footer/navigations/socials.html
new file mode 100644
index 000000000..d10570f75
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/socials.html
@@ -0,0 +1,9 @@
+
+
+ {% for item in site.data.new-data.footer.social-navigation %}
+
+
+
+ {% endfor %}
+
+
diff --git a/_includes/new-includes/footer/navigations/tools.html b/_includes/new-includes/footer/navigations/tools.html
new file mode 100644
index 000000000..1d536c447
--- /dev/null
+++ b/_includes/new-includes/footer/navigations/tools.html
@@ -0,0 +1,10 @@
+
+ 工具
+
+ {% for item in site.data.new-data.footer.tools-navigation %}
+
+ {{ item.title }}
+
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/_includes/new-includes/footer/theme-toggle.html b/_includes/new-includes/footer/theme-toggle.html
new file mode 100644
index 000000000..4d57f69fb
--- /dev/null
+++ b/_includes/new-includes/footer/theme-toggle.html
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/_includes/new-includes/header/header.html b/_includes/new-includes/header/header.html
new file mode 100644
index 000000000..b664378b8
--- /dev/null
+++ b/_includes/new-includes/header/header.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ {% include new-includes/header/navigation.html %}
+
+
+
+
+
+
+
+
+ {% include new-includes/header/navigation.html %}
+
+
+
\ No newline at end of file
diff --git a/_includes/logo.html b/_includes/new-includes/header/logo.html
similarity index 97%
rename from _includes/logo.html
rename to _includes/new-includes/header/logo.html
index e0912ed14..2dbb6be5d 100644
--- a/_includes/logo.html
+++ b/_includes/new-includes/header/logo.html
@@ -1,4 +1,5 @@
-
+
+
@@ -14,4 +15,4 @@
-
\ No newline at end of file
+
diff --git a/_includes/new-includes/header/navigation.html b/_includes/new-includes/header/navigation.html
new file mode 100644
index 000000000..1027f7e80
--- /dev/null
+++ b/_includes/new-includes/header/navigation.html
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/_layouts/base.html b/_layouts/base.html
index 07104a867..1f5a9ea4e 100644
--- a/_layouts/base.html
+++ b/_layouts/base.html
@@ -71,7 +71,7 @@
{% endif %}
-{% include navigation.html %}
+{% include new-includes/header/header.html %}
{{content}}
diff --git a/_layouts/default.html b/_layouts/default.html
index 7e2ae0c76..99abc4a55 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -6,4 +6,4 @@
{{ content }}
-{% include footer.html %}
+{% include new-includes/footer/footer.html %}
diff --git a/_layouts/new-layouts/base.html b/_layouts/new-layouts/base.html
new file mode 100644
index 000000000..611d56e85
--- /dev/null
+++ b/_layouts/new-layouts/base.html
@@ -0,0 +1,182 @@
+
+
+
+
+ {{ site.title }} - {{ page.title | escape }}
+ {% if jekyll.environment == 'stage' %}
+
+ {% endif %}
+
+
+ {% if page.excerpt %}
+
+ {% endif %} {% if page.url == "/" %}
+
+
+
+
+
+
+ {% endif %}
+
+
+
+ {% if page.url == "/" %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+ {% if page.atom %}
+
+ {% endif %} {% if page.url %}
+
+ {% endif %}
+
+
+
+ {% if page.id %}
+
+
+ {% else %}
+
+
+ {% endif %}
+
+
+
+ {% if page.robots %}
+
+ {% endif %} {% if page.id %}
+
+
+
+
+
+
+ {% else %}
+
+
+
+ {% endif %}
+
+
+
+
+ {% include new-includes/header/header.html %} {{content}} {% include
+ new-includes/footer/footer.html %}
+
+
+
+ {% if page.url == "/" %}
+
+ {% endif %}
+
+
diff --git a/_layouts/new-layouts/install-linux-version.html b/_layouts/new-layouts/install-linux-version.html
new file mode 100644
index 000000000..0a1206084
--- /dev/null
+++ b/_layouts/new-layouts/install-linux-version.html
@@ -0,0 +1,7 @@
+---
+layout: new-layouts/install
+---
+
+{% include new-includes/components/linux-os-selection.html %}
+
+{{ content }}
diff --git a/_layouts/new-layouts/install-linux.html b/_layouts/new-layouts/install-linux.html
new file mode 100644
index 000000000..db18d1bcd
--- /dev/null
+++ b/_layouts/new-layouts/install-linux.html
@@ -0,0 +1,7 @@
+---
+layout: new-layouts/install
+---
+
+{{ content }}
+
+{% include new-includes/components/linux-os-selection.html %}
diff --git a/_layouts/new-layouts/install.html b/_layouts/new-layouts/install.html
new file mode 100644
index 000000000..6f7510106
--- /dev/null
+++ b/_layouts/new-layouts/install.html
@@ -0,0 +1,25 @@
+---
+layout: new-layouts/base
+---
+
+
+ {% include new-includes/components/os-selection.html %} {{ content }}
+
+
+
+
+
\ No newline at end of file
diff --git a/_layouts/post.html b/_layouts/post.html
index 578108f2d..7cd0765c3 100644
--- a/_layouts/post.html
+++ b/_layouts/post.html
@@ -34,7 +34,7 @@ {{ page.title }}
{% capture licenseinfo %}
- Except where otherwise noted, all content on this blog is licensed under a Creative Commons Attribution 4.0 International license .
+ Except where otherwise noted, all content on this blog is licensed under a Creative Commons Attribution 4.0 International license .
{% endcapture %}
-{% include footer.html licenseinfo=licenseinfo %}
+{% include new-includes/footer/footer.html licenseinfo=licenseinfo %}
diff --git a/_plugins/liquid-in-yaml.rb b/_plugins/liquid-in-yaml.rb
new file mode 100644
index 000000000..39d8e08ec
--- /dev/null
+++ b/_plugins/liquid-in-yaml.rb
@@ -0,0 +1,52 @@
+require 'yaml'
+
+module Jekyll
+ class LiquidInYaml < Generator
+ priority :highest
+
+ def generate(site)
+ context = Liquid::Context.new(site.site_payload)
+
+ site.data.each do |filename, content|
+ site.data[filename] = process_yaml(content, context)
+ end
+ end
+
+ private
+
+ def render_liquid_string(data, context)
+ last = nil
+ current = data
+
+ while current != last && current =~ /{{|{%/
+ last = current
+ current = Liquid::Template.parse(current).render!(context)
+ end
+ current
+ end
+
+ def process_yaml(data, context)
+ case data
+ when Hash
+ data.transform_values { |value| process_yaml(value, context) }
+ when Array
+ data.map { |item| process_yaml(item, context) }
+ when String
+ if data =~ /({{.*}}|{%.+%})/
+ begin
+ render_liquid_string(data, context)
+ rescue => e
+ Jekyll.logger.error "LiquidInYaml Plugin:", "Error rendering: #{data.inspect}"
+ Jekyll.logger.error "", e.message
+ data
+ end
+ else
+ data
+ end
+ else
+ data
+ end
+ end
+
+ end
+end
diff --git a/_posts/2024-03-12-byte-sized-swift-tiny-games-playdate.md b/_posts/2024-03-12-byte-sized-swift-tiny-games-playdate.md
index 9c4c32255..86b6651ac 100644
--- a/_posts/2024-03-12-byte-sized-swift-tiny-games-playdate.md
+++ b/_posts/2024-03-12-byte-sized-swift-tiny-games-playdate.md
@@ -6,7 +6,7 @@ title: "Byte-sized Swift: Building Tiny Games for the Playdate"
author: [rauhul]
---
-I'm excited to share [swift-playdate-examples](https://github.com/apple/swift-playdate-examples), a technical demonstration of using Swift to build games for [Playdate](https://play.date/), a handheld game system by [Panic](https://panic.com).
+I'm excited to share [swift-playdate-examples](https://github.com/swiftlang/swift-playdate-examples), a technical demonstration of using Swift to build games for [Playdate](https://play.date/), a handheld game system by [Panic](https://panic.com).
@@ -96,7 +96,7 @@ Swift Break features a splash screen, a pause menu, paddle-location-based bounce
## Try it Out
-If you're eager to use Swift on your Playdate, the [swift-playdate-examples](https://github.com/apple/swift-playdate-examples) repository has you covered. It contains the above ready-to-use examples that demonstrate how to build Swift games for the Playdate, both for the simulator and the hardware.
+If you're eager to use Swift on your Playdate, the [swift-playdate-examples](https://github.com/swiftlang/swift-playdate-examples) repository has you covered. It contains the above ready-to-use examples that demonstrate how to build Swift games for the Playdate, both for the simulator and the hardware.
Additionally, the repository includes detailed documentation to guide you through the setup process. Whether you're a seasoned developer or just starting, you'll find the necessary resources to bring your ideas to life.
@@ -440,7 +440,7 @@ Thanks for diving into the bring-up journey with me. From refining the Swift Pla
However, with the issues now resolved, creating Playdate games in Swift is a streamlined process. Just run `make` and enjoy a development experience with Swift that is both expressive _and_ performant.
-You can find all the code examples mentioned in this post in the [swift-playdate-examples](https://github.com/apple/swift-playdate-examples) repository with accompanying "Getting Started" documentation.
+You can find all the code examples mentioned in this post in the [swift-playdate-examples](https://github.com/swiftlang/swift-playdate-examples) repository with accompanying "Getting Started" documentation.
I hope this post encourages you to explore the possibilities of using Swift in unconventional environments. Feel free to reach out with your experiences, questions, or game ideas on the [Swift Forums](https://forums.swift.org/t/byte-sized-swift-building-tiny-games-for-the-playdate/70615)!
diff --git a/_posts/2024-04-03-embedded-swift-examples.md b/_posts/2024-04-03-embedded-swift-examples.md
index b83f5aa62..868a51469 100644
--- a/_posts/2024-04-03-embedded-swift-examples.md
+++ b/_posts/2024-04-03-embedded-swift-examples.md
@@ -6,13 +6,13 @@ title: "Get Started with Embedded Swift on ARM and RISC-V Microcontrollers"
author: [kubamracek]
---
-We're pleased to introduce a [repository of example projects](https://github.com/apple/swift-embedded-examples) that demonstrate how Embedded Swift can be used to develop software on a range of microcontrollers.
+We're pleased to introduce a [repository of example projects](https://github.com/swiftlang/swift-embedded-examples) that demonstrate how Embedded Swift can be used to develop software on a range of microcontrollers.
Swift is a scalable language, great for writing desktop and mobile apps, server backends, and system software. And as you [may have seen](https://www.swift.org/blog/byte-sized-swift-tiny-games-playdate/), thanks to a new, experimental compilation mode, you can use Swift to target embedded environments like ARM and RISC-V microcontrollers as well, popular for building professional and hobbyist electronics projects such as IoT devices.
Microcontrollers are constrained environments where not all of Swift’s features are appropriate. The new Embedded Swift compilation mode turns off certain language features like runtime reflection, ABI stability, and existentials, to produce standalone binaries suitable for firmware. Despite turning off some language features, the Embedded Swift subset still feels very close to the “full” Swift that developers love, and makes it easy to continue writing idiomatic, easy-to-read Swift code. You can dive into the details in the formally accepted [Embedded Swift Vision Document](https://github.com/swiftlang/swift-evolution/blob/main/visions/embedded-swift.md), and try it out in the [nightly downloadable toolchains](https://www.swift.org/download/#snapshots).
-The Swift community has already started publishing [several](https://forums.swift.org/t/embedded-swift-on-the-raspberry-pi-pico-rp2040-without-the-pico-sdk/69338) [fascinating](https://forums.swift.org/t/rp2040mmio-a-hardware-access-layer-for-the-rp2040/69513/1) [projects](https://forums.swift.org/t/byte-sized-swift-building-tiny-games-for-the-playdate/70615) built with this language mode, and we thought it would be useful to publish a collection of sample projects at [**swift-embedded-examples**](https://github.com/apple/swift-embedded-examples).
+The Swift community has already started publishing [several](https://forums.swift.org/t/embedded-swift-on-the-raspberry-pi-pico-rp2040-without-the-pico-sdk/69338) [fascinating](https://forums.swift.org/t/rp2040mmio-a-hardware-access-layer-for-the-rp2040/69513/1) [projects](https://forums.swift.org/t/byte-sized-swift-building-tiny-games-for-the-playdate/70615) built with this language mode, and we thought it would be useful to publish a collection of sample projects at [**swift-embedded-examples**](https://github.com/swiftlang/swift-embedded-examples).
@@ -26,7 +26,7 @@ We encourage anyone interested to try out the examples and help us grow the repo
## Try It Out
-If you'd like to try out the existing example projects, visit the repository at [**swift-embedded-examples**](https://github.com/apple/swift-embedded-examples). It contains a catalog of examples along with instructions on how to build and run each of them.
+If you'd like to try out the existing example projects, visit the repository at [**swift-embedded-examples**](https://github.com/swiftlang/swift-embedded-examples). It contains a catalog of examples along with instructions on how to build and run each of them.
To use these examples, be sure to install the latest [development snapshot toolchain](https://www.swift.org/download/#snapshots). As an experimental mode, Embedded Swift is not yet available in release versions of Swift.
diff --git a/_posts/2025-05-05-memory-safety-ecosystem-talks-java-interoperability-fosdem-2025.md b/_posts/2025-05-05-memory-safety-ecosystem-talks-java-interoperability-fosdem-2025.md
new file mode 100644
index 000000000..da3cfa12c
--- /dev/null
+++ b/_posts/2025-05-05-memory-safety-ecosystem-talks-java-interoperability-fosdem-2025.md
@@ -0,0 +1,43 @@
+---
+layout: post
+published: true
+date: 2025-05-05 11:55:00
+title: "ICYMI: Memory Safety, Ecosystem Talks, and Java Interoperability at FOSDEM 2025"
+author: [parispittman]
+---
+
+The Swift community had a strong presence at FOSDEM 2025, the world’s largest independently run open source conference, held every year in Brussels, Belgium. FOSDEM highlighted a range of Swift-related talks related to memory safety, a broad ecosystem around Swift including using it to develop web services and embedded projects, and new areas of the project including Java interoperability.
+
+In case you missed it, here are a few highlights from the event:
+
+## Memory Safety in Swift
+
+The main track of the conference featured a talk presented by Doug Gregor on memory safety: [“Incremental Memory Safety in an Established Software Stack: Lessons Learned from Swift.”](https://fosdem.org/2025/schedule/event/fosdem-2025-6176-incremental-memory-safety-in-an-established-software-stack-lessons-learned-from-swift/)
+
+
+
+If you’re interested in learning more about Swift’s memory safe features, this talk is a great place to start; it walks through the different dimensions of memory safety in Swift, the language’s safe interoperability with C(++), and reflects on lessons learned for both programming language design and adopting Swift in an established software codebase.
+
+To learn more about memory in safety in Swift, see the [Swift documentation page on memory safety](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/memorysafety/),as well as a features [vision document on memory safety](https://github.com/swiftlang/swift-evolution/blob/main/visions/memory-safety.md).
+
+## Swift DevRoom
+
+FOSDEM is primarily organized into DevRooms, volunteer-organized conference tracks around technical communities and topics. This year Swift celebrated its inaugural DevRoom organized by a local community member, Steven Van Impe, with contributions from a large group of volunteers including proposal reviewers, speakers, and day-of-operations support.
+
+Swift’s first Swift DevRoom was a hit! 🎉 The room was packed with 12 talks, covering a wide range of topics and demos from the Swift ecosystem: talks related to running Swift on Linux, to showcasing various IDEs like VS Code, and a whole hour dedicated to embedded content. A few talks to highlight from the event:
+
+* [Building a Ferrofluidic Music Visualizer with Embedded Swift](https://fosdem.org/2025/schedule/event/fosdem-2025-5284-building-a-ferrofluidic-music-visualizer-with-embedded-swift/)
+* [Building container images with swift-container-plugin](https://fosdem.org/2025/schedule/event/fosdem-2025-5116-how-to-put-swift-in-a-box-building-container-images-with-swift-container-plugin/)
+* [Distributed Tracing in Server-Side Swift](https://fosdem.org/2025/schedule/event/fosdem-2025-5218-distributed-tracing-in-server-side-swift/)
+
+Check out the [complete lineup](https://fosdem.org/2025/schedule/track/swift/) to learn more!
+
+## Java Interoperability
+
+In the Free Java DevRoom, Konrad 'ktoso' Malawski presented on Java interoperability in Swift: [“Foreign Function and Memory APIs and Swift/Java interoperability.“](https://fosdem.org/2025/schedule/event/fosdem-2025-4886-foreign-function-and-memory-apis-and-swift-java-interoperability/)
+
+
+
+Konrad’s talk was a technical deep dive into the [Java interoperability effort](https://forums.swift.org/t/java-interoperability-effort/74969) that launched at the 2024, demonstrating the bridges and bindings needed to integrate systems written in these Swift and Java while still maintaining great performance. Catch up on this talk to see how you can leverage existing libraries without complete rewrites.
+
+Work in early development has been [released on GitHub](https://github.com/swiftlang/swift-java) for feedback and contributions, and your feedback is welcome on the [forums](https://forums.swift.org/c/development/java-interoperability/109).
\ No newline at end of file
diff --git a/_posts/2025-06-02-swift-at-apple-migrating-the-password-monitoring-service-from-java.md b/_posts/2025-06-02-swift-at-apple-migrating-the-password-monitoring-service-from-java.md
new file mode 100644
index 000000000..2fe534b20
--- /dev/null
+++ b/_posts/2025-06-02-swift-at-apple-migrating-the-password-monitoring-service-from-java.md
@@ -0,0 +1,65 @@
+---
+layout: post
+published: true
+date: 2025-06-02 10:00:00
+title: "Swift at Apple: Migrating the Password Monitoring service from Java"
+author: [rmondello, indravardhan, spencervd6, umeshbatra13]
+---
+
+_Swift is heavily used in production for building cloud services at Apple, with incredible results. Last year, the Password Monitoring service was rewritten in Swift, handling multiple billions of requests per day from devices all over the world. In comparison with the previous Java service, the updated backend delivers a 40% increase in performance, along with improved scalability, security, and availability._
+
+The Passwords app, introduced in the fall of 2024, helps users manage their passwords, passkeys, and verification codes. It allows them to store, autofill, and generate strong passwords that can be shared across all their devices, as well as share passwords with trusted contacts. One security feature included in the app is Password Monitoring, which warns users if one of their saved passwords shows up in a data leak. This feature has a server component, running on Linux-based infrastructure, that is maintained by Apple.
+
+On a regular interval, Password Monitoring checks a user’s passwords against a continuously updated and curated list of passwords that are known to have been exposed in a leak. Importantly, this task is handled in a thoughtful, privacy-preserving way that never reveals users’ passwords to Apple. A detailed discussion of how this is done using the cryptographic private set intersection protocol is in the [Password Monitoring](https://support.apple.com/guide/security/password-monitoring-sec78e79fc3b/web) section of the [Apple Platform Security](https://help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf) guide.
+
+The migration from Java to Swift was motivated by a need to scale the Password Monitoring service in a performant way. The layered encryption module used by Password Monitoring requires a significant amount of computation for each request, yet the overall service needs to respond quickly even when under high load.
+
+## Choosing Swift for increased performance
+
+For years, our team relied on Java to power large-scale, mission-critical services because of its proven stability and performance. However, Java’s memory management approach no longer aligns with our growing demands and efficiency goals. Instead of simply expanding hardware resources, we were seeking a more-efficient language to support our growth while reducing server overhead.
+
+Prior to seeking a replacement language, we sought ways of tuning the JVM to achieve the performance required. Java's G1 Garbage Collector (GC) mitigated some limitations of earlier collectors by introducing features like predictable pause times, region-based collection, and concurrent processing. However, even with these advancements, managing garbage collection at scale remains a challenge due to issues like prolonged GC pauses under high loads, increased performance overhead, and the complexity of fine-tuning for diverse workloads.
+
+One of the challenges faced by our Java service was its inability to quickly provision and decommission instances due to the overhead of the JVM. The Password Monitoring service runs globally, so service load can greatly fluctuate throughout the day, even with client-side techniques to smooth over the distribution of traffic. The peak and trough of a day differ by approximately 50% regionally. To efficiently manage this, we aim to scale down when demand is low and scale up as demand peaks in different regions. A faster bootstrap time is a crucial requirement to support this dynamic scaling strategy.
+
+Given the scale of our application and the volume of traffic we manage daily, the decision to transition from Java to another language was not made lightly. We evaluated our options, and found only a few languages that could help us achieve our goals. While you might expect that Apple would automatically choose Swift, we were pleasantly surprised by how well it fit the unique needs of a cloud-based service like ours. Swift has expressive syntax that was easy to learn, and could deliver the performance improvements necessary to meet the demands of our compute workloads. We decided to take a significant leap and started a rewrite of the Password Monitoring backend using Swift.
+
+## Our experience developing with Swift
+
+We began rewriting our service using [Vapor](https://vapor.codes/), a Swift web framework that provided Routing, Controller, and Content modules that we were able to build upon. Our service had additional requirements that led us to create a few custom packages with essential functionality: elliptic curve operations that are crucial for implementing [password monitoring](https://support.apple.com/guide/security/password-monitoring-sec78e79fc3b/web), auditing, configuration, error handling, and custom middleware.
+
+
+
+
+
+One of the most significant aspects of Swift that impressed us was its emphasis on [protocols](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/). In Java, we relied heavily on inheritance, which can lead to complex class hierarchies and tight coupling. Swift’s approach of protocols and generics promotes modularity and reusability by allowing classes, structs, and enums to share common protocols, enabling a more flexible and scalable codebase. This shift in mindset encouraged us to think in terms of behaviors rather than concrete classes, resulting in cleaner and more maintainable code.
+
+Safety is another area where Swift takes a distinctive approach compared to Java. For example, Swift’s optional type and safe unwrapping mechanisms eliminate the need for null checks everywhere, reducing the risk of null pointer exceptions and enhancing code readability. This safety-first approach ingrained throughout Swift’s language design, whether it is deterministic deallocation, copy-on-write (CoW), or value types, makes it inherently less prone to runtime errors.
+
+Swift's async/await support is a nice addition, streamlining how we handle async tasks. Previously, managing async operations often involved complex callback patterns or external libraries. Swift’s async/await syntax simplifies this process, making it more intuitive and less error-prone. We can now write async code that reads like sync code, leading to more readable, testable, and maintainable concurrency handling—especially critical in high-load, multi-threaded environments.
+
+Overall, our experience with Swift has been overwhelmingly positive and we were able to finish the rewrite much faster than initially estimated. Swift allowed us to write smaller, less verbose, and more expressive codebases (close to 85% reduction in lines of code) that are highly readable while prioritizing safety and efficiency.
+
+Our service benefited from a diverse ecosystem of Swift packages, including [logging](https://github.com/apple/swift-log) frameworks, a [Cassandra](https://github.com/apple/swift-cassandra-client) client, and [crypto](https://github.com/apple/swift-crypto) libraries that were readily available. In addition to an excellent support system and tooling, Swift’s inherent emphasis on modularity and extensibility helped future-proof and simplify the integration and customizations needed for our service-specific functions.
+
+## Takeaways for future Swift on server development
+
+We benchmarked performance throughout the process of development and deployment, allowing us to discover the trait of the Swift programming language that delighted us the most — its efficiency.
+
+Swift’s deterministic memory management led to a much lower memory threshold for our service. Not only were our initial results heartening, but after a few iterations of performance improvements, we had close to 40% throughput gain with latencies under 1 ms for 99.9% of requests on our current production hardware. Additionally, the new service had a much smaller memory footprint per instance — in the 100s of megabytes — an order of magnitude smaller compared to the 10s of gigabytes our Java implementation needed under peak load to sustain the same throughput and latencies. The service runs on Kubernetes, and the migration's efficiency improvements allowed us to release about 50% of its capacity for other workloads.
+
+
+
+
+
+Our Swift implementation has run smoothly and efficiently in production, making it worth the effort we put into this migration. In addition to outperforming our previous Java-based application, Swift delivered better performance consistency, enhanced safety features, and robust reliability — all while requiring fewer resources by utilizing memory and CPU efficiently. With fewer lines of boilerplate code and more flexible design patterns that we used, we look forward to simplified maintenance of our application. Swift was a powerful choice for building fast, resilient, and maintainable applications in our high-demand environment.
diff --git a/_posts/2025-06-04-redesigned-swift-org-is-now-live.md b/_posts/2025-06-04-redesigned-swift-org-is-now-live.md
new file mode 100644
index 000000000..f5575af5d
--- /dev/null
+++ b/_posts/2025-06-04-redesigned-swift-org-is-now-live.md
@@ -0,0 +1,42 @@
+---
+layout: post
+published: true
+date: 2025-06-04 10:00:00
+title: "Redesigned Swift.org is now live"
+author: [shahmishal]
+---
+
+Over the past few months, the website workgroup has been redesigning Swift.org. On behalf of the website workgroup, I'm pleased to announce that we have merged the initial changes.
+
+Our goal with the site redesign has been to make Swift.org more approachable for newcomers to Swift, highlight the language’s technical strengths, and make it easy to get started. That led to a focus on the website's appearance, improving the user experience, and emphasizing important features such as Swift’s multiplatform support.
+
+Today's release includes refreshed home and install pages. Additionally, new pages have been designed to explore Swift use cases, including cloud services, command line tools, and embedded software. Looking forward, we plan to take an iterative approach to improving the website, including pushing changes live as we complete their design and implementation.
+
+## Brand new design
+
+We explored several design options and found that the latest design conveys the fluidity and creativity of Swift through the splash of orange and the bird animation in the background.
+
+
+
+
+
+
+## Curated content and examples
+
+The homepage now highlights Swift's strengths alongside code examples that illustrate them. Additionally, we showcase various types of software that can be developed using Swift; these new use case pages provide information such as relevant packages, examples of Swift in action, code snippets, and links to resources for further learning.
+
+
+
+
+
+
+## Next Steps
+
+We look forward to hearing your feedback on this first set of changes as we continue to redesign other sections of the site. There are several ways to offer feedback on the redesign and to get involved:
+
+* A [forum announcement](https://forums.swift.org/t/redesigned-swift-org-is-now-live/80296) has been shared on the forums that can be used for discussion, and the website repository has GitHub issues.
+* The website itself is open source, and your contributions to the [swiftlang/swift-org-website](https://github.com/swiftlang/swift-org-website) repository are welcome.
+* [The Swift Information Architecture Project](https://forums.swift.org/t/announcing-the-swift-information-architecture-project/75866) is an ongoing effort that has helped inform decisions related to the site redesign.
+
+
+Thank you to the website workgroup and community members for contributing to these improvements.
diff --git a/api/v1/install/dev/6.2/amazonlinux2.json b/api/v1/install/dev/6.2/amazonlinux2.json
new file mode 100644
index 000000000..02646e01f
--- /dev/null
+++ b/api/v1/install/dev/6.2/amazonlinux2.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.amazonlinux2 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.amazonlinux2-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/centos7.json b/api/v1/install/dev/6.2/centos7.json
new file mode 100644
index 000000000..a9946a824
--- /dev/null
+++ b/api/v1/install/dev/6.2/centos7.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.centos7 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.centos7-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/debian12.json b/api/v1/install/dev/6.2/debian12.json
new file mode 100644
index 000000000..2ae39d84c
--- /dev/null
+++ b/api/v1/install/dev/6.2/debian12.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.debian12 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.debian12-aarch64 | jsonify }}
+}
diff --git a/api/v1/install/dev/6.2/fedora39.json b/api/v1/install/dev/6.2/fedora39.json
new file mode 100644
index 000000000..665a2f234
--- /dev/null
+++ b/api/v1/install/dev/6.2/fedora39.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.fedora39 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.fedora39-aarch64 | jsonify }}
+}
diff --git a/api/v1/install/dev/6.2/macos.json b/api/v1/install/dev/6.2/macos.json
new file mode 100644
index 000000000..dcca88520
--- /dev/null
+++ b/api/v1/install/dev/6.2/macos.json
@@ -0,0 +1,4 @@
+---
+layout: none
+---
+{ "universal": {{ site.data.builds.swift-6_2-branch.xcode | jsonify }}}
diff --git a/api/v1/install/dev/6.2/static-sdk.json b/api/v1/install/dev/6.2/static-sdk.json
new file mode 100644
index 000000000..8841fb41f
--- /dev/null
+++ b/api/v1/install/dev/6.2/static-sdk.json
@@ -0,0 +1,4 @@
+---
+layout: none
+---
+{{ site.data.builds.swift-6_2-branch.static_sdk | jsonify }}
\ No newline at end of file
diff --git a/api/v1/install/dev/6.2/ubi9.json b/api/v1/install/dev/6.2/ubi9.json
new file mode 100644
index 000000000..75d41018c
--- /dev/null
+++ b/api/v1/install/dev/6.2/ubi9.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.ubi9 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.ubi9-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/ubuntu2004.json b/api/v1/install/dev/6.2/ubuntu2004.json
new file mode 100644
index 000000000..a42158739
--- /dev/null
+++ b/api/v1/install/dev/6.2/ubuntu2004.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.ubuntu2004 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.ubuntu2004-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/ubuntu2204.json b/api/v1/install/dev/6.2/ubuntu2204.json
new file mode 100644
index 000000000..b701849f6
--- /dev/null
+++ b/api/v1/install/dev/6.2/ubuntu2204.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.ubuntu2204 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.ubuntu2204-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/ubuntu2404.json b/api/v1/install/dev/6.2/ubuntu2404.json
new file mode 100644
index 000000000..2c51db197
--- /dev/null
+++ b/api/v1/install/dev/6.2/ubuntu2404.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.ubuntu2404 | jsonify }},
+ "aarch64": {{ site.data.builds.swift-6_2-branch.ubuntu2404-aarch64 | jsonify}}
+}
diff --git a/api/v1/install/dev/6.2/windows10.json b/api/v1/install/dev/6.2/windows10.json
new file mode 100644
index 000000000..82a2f44e2
--- /dev/null
+++ b/api/v1/install/dev/6.2/windows10.json
@@ -0,0 +1,6 @@
+---
+layout: none
+---
+{ "x86_64": {{ site.data.builds.swift-6_2-branch.windows10 | jsonify }},
+ "arm64": {{ site.data.builds.swift-6_2-branch.windows10-arm64 | jsonify }}
+}
diff --git a/assets/fonts/Anonymous-Pro-B.ttf b/assets/fonts/Anonymous-Pro-B.ttf
new file mode 100644
index 000000000..985bd4002
Binary files /dev/null and b/assets/fonts/Anonymous-Pro-B.ttf differ
diff --git a/assets/fonts/Anonymous-Pro-BI.ttf b/assets/fonts/Anonymous-Pro-BI.ttf
new file mode 100644
index 000000000..838f2d125
Binary files /dev/null and b/assets/fonts/Anonymous-Pro-BI.ttf differ
diff --git a/assets/fonts/Anonymous-Pro-I.ttf b/assets/fonts/Anonymous-Pro-I.ttf
new file mode 100644
index 000000000..43505c164
Binary files /dev/null and b/assets/fonts/Anonymous-Pro-I.ttf differ
diff --git a/assets/fonts/Anonymous-Pro.ttf b/assets/fonts/Anonymous-Pro.ttf
new file mode 100644
index 000000000..06aafc067
Binary files /dev/null and b/assets/fonts/Anonymous-Pro.ttf differ
diff --git a/assets/fonts/Inter-Italic-VariableFont-opsz-wght.ttf b/assets/fonts/Inter-Italic-VariableFont-opsz-wght.ttf
new file mode 100644
index 000000000..43ed4f5ee
Binary files /dev/null and b/assets/fonts/Inter-Italic-VariableFont-opsz-wght.ttf differ
diff --git a/assets/fonts/Inter-VariableFont-opsz-wght.ttf b/assets/fonts/Inter-VariableFont-opsz-wght.ttf
new file mode 100644
index 000000000..e31b51e3e
Binary files /dev/null and b/assets/fonts/Inter-VariableFont-opsz-wght.ttf differ
diff --git a/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-1.png b/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-1.png
new file mode 100644
index 000000000..57f3d458e
Binary files /dev/null and b/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-1.png differ
diff --git a/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-2.png b/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-2.png
new file mode 100644
index 000000000..822bff1fb
Binary files /dev/null and b/assets/images/fosdem-2025-memory-and-java-blog/fosdem2025-2.png differ
diff --git a/assets/images/get-started/cloud-services-hero-top.png b/assets/images/get-started/cloud-services-hero-top.png
new file mode 100644
index 000000000..b9b1bf16e
Binary files /dev/null and b/assets/images/get-started/cloud-services-hero-top.png differ
diff --git a/assets/images/get-started/embedded-hero@2x.png b/assets/images/get-started/embedded-hero@2x.png
new file mode 100644
index 000000000..f1ca88cc0
Binary files /dev/null and b/assets/images/get-started/embedded-hero@2x.png differ
diff --git a/assets/images/get-started/embedded-swift-micro-controllers@2x.png b/assets/images/get-started/embedded-swift-micro-controllers@2x.png
new file mode 100644
index 000000000..2a2056ab0
Binary files /dev/null and b/assets/images/get-started/embedded-swift-micro-controllers@2x.png differ
diff --git a/assets/images/get-started/ergonomic-performant@2x.png b/assets/images/get-started/ergonomic-performant@2x.png
new file mode 100644
index 000000000..1ec54b730
Binary files /dev/null and b/assets/images/get-started/ergonomic-performant@2x.png differ
diff --git a/assets/images/get-started/harmony-bluetooth-speaker@2x.png b/assets/images/get-started/harmony-bluetooth-speaker@2x.png
new file mode 100644
index 000000000..5985b3744
Binary files /dev/null and b/assets/images/get-started/harmony-bluetooth-speaker@2x.png differ
diff --git a/assets/images/get-started/hero-bottom.png b/assets/images/get-started/hero-bottom.png
new file mode 100644
index 000000000..885b494cd
Binary files /dev/null and b/assets/images/get-started/hero-bottom.png differ
diff --git a/assets/images/get-started/interactive-ui-examples@2x.png b/assets/images/get-started/interactive-ui-examples@2x.png
new file mode 100644
index 000000000..89bb895df
Binary files /dev/null and b/assets/images/get-started/interactive-ui-examples@2x.png differ
diff --git a/assets/images/get-started/matter-homeKit-smartlight@2x.png b/assets/images/get-started/matter-homeKit-smartlight@2x.png
new file mode 100644
index 000000000..438ff0d6c
Binary files /dev/null and b/assets/images/get-started/matter-homeKit-smartlight@2x.png differ
diff --git a/assets/images/get-started/package.png b/assets/images/get-started/package.png
new file mode 100644
index 000000000..5371b654e
Binary files /dev/null and b/assets/images/get-started/package.png differ
diff --git a/assets/images/get-started/playdate-device@2x.png b/assets/images/get-started/playdate-device@2x.png
new file mode 100644
index 000000000..07a5fb36d
Binary files /dev/null and b/assets/images/get-started/playdate-device@2x.png differ
diff --git a/assets/images/get-started/playdate-kit@2x.png b/assets/images/get-started/playdate-kit@2x.png
new file mode 100644
index 000000000..a5d3969ed
Binary files /dev/null and b/assets/images/get-started/playdate-kit@2x.png differ
diff --git a/assets/images/get-started/swift-performance-graph@2x.png b/assets/images/get-started/swift-performance-graph@2x.png
new file mode 100644
index 000000000..a506ab63b
Binary files /dev/null and b/assets/images/get-started/swift-performance-graph@2x.png differ
diff --git a/assets/images/get-started/swift-performance-graph~dark@2x.png b/assets/images/get-started/swift-performance-graph~dark@2x.png
new file mode 100644
index 000000000..c308e08f2
Binary files /dev/null and b/assets/images/get-started/swift-performance-graph~dark@2x.png differ
diff --git a/assets/images/get-started/tiny-games-playdate@2x.png b/assets/images/get-started/tiny-games-playdate@2x.png
new file mode 100644
index 000000000..624817a47
Binary files /dev/null and b/assets/images/get-started/tiny-games-playdate@2x.png differ
diff --git a/assets/images/getting-started/cloud-services/humingbird@2x.png b/assets/images/getting-started/cloud-services/humingbird@2x.png
new file mode 100644
index 000000000..d7970bcdf
Binary files /dev/null and b/assets/images/getting-started/cloud-services/humingbird@2x.png differ
diff --git a/assets/images/getting-started/cloud-services/secondary-card-vapor-logo.png b/assets/images/getting-started/cloud-services/secondary-card-vapor-logo.png
new file mode 100644
index 000000000..ecc97fa4d
Binary files /dev/null and b/assets/images/getting-started/cloud-services/secondary-card-vapor-logo.png differ
diff --git a/assets/images/getting-started/embedded/ergonimic-and-performant.png b/assets/images/getting-started/embedded/ergonimic-and-performant.png
new file mode 100644
index 000000000..0efa7cdce
Binary files /dev/null and b/assets/images/getting-started/embedded/ergonimic-and-performant.png differ
diff --git a/assets/images/getting-started/embedded/pico-blinking.gif b/assets/images/getting-started/embedded/pico-blinking.gif
new file mode 100644
index 000000000..be54e05cb
Binary files /dev/null and b/assets/images/getting-started/embedded/pico-blinking.gif differ
diff --git a/assets/images/getting-started/embedded/pimary-card-hummingbird-logo.jpg b/assets/images/getting-started/embedded/pimary-card-hummingbird-logo.jpg
new file mode 100644
index 000000000..afc972bc2
Binary files /dev/null and b/assets/images/getting-started/embedded/pimary-card-hummingbird-logo.jpg differ
diff --git a/assets/images/getting-started/embedded/primary-card-vapor-logo.jpg b/assets/images/getting-started/embedded/primary-card-vapor-logo.jpg
new file mode 100644
index 000000000..f7e8fe464
Binary files /dev/null and b/assets/images/getting-started/embedded/primary-card-vapor-logo.jpg differ
diff --git a/assets/images/getting-started/embedded/secondary-card-vapor-logo.jpg b/assets/images/getting-started/embedded/secondary-card-vapor-logo.jpg
new file mode 100644
index 000000000..e19044346
Binary files /dev/null and b/assets/images/getting-started/embedded/secondary-card-vapor-logo.jpg differ
diff --git a/assets/images/exclusivity-blog/Example1.png b/assets/images/getting-started/exclusivity-blog/Example1.png
similarity index 100%
rename from assets/images/exclusivity-blog/Example1.png
rename to assets/images/getting-started/exclusivity-blog/Example1.png
diff --git a/assets/images/exclusivity-blog/Example2.png b/assets/images/getting-started/exclusivity-blog/Example2.png
similarity index 100%
rename from assets/images/exclusivity-blog/Example2.png
rename to assets/images/getting-started/exclusivity-blog/Example2.png
diff --git a/assets/images/exclusivity-blog/Example3.png b/assets/images/getting-started/exclusivity-blog/Example3.png
similarity index 100%
rename from assets/images/exclusivity-blog/Example3.png
rename to assets/images/getting-started/exclusivity-blog/Example3.png
diff --git a/assets/images/exclusivity-blog/Example4a.png b/assets/images/getting-started/exclusivity-blog/Example4a.png
similarity index 100%
rename from assets/images/exclusivity-blog/Example4a.png
rename to assets/images/getting-started/exclusivity-blog/Example4a.png
diff --git a/assets/images/exclusivity-blog/Example4b.png b/assets/images/getting-started/exclusivity-blog/Example4b.png
similarity index 100%
rename from assets/images/exclusivity-blog/Example4b.png
rename to assets/images/getting-started/exclusivity-blog/Example4b.png
diff --git a/assets/images/exclusivity-blog/XcodeBuildSettings.png b/assets/images/getting-started/exclusivity-blog/XcodeBuildSettings.png
similarity index 100%
rename from assets/images/exclusivity-blog/XcodeBuildSettings.png
rename to assets/images/getting-started/exclusivity-blog/XcodeBuildSettings.png
diff --git a/assets/images/hummingbird.png b/assets/images/hummingbird.png
new file mode 100644
index 000000000..6e04b2603
Binary files /dev/null and b/assets/images/hummingbird.png differ
diff --git a/assets/images/icon-ai.svg b/assets/images/icon-ai.svg
new file mode 100644
index 000000000..9642b5d11
--- /dev/null
+++ b/assets/images/icon-ai.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-arrow-right-circle.svg b/assets/images/icon-arrow-right-circle.svg
new file mode 100644
index 000000000..d620adbf9
--- /dev/null
+++ b/assets/images/icon-arrow-right-circle.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/images/icon-chip.svg b/assets/images/icon-chip.svg
new file mode 100644
index 000000000..b9eca80f2
--- /dev/null
+++ b/assets/images/icon-chip.svg
@@ -0,0 +1,21 @@
+
+
+ embedded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-cloud.svg b/assets/images/icon-cloud.svg
new file mode 100644
index 000000000..f1ede198e
--- /dev/null
+++ b/assets/images/icon-cloud.svg
@@ -0,0 +1,7 @@
+
+
+ cloud-services
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-command-line.svg b/assets/images/icon-command-line.svg
new file mode 100644
index 000000000..550c468ed
--- /dev/null
+++ b/assets/images/icon-command-line.svg
@@ -0,0 +1,11 @@
+
+
+ command-line
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-copy.svg b/assets/images/icon-copy.svg
new file mode 100644
index 000000000..bdee8facd
--- /dev/null
+++ b/assets/images/icon-copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon-desktop.svg b/assets/images/icon-desktop.svg
new file mode 100644
index 000000000..53d52ad2e
--- /dev/null
+++ b/assets/images/icon-desktop.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-games.svg b/assets/images/icon-games.svg
new file mode 100644
index 000000000..6ae8bcc00
--- /dev/null
+++ b/assets/images/icon-games.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-github.svg b/assets/images/icon-github.svg
new file mode 100644
index 000000000..37fa923df
--- /dev/null
+++ b/assets/images/icon-github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon-mobile.svg b/assets/images/icon-mobile.svg
new file mode 100644
index 000000000..b334bb35e
--- /dev/null
+++ b/assets/images/icon-mobile.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-packages.svg b/assets/images/icon-packages.svg
new file mode 100644
index 000000000..d8dc97059
--- /dev/null
+++ b/assets/images/icon-packages.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/icon-websites.svg b/assets/images/icon-websites.svg
new file mode 100644
index 000000000..c7212e22a
--- /dev/null
+++ b/assets/images/icon-websites.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/install/swoops/swoop-0.png b/assets/images/install/swoops/swoop-0.png
new file mode 100644
index 000000000..1ae872600
Binary files /dev/null and b/assets/images/install/swoops/swoop-0.png differ
diff --git a/assets/images/landing-page/hero/bird.png b/assets/images/landing-page/hero/bird.png
new file mode 100644
index 000000000..a7121c5bd
Binary files /dev/null and b/assets/images/landing-page/hero/bird.png differ
diff --git a/assets/images/landing-page/hero/orange-swoop-bottom.png b/assets/images/landing-page/hero/orange-swoop-bottom.png
new file mode 100644
index 000000000..39e4a59ca
Binary files /dev/null and b/assets/images/landing-page/hero/orange-swoop-bottom.png differ
diff --git a/assets/images/landing-page/hero/orange-swoop-top.png b/assets/images/landing-page/hero/orange-swoop-top.png
new file mode 100644
index 000000000..ddcec7c3e
Binary files /dev/null and b/assets/images/landing-page/hero/orange-swoop-top.png differ
diff --git a/assets/images/landing-page/hero/purple-swoop.png b/assets/images/landing-page/hero/purple-swoop.png
new file mode 100644
index 000000000..edabf5756
Binary files /dev/null and b/assets/images/landing-page/hero/purple-swoop.png differ
diff --git a/assets/images/landing-page/hero/white-swoop-1.png b/assets/images/landing-page/hero/white-swoop-1.png
new file mode 100644
index 000000000..232c53ecf
Binary files /dev/null and b/assets/images/landing-page/hero/white-swoop-1.png differ
diff --git a/assets/images/landing-page/hero/white-swoop-2.png b/assets/images/landing-page/hero/white-swoop-2.png
new file mode 100644
index 000000000..27fe82a23
Binary files /dev/null and b/assets/images/landing-page/hero/white-swoop-2.png differ
diff --git a/assets/images/landing-page/swoops/swoop-0.png b/assets/images/landing-page/swoops/swoop-0.png
new file mode 100644
index 000000000..3cde32846
Binary files /dev/null and b/assets/images/landing-page/swoops/swoop-0.png differ
diff --git a/assets/images/landing-page/swoops/swoop-1.png b/assets/images/landing-page/swoops/swoop-1.png
new file mode 100644
index 000000000..dbcbbf5cc
Binary files /dev/null and b/assets/images/landing-page/swoops/swoop-1.png differ
diff --git a/assets/images/landing-page/swoops/swoop-2.png b/assets/images/landing-page/swoops/swoop-2.png
new file mode 100644
index 000000000..648b5cdf5
Binary files /dev/null and b/assets/images/landing-page/swoops/swoop-2.png differ
diff --git a/assets/images/noise.png b/assets/images/noise.png
new file mode 100644
index 000000000..146a505a8
Binary files /dev/null and b/assets/images/noise.png differ
diff --git a/assets/images/placeholders/image_placeholder_large.png b/assets/images/placeholders/image_placeholder_large.png
new file mode 100644
index 000000000..231b789b4
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_large.png differ
diff --git a/assets/images/placeholders/image_placeholder_large@2x.png b/assets/images/placeholders/image_placeholder_large@2x.png
new file mode 100644
index 000000000..050eb0d13
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_large@2x.png differ
diff --git a/assets/images/placeholders/image_placeholder_playdate.png b/assets/images/placeholders/image_placeholder_playdate.png
new file mode 100644
index 000000000..bb78f9147
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_playdate.png differ
diff --git a/assets/images/placeholders/image_placeholder_playdate@2x.png b/assets/images/placeholders/image_placeholder_playdate@2x.png
new file mode 100644
index 000000000..2c4d23319
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_playdate@2x.png differ
diff --git a/assets/images/placeholders/image_placeholder_small.png b/assets/images/placeholders/image_placeholder_small.png
new file mode 100644
index 000000000..f47c84719
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_small.png differ
diff --git a/assets/images/placeholders/image_placeholder_small@2x.png b/assets/images/placeholders/image_placeholder_small@2x.png
new file mode 100644
index 000000000..295a3a058
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_small@2x.png differ
diff --git a/assets/images/placeholders/image_placeholder_tiny.png b/assets/images/placeholders/image_placeholder_tiny.png
new file mode 100644
index 000000000..8c0912f18
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_tiny.png differ
diff --git a/assets/images/placeholders/image_placeholder_tiny@2x.png b/assets/images/placeholders/image_placeholder_tiny@2x.png
new file mode 100644
index 000000000..762f593ba
Binary files /dev/null and b/assets/images/placeholders/image_placeholder_tiny@2x.png differ
diff --git a/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/password monitoring service.png b/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/password monitoring service.png
new file mode 100644
index 000000000..13c287584
Binary files /dev/null and b/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/password monitoring service.png differ
diff --git a/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/resource utilization.png b/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/resource utilization.png
new file mode 100644
index 000000000..0baba9bf0
Binary files /dev/null and b/assets/images/swift-at-apple-migrating-the-password-monitoring-service-from-java/resource utilization.png differ
diff --git a/assets/images/swift-redesign-blog/cloud_dark@2x.jpg b/assets/images/swift-redesign-blog/cloud_dark@2x.jpg
new file mode 100644
index 000000000..46c5e9975
Binary files /dev/null and b/assets/images/swift-redesign-blog/cloud_dark@2x.jpg differ
diff --git a/assets/images/swift-redesign-blog/cloud_light@2x.jpg b/assets/images/swift-redesign-blog/cloud_light@2x.jpg
new file mode 100644
index 000000000..d05248096
Binary files /dev/null and b/assets/images/swift-redesign-blog/cloud_light@2x.jpg differ
diff --git a/assets/images/swift-redesign-blog/code_dark@2x.jpg b/assets/images/swift-redesign-blog/code_dark@2x.jpg
new file mode 100644
index 000000000..48937490b
Binary files /dev/null and b/assets/images/swift-redesign-blog/code_dark@2x.jpg differ
diff --git a/assets/images/swift-redesign-blog/code_light@2x.jpg b/assets/images/swift-redesign-blog/code_light@2x.jpg
new file mode 100644
index 000000000..a78b8dcec
Binary files /dev/null and b/assets/images/swift-redesign-blog/code_light@2x.jpg differ
diff --git a/assets/images/swift-redesign-blog/home_dark@2x.jpg b/assets/images/swift-redesign-blog/home_dark@2x.jpg
new file mode 100644
index 000000000..cf1dc3467
Binary files /dev/null and b/assets/images/swift-redesign-blog/home_dark@2x.jpg differ
diff --git a/assets/images/swift-redesign-blog/home_light@2x.jpg b/assets/images/swift-redesign-blog/home_light@2x.jpg
new file mode 100644
index 000000000..c4a00e685
Binary files /dev/null and b/assets/images/swift-redesign-blog/home_light@2x.jpg differ
diff --git a/assets/images/vapor.png b/assets/images/vapor.png
new file mode 100644
index 000000000..efca3053d
Binary files /dev/null and b/assets/images/vapor.png differ
diff --git a/assets/javascripts/color-scheme-toggle.js b/assets/javascripts/color-scheme-toggle.js
index fc5875236..d8fbb02e0 100644
--- a/assets/javascripts/color-scheme-toggle.js
+++ b/assets/javascripts/color-scheme-toggle.js
@@ -1,28 +1,28 @@
-document.addEventListener("DOMContentLoaded", ready);
+document.addEventListener('DOMContentLoaded', ready)
const ColorScheme = {
auto: 'auto',
light: 'light',
- dark: 'dark'
-};
+ dark: 'dark',
+}
// Must be same as key used by microsites so that the preferences stick across microsites
-const localStorageKey = 'developer.setting.preferredColorScheme';
+const localStorageKey = 'developer.setting.preferredColorScheme'
-const supportsAutoColorScheme = (typeof window.matchMedia !== 'undefined') && [
- ColorScheme.light,
- ColorScheme.dark,
- 'no-preference',
-].some(scheme => window.matchMedia(`(prefers-color-scheme: ${scheme})`).matches);
+const supportsAutoColorScheme =
+ typeof window.matchMedia !== 'undefined' &&
+ [ColorScheme.light, ColorScheme.dark, 'no-preference'].some(
+ (scheme) => window.matchMedia(`(prefers-color-scheme: ${scheme})`).matches,
+ )
// Hide auto as an option if the system doesn't support light/dark/auto
if (!supportsAutoColorScheme) {
- document.getElementById('scheme-auto-wrapper').remove();
+ document.getElementById('scheme-auto-wrapper').remove()
}
//////////////////////////////////
-setColorSchemeFor(preferredColorSchemeSetting());
+setColorSchemeFor(preferredColorSchemeSetting())
//////////////////////////////////
/* Events */
@@ -34,34 +34,34 @@ window.addEventListener('storage', (e) => {
if (ColorScheme[e.newValue] == undefined) {
if (ColorScheme[e.oldValue] == undefined) {
if (supportsAutoColorScheme) {
- setColorSchemeFor(ColorScheme.auto);
+ setColorSchemeFor(ColorScheme.auto)
} else {
- setColorSchemeFor(ColorScheme.light);
+ setColorSchemeFor(ColorScheme.light)
}
} else {
- setColorSchemeFor(e.oldValue);
+ setColorSchemeFor(e.oldValue)
}
} else {
- setColorSchemeFor(e.newValue);
+ setColorSchemeFor(e.newValue)
}
-});
+})
// Needed to update page when Safari back button is used after toggle has been changed
window.addEventListener('pageshow', () => {
- setColorSchemeFor(preferredColorSchemeSetting());
-});
+ setColorSchemeFor(preferredColorSchemeSetting())
+})
systemLightMedia().addEventListener('change', (e) => {
if (e.matches && preferredColorSchemeIsAuto()) {
- updateColorSchemeAttribute(ColorScheme.light);
+ updateColorSchemeAttribute(ColorScheme.light)
}
-});
+})
systemDarkMedia().addEventListener('change', (e) => {
if (e.matches && preferredColorSchemeIsAuto()) {
- updateColorSchemeAttribute(ColorScheme.dark);
+ updateColorSchemeAttribute(ColorScheme.dark)
}
-});
+})
//////////////////////////////////
/* General */
@@ -69,35 +69,37 @@ systemDarkMedia().addEventListener('change', (e) => {
function setColorSchemeFor(value) {
switch (value) {
case ColorScheme.light:
- changeColorScheme(ColorScheme.light);
- break;
+ changeColorScheme(ColorScheme.light)
+ break
case ColorScheme.dark:
- changeColorScheme(ColorScheme.dark);
- break;
+ changeColorScheme(ColorScheme.dark)
+ break
case ColorScheme.auto:
default:
// Update to light or dark, depending on current system situation
- let systemColorScheme = systemIsDark() ? ColorScheme.dark : ColorScheme.light;
- changeColorScheme(systemColorScheme, ColorScheme.auto);
- break;
+ let systemColorScheme = systemIsDark()
+ ? ColorScheme.dark
+ : ColorScheme.light
+ changeColorScheme(systemColorScheme, ColorScheme.auto)
+ break
}
}
function changeColorScheme(color, setting = color) {
// Don't unnecessarily set localStorage if same value
if (setting !== preferredColorSchemeSetting()) {
- updateColorSchemeSetting(setting);
+ updateColorSchemeSetting(setting)
}
// Don't unnecessarily change body attribute if same value
if (getColorSchemeAttribute() !== color) {
- updateColorSchemeAttribute(color);
+ updateColorSchemeAttribute(color)
}
// Don't unnecessarily set the toggle if same value
if (!!getToggleRadioNodeList()) {
if (getToggle().value !== setting) {
- setToggleTo(setting);
+ setToggleTo(setting)
}
}
}
@@ -105,50 +107,50 @@ function changeColorScheme(color, setting = color) {
/* System values */
function systemLightMedia() {
- return window.matchMedia('(prefers-color-scheme: light)');
+ return window.matchMedia('(prefers-color-scheme: light)')
}
function systemDarkMedia() {
- return window.matchMedia('(prefers-color-scheme: dark)');
+ return window.matchMedia('(prefers-color-scheme: dark)')
}
//////////////////////////////////
/* Getters and Setters for system values */
function getToggleRadioNodeList() {
- return document.getElementById('color-scheme-toggle');
+ return document.getElementById('color-scheme-toggle')
}
function getToggle() {
- return getToggleRadioNodeList().elements['color-scheme-preference'];
+ return getToggleRadioNodeList().elements['color-scheme-preference']
}
function setToggleTo(value) {
- getToggle().value = value;
+ getToggle().value = value
}
// Boolean if is given value
function getColorSchemeAttribute() {
- return document.body.getAttribute('data-color-scheme');
+ return document.body.getAttribute('data-color-scheme')
}
function updateColorSchemeAttribute(color) {
- document.body.setAttribute('data-color-scheme', color);
+ document.body.setAttribute('data-color-scheme', color)
}
function preferredColorSchemeSetting() {
try {
- return window.localStorage.getItem(localStorageKey);
+ return window.localStorage.getItem(localStorageKey)
} catch (_) {
// referencing `localStorage` when "Block all cookies" is enabled
// will throw an error
- return null;
+ return null
}
}
function updateColorSchemeSetting(color) {
try {
- window.localStorage.setItem(localStorageKey, color);
+ window.localStorage.setItem(localStorageKey, color)
} catch (_) {
// referencing `localStorage` when "Block all cookies" is enabled
// will throw an error
@@ -159,24 +161,24 @@ function updateColorSchemeSetting(color) {
/* Utils */
function systemIsLight() {
- return systemLightMedia().matches;
+ return systemLightMedia().matches
}
function systemIsDark() {
- return systemDarkMedia().matches;
+ return systemDarkMedia().matches
}
// Boolean if localStorage setting is Auto
function preferredColorSchemeIsAuto() {
- return preferredColorSchemeSetting() == ColorScheme.auto;
+ return preferredColorSchemeSetting() == ColorScheme.auto
}
function ready() {
if (getToggle().value !== preferredColorSchemeSetting()) {
- setToggleTo(preferredColorSchemeSetting());
+ setToggleTo(preferredColorSchemeSetting())
}
getToggleRadioNodeList().addEventListener('change', (e) => {
- setColorSchemeFor(e.target.value);
- });
+ setColorSchemeFor(e.target.value)
+ })
}
diff --git a/assets/javascripts/install.js b/assets/javascripts/install.js
index cb3ec3cef..d9edf4113 100644
--- a/assets/javascripts/install.js
+++ b/assets/javascripts/install.js
@@ -1,4 +1,4 @@
-const { userAgentData, userAgent } = window.navigator;
+const { userAgentData, userAgent } = window.navigator
const osToOsRegex = {
windows: /win/,
@@ -12,6 +12,9 @@ const osToPage = {
linux: '/install/linux/',
}
-const OS = Object.keys(osToOsRegex).find(os => osToOsRegex[os].test(userAgent.toLowerCase())) || 'macos';
+const OS =
+ Object.keys(osToOsRegex).find((os) =>
+ osToOsRegex[os].test(userAgent.toLowerCase()),
+ ) || 'macos'
-window.location.replace(OS);
+window.location.replace(OS)
diff --git a/assets/javascripts/new-javascripts/application.js b/assets/javascripts/new-javascripts/application.js
new file mode 100644
index 000000000..955afc964
--- /dev/null
+++ b/assets/javascripts/new-javascripts/application.js
@@ -0,0 +1,114 @@
+function toggleClass(element, className) {
+ if (!element || !className) {
+ return
+ }
+ var classString = element.className,
+ nameIndex = classString.indexOf(className)
+ if (nameIndex == -1) {
+ classString += ' ' + className
+ } else {
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
+ }
+ element.className = classString
+}
+
+document
+ .getElementById('menu-toggle')
+ .addEventListener('mousedown', function () {
+ const menuToggle = document.getElementById('menu-toggle')
+ toggleClass(menuToggle, 'open')
+ menuToggle.setAttribute(
+ 'aria-expanded',
+ menuToggle.getAttribute('aria-expanded') === 'true' ? 'false' : 'true',
+ )
+ toggleClass(document.querySelector('nav.mobile-navigation'), 'open')
+ })
+
+document.addEventListener('DOMContentLoaded', function () {
+ const sectionToggles = document.querySelectorAll('.section-toggle')
+
+ sectionToggles.forEach(function (toggle) {
+ toggle.addEventListener('mousedown', function () {
+ var navSubmenu = toggle.closest('.link-container').nextElementSibling
+
+ if (navSubmenu) {
+ toggleClass(navSubmenu, 'open')
+ var isExpanded = toggle.getAttribute('aria-expanded') === 'true'
+ toggle.setAttribute('aria-expanded', isExpanded ? 'false' : 'true')
+ }
+ })
+ })
+})
+
+if (navigator && navigator.clipboard) {
+ const codeBlocks = document.querySelectorAll(
+ ':is([class^="language-"] pre.highlight, .code-box pre code)',
+ );
+
+ const copyIcon = ` `;
+ const copiedIcon = ` `;
+
+ codeBlocks.forEach((codeBlock) => {
+ const button = document.createElement('button');
+ const codeElement = codeBlock.querySelector('code') || codeBlock;
+ const container = codeBlock.parentElement;
+
+ button.classList.add('copy-button');
+ container.appendChild(button);
+ button.innerHTML = copyIcon
+
+ button.addEventListener('mousedown', async () => {
+ const originalIcon = copyIcon; // Store the original icon
+
+ try {
+ await navigator.clipboard.writeText(codeElement.innerText);
+
+ button.classList.add('copied');
+ button.innerHTML = copiedIcon;
+
+ setTimeout(() => {
+ button.classList.remove('copied');
+ button.innerHTML = originalIcon;
+ }, 1000);
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
+ setTimeout(() => {
+ button.innerHTML = originalIcon; // Revert to original icon
+ }, 1000);
+ }
+ });
+ });
+}
+
+// Check for reduced motion setting
+if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
+ document.body.classList.add('reduced-motion')
+}
+
+// code-box
+const codeBoxes = document.querySelectorAll('.code-box-with-tabs')
+
+if (codeBoxes.length) {
+ const ACTIVE_CLASS = 'active'
+
+ codeBoxes.forEach((codeBox) => {
+ const tabNav = codeBox.querySelector('nav')
+ const navItems = tabNav.querySelectorAll('li')
+ const codeBlocks = codeBox.querySelectorAll('pre')
+ let activeIndex = 0
+
+ navItems.forEach((item) => {
+ item.addEventListener('click', (evt) => {
+ const targetIndex = evt.target.getAttribute('data-tab-index')
+ if (!targetIndex || evt.target.classList.contains(ACTIVE_CLASS)) return
+ navItems[activeIndex].classList.remove(ACTIVE_CLASS)
+ codeBlocks[activeIndex].classList.remove(ACTIVE_CLASS)
+ activeIndex = evt.target.getAttribute('data-tab-index')
+ navItems[activeIndex].classList.add(ACTIVE_CLASS)
+ codeBlocks[activeIndex].classList.add(ACTIVE_CLASS)
+ })
+ })
+ })
+}
diff --git a/assets/javascripts/new-javascripts/carousel.js b/assets/javascripts/new-javascripts/carousel.js
new file mode 100644
index 000000000..9cee58c0a
--- /dev/null
+++ b/assets/javascripts/new-javascripts/carousel.js
@@ -0,0 +1,47 @@
+document.querySelectorAll('.carousel-container').forEach((container) => {
+ const carousel = container.querySelector('.carousel')
+ const items = container.querySelectorAll('.carousel-item')
+ const prevBtn = container.querySelector('.prev-btn')
+ const nextBtn = container.querySelector('.next-btn')
+ const gap = 16
+ const itemWidth = items[0].offsetWidth + gap
+ const totalItems = items.length
+ const visibleItems = 3
+ const maxIndex = totalItems - visibleItems
+ let currentIndex = 0
+
+ function scrollToIndex(index) {
+ currentIndex = Math.max(0, Math.min(index, maxIndex))
+
+ carousel.scrollTo({
+ left: currentIndex * itemWidth,
+ behavior: 'smooth',
+ })
+
+ updateButtons()
+ }
+
+ function updateButtons() {
+ const scrollLeft = carousel.scrollLeft
+ const maxScrollLeft = carousel.scrollWidth - carousel.clientWidth
+
+ prevBtn.disabled = scrollLeft <= 0
+ nextBtn.disabled = scrollLeft >= maxScrollLeft - 1
+ }
+
+ function updateIndexFromScroll() {
+ const scrollLeft = carousel.scrollLeft
+
+ currentIndex = Math.round(scrollLeft / itemWidth)
+ updateButtons()
+ }
+
+ carousel.addEventListener('scroll', () => {
+ window.requestAnimationFrame(updateIndexFromScroll)
+ })
+
+ prevBtn.addEventListener('click', () => scrollToIndex(currentIndex - 1))
+ nextBtn.addEventListener('click', () => scrollToIndex(currentIndex + 1))
+
+ scrollToIndex(0)
+})
diff --git a/assets/javascripts/new-javascripts/color-scheme-toggle.js b/assets/javascripts/new-javascripts/color-scheme-toggle.js
new file mode 100644
index 000000000..7a6716aff
--- /dev/null
+++ b/assets/javascripts/new-javascripts/color-scheme-toggle.js
@@ -0,0 +1,125 @@
+document.addEventListener('DOMContentLoaded', initColorScheme);
+
+const ColorScheme = {
+ auto: 'auto',
+ light: 'light',
+ dark: 'dark',
+};
+
+const localStorageKey = 'developer.setting.preferredColorScheme';
+
+const supportsAutoColorScheme = (() => {
+ return typeof window.matchMedia !== 'undefined' &&
+ ['light', 'dark', 'no-preference'].some(
+ (scheme) => window.matchMedia(`(prefers-color-scheme: ${scheme})`).matches
+ );
+})();
+
+if (!supportsAutoColorScheme) {
+ document.getElementById('scheme-auto-wrapper')?.remove();
+}
+
+function initColorScheme() {
+ setColorScheme(getStoredScheme());
+
+ const toggle = getToggle();
+ if (toggle && toggle.value !== getStoredScheme()) {
+ toggle.value = getStoredScheme();
+ }
+
+ getToggleForm()?.addEventListener('change', (e) => {
+ setColorScheme(e.target.value);
+ });
+}
+
+function systemPrefersLight() {
+ return window.matchMedia('(prefers-color-scheme: light)');
+}
+
+function systemPrefersDark() {
+ return window.matchMedia('(prefers-color-scheme: dark)');
+}
+
+function isSystemDark() {
+ return systemPrefersDark().matches;
+}
+
+function setColorScheme(value) {
+ if (!Object.values(ColorScheme).includes(value)) {
+ value = supportsAutoColorScheme ? ColorScheme.auto : ColorScheme.light;
+ }
+
+ if (value === ColorScheme.auto) {
+ updateScheme(isSystemDark() ? ColorScheme.dark : ColorScheme.light, value);
+ } else {
+ updateScheme(value);
+ }
+}
+
+function updateScheme(scheme, storedValue = scheme) {
+ if (getStoredScheme() !== storedValue) {
+ saveScheme(storedValue);
+ }
+
+ if (getCurrentScheme() !== scheme) {
+ document.body.setAttribute('data-color-scheme', scheme);
+ }
+
+ const toggle = getToggle();
+ if (toggle && toggle.value !== storedValue) {
+ toggle.value = storedValue;
+ }
+}
+
+systemPrefersLight().addEventListener('change', (e) => {
+ if (e.matches && getStoredScheme() === ColorScheme.auto) {
+ const current = getCurrentScheme();
+ if (current !== ColorScheme.light) {
+ document.body.setAttribute('data-color-scheme', ColorScheme.light);
+ }
+ }
+});
+
+systemPrefersDark().addEventListener('change', (e) => {
+ if (e.matches && getStoredScheme() === ColorScheme.auto) {
+ const current = getCurrentScheme();
+ if (current !== ColorScheme.dark) {
+ document.body.setAttribute('data-color-scheme', ColorScheme.dark);
+ }
+ }
+});
+
+window.addEventListener('storage', () => {
+ setColorScheme(getStoredScheme());
+});
+
+window.addEventListener('pageshow', () => {
+ setColorScheme(getStoredScheme());
+});
+
+function getToggleForm() {
+ return document.getElementById('color-scheme-toggle');
+}
+
+function getToggle() {
+ return getToggleForm()?.elements['color-scheme-preference'];
+}
+
+function getCurrentScheme() {
+ return document.body.getAttribute('data-color-scheme');
+}
+
+function getStoredScheme() {
+ try {
+ return localStorage.getItem(localStorageKey);
+ } catch {
+ return null;
+ }
+}
+
+function saveScheme(value) {
+ try {
+ localStorage.setItem(localStorageKey, value);
+ } catch {
+ }
+}
diff --git a/assets/javascripts/new-javascripts/hero.js b/assets/javascripts/new-javascripts/hero.js
new file mode 100644
index 000000000..bd7767695
--- /dev/null
+++ b/assets/javascripts/new-javascripts/hero.js
@@ -0,0 +1,294 @@
+const heroAnimation = async (animContainer) => {
+ const isReduceMotionEnabled = window.matchMedia(
+ '(prefers-reduced-motion: reduce)',
+ ).matches
+ const urlParams = new URLSearchParams(location.search)
+ const hasDebugParam = urlParams.has('debug')
+
+ async function loadImage(url) {
+ const el = new Image()
+ return new Promise((resolve, reject) => {
+ el.onload = () => resolve(el)
+ el.onerror = (err) => reject(err)
+ el.src = url
+ })
+ }
+
+ // Skip to visible portion of animation when cropped on small screens
+ const { left, width } = animContainer.getClientRects()[0]
+ const offScreenDelta = Math.abs(left) / width
+
+ const heroSwoops = [
+ {
+ canvas: document.querySelector('#purple-swoop'),
+ path: 'M-34 860C-34 860 42 912 102 854C162 796 98 658 50 556C2 454 18 48 142 88C272 130 290 678 432 682C574 686 434 102 794 90C1009 83 1028 280 1028 280',
+ pathLength: 2776,
+ anchorPoints: [558, 480.5],
+ position: [558, 640.5],
+ imagePath: '/assets/images/landing-page/hero/purple-swoop.png',
+ lineWidth: 210,
+ debugColor: 'purple',
+ image: null,
+ state: { progress: offScreenDelta },
+ },
+ {
+ canvas: document.querySelector('#white-swoop-1'),
+ path: 'M-26 910C-26 910 209 817 90 542C38 422 -87 99 102 62C294 24 226 454 397 650C540 812 530 398 567 228C600 84 764 -94 1182 320',
+ pathLength: 3015.6103515625,
+ anchorPoints: [600, 456],
+ position: [600, 652],
+ imagePath: '/assets/images/landing-page/hero/white-swoop-1.png',
+ lineWidth: 140,
+ debugColor: 'red',
+ image: null,
+ state: { progress: offScreenDelta },
+ },
+ {
+ canvas: document.querySelector('#white-swoop-2'),
+ path: ' M-59,796.5009765625 C-59,796.5009765625 258.5199890136719,885.5130004882812 361,430.5 C461,-13.5 757,18.5 903,44.5 C1049,70.5 1123,166.5 1167,228.5',
+ pathLength: 1716,
+ anchorPoints: [595, 417],
+ position: [594, 508.5],
+ imagePath: '/assets/images/landing-page/hero/white-swoop-2.png',
+ lineWidth: 73.6,
+ debugColor: 'cyan',
+ image: null,
+ state: { progress: offScreenDelta },
+ },
+ {
+ canvas: document.querySelector('#orange-swoop-bottom'),
+ path: 'M-74 816C-74 816 216 887 326 598C408 382 458 170 634 180C809 190 851 305 904 368C972 448 1124 476 1124 476',
+ pathLength: 1651,
+ anchorPoints: [610, 455.5],
+ position: [610, 479.5],
+ imagePath: '/assets/images/landing-page/hero/orange-swoop-bottom.png',
+ lineWidth: 202.2,
+ debugColor: 'yellow',
+ image: null,
+ state: { progress: offScreenDelta },
+ },
+ {
+ canvas: document.querySelector('#orange-swoop-top'),
+ path: 'M468 168C468 168 674 46 858 78C1018 106 1116 142 1160 414',
+ pathLength: 906,
+ anchorPoints: [610, 455.5],
+ position: [610, 479.5],
+ imagePath: '/assets/images/landing-page/hero/orange-swoop-top.png',
+ lineWidth: 163.4,
+ debugColor: 'green',
+ image: null,
+ state: { progress: offScreenDelta },
+ },
+ ]
+ const logo = {
+ canvas: document.querySelector('#bird'),
+ positionStart: [899.2, 202.5],
+ positionEnd: [1084, 388],
+ anchorPoints: [304, 268.5],
+ position: [610, 672.5],
+ imagePath: '/assets/images/landing-page/hero/bird.png',
+ image: null,
+ state: { progress: offScreenDelta },
+ }
+
+ const initSwoops = ({
+ path,
+ pathLength,
+ position: [posX, posY],
+ lineWidth,
+ debugColor,
+ canvas,
+ image,
+ }) => {
+ const ctx = canvas.getContext('2d')
+ // The reference animation's transform origin is in the center of the canvas
+ // We're not going to reset this as it will make pulling values directly from AE easier
+ ctx.translate(posX - image.naturalWidth / 2, posY - image.naturalHeight / 2)
+ // Set mask styles
+ ctx.lineWidth = lineWidth
+ ctx.lineCap = 'round'
+ let pathInstance = new Path2D(path)
+
+ if (!isReduceMotionEnabled) {
+ ctx.setLineDash([pathLength])
+ ctx.lineDashOffset = pathLength
+
+ if (hasDebugParam) {
+ ctx.strokeStyle = debugColor
+ ctx.stroke(pathInstance)
+ }
+ } else {
+ ctx.drawImage(image, 0, 0)
+ }
+
+ return { ctx, pathInstance }
+ }
+
+ const initLogo = ({
+ canvas,
+ image,
+ positionStart: [posX, posY],
+ positionEnd: [endX, endY],
+ }) => {
+ const ctx = canvas.getContext('2d')
+ // Applying this conversion for the same purpose as init swoops
+ ctx.translate(posX - image.naturalWidth / 2, posY - image.naturalHeight / 2)
+
+ if (isReduceMotionEnabled) {
+ ctx.globalAlpha = 1
+ const deltaX = endX - posX
+ const deltaY = endY - posY
+ ctx.drawImage(image, deltaX, deltaY)
+ }
+
+ return ctx
+ }
+
+ try {
+ // Load swoop images
+ const swoopImages = await Promise.all(
+ heroSwoops.map((swoop) => loadImage(swoop.imagePath)),
+ )
+ // Load logo
+ const logoImage = await loadImage(logo.imagePath)
+
+ logo.image = logoImage
+ // Init canvas for each swoop layer
+ heroSwoops.forEach((swoop, i) => {
+ swoop.image = swoopImages[i]
+ const canvasData = initSwoops(swoop)
+ swoop.ctx = canvasData.ctx
+ swoop.pathInstance = canvasData.pathInstance
+ })
+ // Init logo canvas
+ logo.ctx = initLogo(logo)
+ } catch (error) {
+ console.error('Error loading images:', error)
+ throw error
+ }
+
+ // Skip animation if reduced motion is enabled
+ if (isReduceMotionEnabled) {
+ return
+ }
+
+ const DURATION = 1000 - 1000 * offScreenDelta
+
+ const tl = anime.createTimeline({
+ defaults: { duration: DURATION, ease: 'in(1.8)' },
+ })
+
+ tl.label('start', 0)
+
+ const swoopUpdate = ({
+ state,
+ ctx,
+ pathLength,
+ pathInstance,
+ image,
+ canvas,
+ }) => {
+ // Clear canvas before next draw
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
+ // Progress line dash offset
+ ctx.lineDashOffset = pathLength * (1 - state.progress)
+ // Draw stroke
+ ctx.stroke(pathInstance)
+ // Source-in will allow us to only draw as far as the stroke
+ ctx.globalCompositeOperation = 'source-in'
+ ctx.drawImage(image, 0, 0)
+ // Reset to default for our next stroke paint
+ ctx.globalCompositeOperation = 'source-out'
+ }
+
+ // White swoop 1
+ tl.add(
+ heroSwoops[1].state,
+ {
+ progress: 1,
+ duration: 950 - 950 * offScreenDelta,
+ onUpdate: () => swoopUpdate(heroSwoops[1]),
+ },
+ 'start',
+ )
+ // Purple swoop
+ tl.add(
+ heroSwoops[0].state,
+ {
+ progress: 1,
+ duration: 950 - 950 * offScreenDelta,
+ onUpdate: () => swoopUpdate(heroSwoops[0]),
+ },
+ 'start',
+ )
+ // White swoop 2
+ tl.add(
+ heroSwoops[2].state,
+ {
+ progress: 1,
+ onUpdate: () => swoopUpdate(heroSwoops[2]),
+ },
+ 'start',
+ )
+ // Orange swoop bottom
+ tl.add(
+ heroSwoops[3].state,
+ {
+ progress: 1,
+ onUpdate: () => swoopUpdate(heroSwoops[3]),
+ },
+ 'start',
+ )
+ // Orange top
+ tl.add(
+ heroSwoops[4].state,
+ {
+ progress: 1,
+ duration: 480 - 480 * offScreenDelta,
+ delay: 520 - 520 * offScreenDelta,
+ onUpdate: () => swoopUpdate(heroSwoops[4]),
+ },
+ 'start',
+ )
+ // Logo
+ tl.add(
+ logo.state,
+ {
+ ease: 'out(1.2)',
+ duration: 200 - 200 * offScreenDelta,
+ delay: 750 - 750 * offScreenDelta,
+ progress: 1,
+ onUpdate: () => {
+ const {
+ state: { progress },
+ ctx,
+ image,
+ canvas,
+ positionStart: [startX, startY],
+ positionEnd: [endX, endY],
+ } = logo
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
+ // Progresses logo opacity from 0 to 1
+ ctx.globalAlpha = progress
+ const deltaX = (endX - startX) * progress
+ const deltaY = (endY - startY) * progress
+ ctx.drawImage(image, deltaX, deltaY)
+ },
+ },
+ 'start',
+ )
+}
+
+// Start animation when container is mounted
+const observer = new MutationObserver(() => {
+ const animContainer = document.querySelector('.animation-container')
+ if (animContainer) {
+ observer.disconnect()
+ heroAnimation(animContainer)
+ }
+})
+
+observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true,
+})
diff --git a/assets/javascripts/new-javascripts/install.js b/assets/javascripts/new-javascripts/install.js
new file mode 100644
index 000000000..0b8ff87f9
--- /dev/null
+++ b/assets/javascripts/new-javascripts/install.js
@@ -0,0 +1,24 @@
+const { userAgent } = window.navigator
+
+const osToRegex = {
+ windows: /win/,
+ macos: /macintosh/,
+ linux: /linux/,
+}
+
+const detectedOS =
+ Object.keys(osToRegex).find((os) =>
+ osToRegex[os].test(userAgent.toLowerCase()),
+ ) || 'linux'
+
+// Utility in case we need just to hightlight the tab
+// document.querySelectorAll('.interactive-tabs.os').forEach(tabBlock => {
+// const links = tabBlock.querySelectorAll('[data-tab-name]');
+
+// links.forEach(link => {
+// const isActive = link.dataset.tabName === activeTabName;
+// link.setAttribute('aria-pressed', isActive ? 'true' : 'false');
+// });
+// });
+
+window.location.replace(detectedOS)
diff --git a/assets/javascripts/new-javascripts/landing.js b/assets/javascripts/new-javascripts/landing.js
new file mode 100644
index 000000000..caf21b3cb
--- /dev/null
+++ b/assets/javascripts/new-javascripts/landing.js
@@ -0,0 +1,39 @@
+const urlParams = new URLSearchParams(location.search)
+const hasDebugParam = urlParams.has('debug')
+const reduceMotion = document.body.classList.contains('reduced-motion')
+
+// Scroll Animations
+
+const swoops = document.querySelectorAll('.swoop-anim')
+const swoopAniVars = [
+ { backgroundPosition: '67.5% 0%' },
+ { backgroundPosition: '80% 0%' },
+ { backgroundPosition: '60% 0%' },
+]
+
+swoops.forEach((el, i) => {
+ anime.animate(el, {
+ autoplay: anime.onScroll({
+ axis: 'y',
+ debug: hasDebugParam,
+ enter: 'bottom - 100%',
+ container: 'body',
+ target: el,
+ onEnter: () => {
+ el.classList.add('visible')
+ },
+ }),
+ })
+ if (!reduceMotion) {
+ anime.animate(el, {
+ ...swoopAniVars[i],
+ autoplay: anime.onScroll({
+ container: 'body',
+ enter: { target: 'top-=50%', container: 'bottom-=50%' },
+ leave: { target: 'bottom-=50%', container: 'top-=50%' },
+ sync: 0.1,
+ debug: hasDebugParam,
+ }),
+ })
+ }
+})
diff --git a/assets/javascripts/new-javascripts/vendor/anime.iife.min.js b/assets/javascripts/new-javascripts/vendor/anime.iife.min.js
new file mode 100644
index 000000000..ea128f90c
--- /dev/null
+++ b/assets/javascripts/new-javascripts/vendor/anime.iife.min.js
@@ -0,0 +1,9 @@
+/**
+ * anime.js - IIFE
+ * @version v4.0.2
+ * @author Julian Garnier
+ * @license MIT
+ * @copyright (c) 2025 Julian Garnier
+ * @see https://animejs.com
+ */
+var anime=function(t){"use strict";const e="undefined"!=typeof window,s=e?window:null,i=e?document:null,r={replace:0,none:1,blend:2},n=Symbol(),o=Symbol(),a=Symbol(),h=Symbol(),l=Symbol(),c=Symbol(),d=1e-11,u=1e12,p=1e3,m="",f=new Map;f.set("x","translateX"),f.set("y","translateY"),f.set("z","translateZ");const g=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective","matrix","matrix3d"],_=g.reduce(((t,e)=>({...t,[e]:e+"("})),{}),y=()=>{},v=/(^#([\da-f]{3}){1,2}$)|(^#([\da-f]{4}){1,2}$)/i,b=/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i,S=/rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(-?\d+|-?\d*.\d+)\s*\)/i,x=/hsl\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*\)/i,T=/hsla\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)\s*\)/i,w=/[-+]?\d*\.?\d+(?:e[-+]?\d)?/gi,k=/^([-+]?\d*\.?\d+(?:e[-+]?\d+)?)([a-z]+|%)$/i,$=/([a-z])([A-Z])/g,E=/(\w+)(\([^)]+\)+)/g,C=/(\*=|\+=|-=)/,B={id:null,keyframes:null,playbackEase:null,playbackRate:1,frameRate:120,loop:0,reversed:!1,alternate:!1,autoplay:!0,duration:p,delay:0,loopDelay:0,ease:"out(2)",composition:r.replace,modifier:t=>t,onBegin:y,onBeforeUpdate:y,onUpdate:y,onLoop:y,onPause:y,onComplete:y,onRender:y},D={defaults:B,root:i,scope:null,precision:4,timeScale:1,tickThreshold:200},L={version:"4.0.2",engine:null};e&&(s.AnimeJS||(s.AnimeJS=[]),s.AnimeJS.push(L));const A=t=>t.replace($,"$1-$2").toLowerCase(),N=(t,e)=>0===t.indexOf(e),F=Date.now,P=Array.isArray,R=t=>t&&t.constructor===Object,Y=t=>"number"==typeof t&&!isNaN(t),X=t=>"string"==typeof t,M=t=>"function"==typeof t,O=t=>void 0===t,z=t=>O(t)||null===t,I=t=>e&&t instanceof SVGElement,W=t=>v.test(t),V=t=>N(t,"rgb"),U=t=>N(t,"hsl"),H=t=>!D.defaults.hasOwnProperty(t),q=t=>X(t)?parseFloat(t):t,Q=Math.pow,j=Math.sqrt,G=Math.sin,Z=Math.cos,J=Math.abs,K=Math.exp,tt=Math.ceil,et=Math.floor,st=Math.asin,it=Math.max,rt=Math.atan2,nt=Math.PI,ot=Math.round,at=(t,e,s)=>ts?s:t,ht={},lt=(t,e)=>{if(e<0)return t;if(!e)return ot(t);let s=ht[e];return s||(s=ht[e]=10**e),ot(t*s)/s},ct=(t,e)=>P(e)?e.reduce(((e,s)=>J(s-t)t+(e-t)*s,ut=t=>t===1/0?u:t===-1/0?-1e12:t,pt=t=>t<=d?d:ut(lt(t,11)),mt=t=>P(t)?[...t]:t,ft=(t,e)=>{const s={...t};for(let i in e){const r=t[i];s[i]=O(r)?e[i]:r}return s},gt=(t,e,s,i="_prev",r="_next")=>{let n=t._head,o=r;for(s&&(n=t._tail,o=i);n;){const t=n[o];e(n),n=t}},_t=(t,e,s="_prev",i="_next")=>{const r=e[s],n=e[i];r?r[i]=n:t._head=n,n?n[s]=r:t._tail=r,e[s]=null,e[i]=null},yt=(t,e,s,i="_prev",r="_next")=>{let n=t._tail;for(;n&&s&&s(n,e);)n=n[i];const o=n?n[r]:t._head;n?n[r]=e:t._head=e,o?o[i]=e:t._tail=e,e[i]=n,e[r]=o};class vt{constructor(t=0){this.deltaTime=0,this._currentTime=t,this._elapsedTime=t,this._startTime=t,this._lastTime=t,this._scheduledTime=0,this._frameDuration=lt(p/120,0),this._fps=120,this._speed=1,this._hasChildren=!1,this._head=null,this._tail=null}get fps(){return this._fps}set fps(t){const e=this._frameDuration,s=+t,i=s{const o=t.parent,a=t.duration,l=t.completed,c=t.iterationDuration,u=t.iterationCount,p=t._currentIteration,f=t._loopDelay,g=t._reversed,y=t._alternate,v=t._hasChildren,b=t._delay,S=t._currentTime,x=b+c,T=e-b,w=at(S,-b,a),k=at(T,-b,a),$=T-S,E=k>0,C=k>=a,B=a<=d,L=2===n;let A=0,N=T,F=0;if(u>1){const e=~~(k/(c+(C?0:f)));t._currentIteration=at(e,0,u),C&&t._currentIteration--,A=t._currentIteration%2,N=k%(c+f)||0}const P=g^(y&&A),R=t._ease;let Y=C?P?0:a:P?c-N:N;R&&(Y=c*R(Y/c)||0);const X=(o?o.backwards:T=b&&e<=x||e<=b&&w>b||e>=x&&w!==a)||Y>=x&&w!==a||Y<=b&&w>0||e<=w&&w===a&&l||C&&!l&&B){if(E&&(t.computeDeltaTime(w),s||t.onBeforeUpdate(t)),!v){const e=L||(X?-1*$:$)>=D.tickThreshold,n=t._offset+(o?o._offset:0)+b+Y;let a,l,c,d,u=t._head,p=0;for(;u;){const t=u._composition,s=u._currentTime,o=u._changeDuration,f=u._absoluteStartTime+u._changeDuration,g=u._nextRep,y=u._prevRep,v=t!==r.none;if((e||(s!==o||n<=f+(g?g._delay:0))&&(0!==s||n>=u._absoluteStartTime))&&(!v||!u._isOverridden&&(!u._isOverlapped||n<=f)&&(!g||g._isOverridden||n<=g._absoluteStartTime)&&(!y||y._isOverridden||n>=y._absoluteStartTime+y._changeDuration+u._delay))){const e=u._currentTime=at(Y-u._startTime,0,o),s=u._ease(e/u._updateDuration),n=u._modifier,m=u._valueType,f=u._tweenType,g=0===f,_=0===m,y=_&&g||0===s||1===s?-1:D.precision;let b,S;if(_)b=S=n(lt(dt(u._fromNumber,u._toNumber,s),y));else if(1===m)S=n(lt(dt(u._fromNumber,u._toNumber,s),y)),b=`${S}${u._unit}`;else if(2===m){const t=u._fromNumbers,e=u._toNumbers,i=lt(at(n(dt(t[0],e[0],s)),0,255),0),r=lt(at(n(dt(t[1],e[1],s)),0,255),0),o=lt(at(n(dt(t[2],e[2],s)),0,255),0),a=at(n(lt(dt(t[3],e[3],s),y)),0,1);if(b=`rgba(${i},${r},${o},${a})`,v){const t=u._numbers;t[0]=i,t[1]=r,t[2]=o,t[3]=a}}else if(3===m){b=u._strings[0];for(let t=0,e=u._toNumbers.length;t=a&&!l||X&&T<=d&&l)&&(t.onComplete(t),t.completed=!X):E&&C?u===1/0?t._startTime+=t.duration:t._currentIteration>=u-1&&(t.paused=!0,l||v||(t.completed=!0,s||o&&(X||!o.began)||(t.onComplete(t),t._resolve(t)))):t.completed=!1,F},St=(t,e,s,i,r)=>{const n=t._currentIteration;if(bt(t,e,s,i,r),t._hasChildren){const o=t,a=o.backwards,h=i?e:o._iterationTime,l=F();let c=0,u=!0;if(!i&&o._currentIteration!==n){const t=o.iterationDuration;gt(o,(e=>{if(a){const i=e.duration,r=e._offset+e._delay;s||!(i<=d)||r&&r+i!==t||e.onComplete(e)}else!e.completed&&!e.backwards&&e._currentTime{const e=lt((h-t._offset)*t._speed,12),n=t._fps=o.duration&&(o.paused=!0,o.completed||(o.completed=!0,s||(o.onComplete(o),o._resolve(o))))}},xt={animation:null,update:y},Tt=e?requestAnimationFrame:setImmediate,wt=e?cancelAnimationFrame:clearImmediate;class kt extends vt{constructor(t){super(t),this.useDefaultMainLoop=!0,this.pauseOnDocumentHidden=!0,this.defaults=B,this.paused=!(!e||!i.hidden),this.reqId=null}update(){const t=this._currentTime=F();if(this.requestTick(t)){this.computeDeltaTime(t);const e=this._speed,s=this._fps;let i=this._head;for(;i;){const r=i._next;i.paused?(_t(this,i),this._hasChildren=!!this._tail,i._running=!1,i.completed&&!i._cancelled&&i.cancel()):St(i,(t-i._startTime)*i._speed*e,0,0,i._fpst.resetTime())),this.wake()}get speed(){return this._speed*(1===D.timeScale?1:p)}set speed(t){this._speed=t*D.timeScale,gt(this,(t=>t.speed=t._speed))}get timeUnit(){return 1===D.timeScale?"ms":"s"}set timeUnit(t){const e="s"===t,s=e?.001:1;if(D.timeScale!==s){D.timeScale=s,D.tickThreshold=200*s;const t=e?.001:p;this.defaults.duration*=t,this._speed*=t}}get precision(){return D.precision}set precision(t){D.precision=t}}const $t=(()=>{const t=new kt(F());return e&&(L.engine=t,i.addEventListener("visibilitychange",(()=>{t.pauseOnDocumentHidden&&(i.hidden?t.pause():t.resume())}))),t})(),Et=()=>{$t._head?($t.reqId=Tt(Et),$t.update()):$t.reqId=0},Ct=()=>(wt($t.reqId),$t.reqId=0,$t);function Bt(t){const e=X(t)?D.root.querySelectorAll(t):t;if(e instanceof NodeList||e instanceof HTMLCollection)return e}function Dt(t){if(z(t))return[];if(P(t)){const e=t.flat(1/0),s=[];for(let t=0,i=e.length;t{const e=Dt(t)[0];if(e&&I(e))return e},Nt=(t,e,s=0)=>t.getPointAtLength(e+s>=1?e+s:0),Ft=(t,e)=>s=>{const i=+t.getTotalLength(),r=s[a],n=t.getCTM();return{from:0,to:i,modifier:s=>{if("a"===e){const e=Nt(t,s,-1),i=Nt(t,s,1);return 180*rt(i.y-e.y,i.x-e.x)/nt}{const i=Nt(t,s,0);return"x"===e?r||!n?i.x:i.x*n.a+i.y*n.c+n.e:r||!n?i.y:i.x*n.b+i.y*n.d+n.f}}}},Pt=["opacity","rotate","overflow","color"],Rt={morphTo:(t,e=.33)=>s=>{const i=At(t);if(!i)return;const r="path"===s.tagName,n=r?" ":",",o=s[l];o&&s.setAttribute(r?"d":"points",o);let a="",h="";if(e){const t=s.getTotalLength(),o=i.getTotalLength(),l=Math.max(Math.ceil(t*e),Math.ceil(o*e));for(let e=0;e{const e=At(t);if(e)return{translateX:Ft(e,"x"),translateY:Ft(e,"y"),rotate:Ft(e,"a")}},createDrawable:(t,e=0,s=0)=>Dt(t).map((t=>((t,e,s)=>{const i=p,r=getComputedStyle(t),n=r.strokeLinecap,o="non-scaling-stroke"===r.vectorEffect?t:null;let a=n;const h=new Proxy(t,{get(t,e){const s=t[e];return e===c?t:"setAttribute"===e?(...e)=>{if("draw"===e[0]){const s=e[1].split(" "),r=+s[0],h=+s[1],l=(t=>{let e=1;if(t&&t.getCTM){const s=t.getCTM();s&&(e=(j(s.a*s.a+s.b*s.b)+j(s.c*s.c+s.d*s.d))/2)}return e})(o),c=-1e3*r*l,d=h*i*l+c,u=i*l+(0===r&&1===h||1===r&&0===h?0:10*l)-d;if("butt"!==n){const e=r===h?"butt":n;a!==e&&(t.style.strokeLinecap=`${e}`,a=e)}t.setAttribute("stroke-dashoffset",`${c}`),t.setAttribute("stroke-dasharray",`${d} ${u}`)}return Reflect.apply(s,t,e)}:M(s)?(...e)=>Reflect.apply(s,t,e):s}});return"1000"!==t.getAttribute("pathLength")&&(t.setAttribute("pathLength","1000"),h.setAttribute("draw",`${e} ${s}`)),h})(t,e,s)))},Yt=(t,e,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(e-t)*s:s<.5?e:s<2/3?t+(e-t)*(2/3-s)*6:t),Xt=(t,e)=>O(t)?e:t,Mt=(t,e,s,i,r)=>{if(M(t)){const n=()=>{const r=t(e,s,i);return isNaN(+r)?r||0:+r};return r&&(r.func=n),n()}return t},Ot=(t,e)=>t[o]?t[a]&&((t,e)=>{if(Pt.includes(e))return!1;if(t.getAttribute(e)||e in t){if("scale"===e){const e=t.parentNode;return e&&"filter"===e.tagName}return!0}})(t,e)?1:g.includes(e)||f.get(e)?3:N(e,"--")?4:e in t.style?2:e in t?0:1:0,zt=(t,e,s)=>{const i=t.style[e];i&&s&&(s[e]=i);const r=i||getComputedStyle(t[c]||t).getPropertyValue(e);return"auto"===r?"0":r},It=(t,e,s,i)=>{const r=O(s)?Ot(t,e):s;return 0===r?t[e]||0:1===r?t.getAttribute(e):3===r?((t,e,s)=>{const i=t.style.transform;let r;if(i){const n=t[h];let o;for(;o=E.exec(i);){const t=o[1],i=o[2].slice(1,-1);n[t]=i,t===e&&(r=i,s&&(s[e]=i))}}return i&&!O(r)?r:N(e,"scale")?"1":N(e,"rotate")||N(e,"skew")?"0deg":"0px"})(t,e,i):4===r?zt(t,e,i).trimStart():zt(t,e,i)},Wt=(t,e,s)=>"-"===s?t-e:"+"===s?t+e:t*e,Vt=(t,e)=>{if(e.t=0,e.n=0,e.u=null,e.o=null,e.d=null,e.s=null,!t)return e;const s=+t;if(isNaN(s)){let s=t;"="===s[1]&&(e.o=s[0],s=s.slice(2));const n=!s.includes(" ")&&k.exec(s);if(n)return e.t=1,e.n=+n[1],e.u=n[2],e;if(e.o)return e.n=+s,e;if(W(r=s)||V(r)||U(r))return e.t=2,e.d=V(i=s)?(t=>{const e=b.exec(t)||S.exec(t),s=O(e[4])?1:+e[4];return[+e[1],+e[2],+e[3],s]})(i):W(i)?(t=>{const e=t.length,s=4===e||5===e;return[+("0x"+t[1]+t[s?1:2]),+("0x"+t[s?2:3]+t[s?2:4]),+("0x"+t[s?3:5]+t[s?3:6]),5===e||9===e?+(+("0x"+t[s?4:7]+t[s?4:8])/255).toFixed(3):1]})(i):U(i)?(t=>{const e=x.exec(t)||T.exec(t),s=+e[1]/360,i=+e[2]/100,r=+e[3]/100,n=O(e[4])?1:+e[4];let o,a,h;if(0===i)o=a=h=r;else{const t=r<.5?r*(1+i):r+i-r*i,e=2*r-t;o=lt(255*Yt(e,t,s+1/3),0),a=lt(255*Yt(e,t,s),0),h=lt(255*Yt(e,t,s-1/3),0)}return[o,a,h,n]})(i):[0,0,0,1],e;{const t=s.match(w);return e.t=3,e.d=t?t.map(Number):[],e.s=s.split(w)||[],e}}var i,r;return e.n=s,e},Ut=(t,e)=>(e.t=t._valueType,e.n=t._toNumber,e.u=t._unit,e.o=null,e.d=mt(t._toNumbers),e.s=mt(t._strings),e),Ht={t:0,n:0,u:null,o:null,d:null,s:null},qt={_rep:new WeakMap,_add:new Map},Qt=(t,e,s="_rep")=>{const i=qt[s];let r=i.get(t);return r||(r={},i.set(t,r)),r[e]?r[e]:r[e]={_head:null,_tail:null}},jt=(t,e)=>t._isOverridden||t._absoluteStartTime>e._absoluteStartTime,Gt=t=>{t._isOverlapped=1,t._isOverridden=1,t._changeDuration=d,t._currentTime=d},Zt=(t,e)=>{const s=t._composition;if(s===r.replace){const s=t._absoluteStartTime;yt(e,t,jt,"_prevRep","_nextRep");const i=t._prevRep;if(i){const e=i.parent,r=i._absoluteStartTime+i._changeDuration;if(t.parent.id!==e.id&&e.iterationCount>1&&r+(e.duration-e.iterationDuration)>s){Gt(i);let t=i._prevRep;for(;t&&t.parent.id===e.id;)Gt(t),t=t._prevRep}const n=s-t._delay;if(r>n){const t=i._startTime,e=r-(t+i._updateDuration);i._changeDuration=n-e-t,i._currentTime=i._changeDuration,i._isOverlapped=1,i._changeDuration{t._isOverlapped||(o=!1)})),o){const t=e.parent;if(t){let s=!0;gt(t,(t=>{t!==e&>(t,(t=>{t._isOverlapped||(s=!1)}))})),s&&t.cancel()}else e.cancel()}}}else if(s===r.blend){const e=Qt(t.target,t.property,"_add"),s=(t=>{let e=xt.animation;return e||(e={duration:d,computeDeltaTime:y,_offset:0,_delay:0,_head:null,_tail:null},xt.animation=e,xt.update=()=>{t.forEach((t=>{for(let e in t){const s=t[e],i=s._head;if(i){const t=i._valueType,e=3===t||2===t?mt(i._fromNumbers):null;let r=i._fromNumber,n=s._tail;for(;n&&n!==i;){if(e)for(let t=0,s=n._numbers.length;t{t._fromNumbers[s]=i._fromNumbers[s]-e,t._toNumbers[s]=0})),i._fromNumbers=e}yt(e,t,null,"_prevAdd","_nextAdd")}return t},Jt=t=>{const e=t._composition;if(e!==r.none){const s=t.target,i=t.property,n=qt._rep.get(s)[i];if(_t(n,t,"_prevRep","_nextRep"),e===r.blend){const e=qt._add,r=e.get(s);if(!r)return;const n=r[i],o=xt.animation;_t(n,t,"_prevAdd","_nextAdd");const a=n._head;if(a&&a===n._tail){_t(n,a,"_prevAdd","_nextAdd"),_t(o,a);let t=!0;for(let e in r)if(r[e]._head){t=!1;break}t&&e.delete(s)}}}return t},Kt=t=>(t.paused=!0,t.began=!1,t.completed=!1,t),te=t=>t._cancelled?(t._hasChildren?gt(t,te):gt(t,(t=>{t._composition!==r.none&&Zt(t,Qt(t.target,t.property))})),t._cancelled=0,t):t;let ee=0;class se extends vt{constructor(t={},e=null,s=0){super(0);const{id:i,delay:r,duration:n,reversed:o,alternate:a,loop:h,loopDelay:l,autoplay:c,frameRate:u,playbackRate:p,onComplete:m,onLoop:f,onPause:g,onBegin:_,onBeforeUpdate:v,onUpdate:b}=t;D.scope&&D.scope.revertibles.push(this);const S=e?0:$t._elapsedTime,x=e?e.defaults:D.defaults,T=M(r)||O(r)?x.delay:+r,w=M(n)||O(n)?1/0:+n,k=Xt(h,x.loop),$=Xt(l,x.loopDelay),E=!0===k||k===1/0||k<0?1/0:k+1;let C=0;if(e)C=s;else{let t=F();$t.paused&&($t.requestTick(t),t=$t._elapsedTime),C=t-$t._startTime}this.id=O(i)?++ee:i,this.parent=e,this.duration=ut((w+$)*E-$)||d,this.backwards=!1,this.paused=!0,this.began=!1,this.completed=!1,this.onBegin=_||x.onBegin,this.onBeforeUpdate=v||x.onBeforeUpdate,this.onUpdate=b||x.onUpdate,this.onLoop=f||x.onLoop,this.onPause=g||x.onPause,this.onComplete=m||x.onComplete,this.iterationDuration=w,this.iterationCount=E,this._autoplay=!e&&Xt(c,x.autoplay),this._offset=C,this._delay=T,this._loopDelay=$,this._iterationTime=0,this._currentIteration=0,this._resolve=y,this._running=!1,this._reversed=+Xt(o,x.reversed),this._reverse=this._reversed,this._cancelled=0,this._alternate=Xt(a,x.alternate),this._prev=null,this._next=null,this._elapsedTime=S,this._startTime=S,this._lastTime=S,this._fps=Xt(u,x.frameRate),this._speed=Xt(p,x.playbackRate)}get cancelled(){return!!this._cancelled}set cancelled(t){t?this.cancel():this.reset(1).play()}get currentTime(){return at(lt(this._currentTime,D.precision),-this._delay,this.duration)}set currentTime(t){const e=this.paused;this.pause().seek(+t),e||this.resume()}get iterationCurrentTime(){return lt(this._iterationTime,D.precision)}set iterationCurrentTime(t){this.currentTime=this.iterationDuration*this._currentIteration+t}get progress(){return at(lt(this._currentTime/this.duration,5),0,1)}set progress(t){this.currentTime=this.duration*t}get iterationProgress(){return at(lt(this._iterationTime/this.iterationDuration,5),0,1)}set iterationProgress(t){const e=this.iterationDuration;this.currentTime=e*this._currentIteration+e*t}get currentIteration(){return this._currentIteration}set currentIteration(t){this.currentTime=this.iterationDuration*at(+t,0,this.iterationCount-1)}get reversed(){return!!this._reversed}set reversed(t){t?this.reverse():this.play()}get speed(){return super.speed}set speed(t){super.speed=t,this.resetTime()}reset(t=0){return te(this),this._reversed&&!this._reverse&&(this.reversed=!1),this._iterationTime=this.iterationDuration,St(this,0,1,t,2),Kt(this),this._hasChildren&>(this,Kt),this}init(t=0){this.fps=this._fps,this.speed=this._speed,!t&&this._hasChildren&&St(this,this.duration,1,t,2),this.reset(t);const e=this._autoplay;return!0===e?this.resume():e&&!O(e.linked)&&e.link(this),this}resetTime(){const t=1/(this._speed*$t._speed);return this._startTime=F()-(this._currentTime+this._delay)*t,this}pause(){return this.paused||(this.paused=!0,this.onPause(this)),this}resume(){return this.paused?(this.paused=!1,this.duration<=d&&!this._hasChildren?St(this,d,0,0,2):(this._running||(yt($t,this),$t._hasChildren=!0,this._running=!0),this.resetTime(),this._startTime-=12,$t.wake()),this):this}restart(){return this.reset(0).resume()}seek(t,e=0,s=0){te(this),this.completed=!1;const i=this.paused;return this.paused=!0,St(this,t+this._delay,~~e,~~s,1),i?this:this.resume()}alternate(){const t=this._reversed,e=this.iterationCount,s=this.iterationDuration,i=e===1/0?et(u/s):e;return this._reversed=+(!this._alternate||i%2?!t:t),e===1/0?this.iterationProgress=this._reversed?1-this.iterationProgress:this.iterationProgress:this.seek(s*i-this._currentTime),this.resetTime(),this}play(){return this._reversed&&this.alternate(),this.resume()}reverse(){return this._reversed||this.alternate(),this.resume()}cancel(){return this._hasChildren?gt(this,(t=>t.cancel()),!0):gt(this,Jt),this._cancelled=1,this.pause()}stretch(t){const e=this.duration,s=pt(t);if(e===s)return this;const i=t/e,r=t<=d;return this.duration=r?d:s,this.iterationDuration=r?d:pt(this.iterationDuration*i),this._offset*=i,this._delay*=i,this._loopDelay*=i,this}revert(){St(this,0,1,0,1);const t=this._autoplay;return t&&t.linked&&t.linked===this&&t.revert(),this.cancel()}complete(){return this.seek(this.duration).cancel()}then(t=y){const e=this.then,s=()=>{this.then=null,t(this),this.then=e,this._resolve=y};return new Promise((t=>(this._resolve=()=>t(s()),this.completed&&this._resolve(),this)))}}const ie=t=>t,re=(t,e,s)=>(((1-3*s+3*e)*t+(3*s-6*e))*t+3*e)*t,ne=(t=.5,e=0,s=.5,i=1)=>t===e&&s===i?ie:r=>0===r||1===r?r:re(((t,e,s)=>{let i,r,n=0,o=1,a=0;do{r=n+(o-n)/2,i=re(r,e,s)-t,i>0?o=r:n=r}while(J(i)>1e-7&&++a<100);return r})(r,t,s),e,i),oe=(t=10,e)=>{const s=e?tt:et;return e=>s(at(e,0,1)*t)*(1/t)},ae=(...t)=>{const e=t.length;if(!e)return ie;const s=e-1,i=t[0],r=t[s],n=[0],o=[q(i)];for(let e=1;e{const s=[0],i=t-1;for(let t=1;te=>Q(e,+t),ue={[m]:de,Quad:de(2),Cubic:de(3),Quart:de(4),Quint:de(5),Sine:t=>1-Z(t*le),Circ:t=>1-j(1-t*t),Expo:t=>t?Q(2,10*t-10):0,Bounce:t=>{let e,s=4;for(;t<((e=Q(2,--s))-1)/11;);return 1/Q(4,3-s)-7.5625*Q((3*e-2)/22-t,2)},Back:(t=1.70158)=>e=>(+t+1)*e*e*e-+t*e*e,Elastic:(t=1,e=.3)=>{const s=at(+t,1,10),i=at(+e,d,2),r=i/ce*st(1/s),n=ce/i;return t=>0===t||1===t?t:-s*Q(2,-10*(1-t))*G((1-t-r)*n)}},pe={in:t=>e=>t(e),out:t=>e=>1-t(1-e),inOut:t=>e=>e<.5?t(2*e)/2:1-t(-2*e+2)/2,outIn:t=>e=>e<.5?(1-t(1-2*e))/2:(t(2*e-1)+1)/2},me=(t,e,s)=>{if(s[t])return s[t];if(t.indexOf("(")<=-1){const i=pe[t]||t.includes("Back")||t.includes("Elastic")?e[t]():e[t];return i?s[t]=i:ie}{const i=t.slice(0,-1).split("("),r=e[i[0]];return r?s[t]=r(...i[1].split(",")):ie}},fe=(()=>{const t={linear:ae,irregular:he,steps:oe,cubicBezier:ne};for(let e in pe)for(let s in ue){const i=ue[s],r=pe[e];t[e+s]=s===m||"Back"===s||"Elastic"===s?(t,e)=>r(i(t,e)):r(i)}return t})(),ge={linear:ie},_e=t=>M(t)?t:X(t)?me(t,fe,ge):ie,ye={},ve=(t,e,s)=>{if(3===s)return f.get(t)||t;if(2===s||1===s&&I(e)&&t in e.style){const e=ye[t];if(e)return e;{const e=t?A(t):t;return ye[t]=e,e}}return t},be={deg:1,rad:180/nt,turn:360},Se={},xe=(t,e,s,r=!1)=>{const n=e.u,o=e.n;if(1===e.t&&n===s)return e;const a=o+n+s,h=Se[a];if(O(h)||r){let r;if(n in be)r=o*be[n]/be[s];else{const e=100,a=t.cloneNode(),h=t.parentNode,l=h&&h!==i?h:i.body;l.appendChild(a);const c=a.style;c.width=e+n;const d=a.offsetWidth||e;c.width=e+s;const u=d/(a.offsetWidth||e);l.removeChild(a),r=u*o}e.n=r,Se[a]=r}else e.n=h;return e.t,e.u=s,e},Te=t=>{if(t._hasChildren)gt(t,Te,!0);else{const e=t;e.pause(),gt(e,(t=>{const s=t.property,i=t.target;if(i[o]){const r=i.style,n=e._inlineStyles[s];if(3===t._tweenType){const e=i[h];if(O(n)||n===m?delete e[s]:e[s]=n,t._renderTransforms)if(Object.keys(e).length){let t=m;for(let s in e)t+=_[s]+e[s]+") ";r.transform=t}else r.removeProperty("transform")}else O(n)||n===m?r.removeProperty(s):r[s]=n;e._tail===t&&e.targets.forEach((t=>{t.getAttribute&&t.getAttribute("style")===m&&t.removeAttribute("style")}))}}))}return t},we={t:0,n:0,u:null,o:null,d:null,s:null},ke={t:0,n:0,u:null,o:null,d:null,s:null},$e={func:null},Ee=[null],Ce=[null,null],Be={to:null};let De,Le,Ae=0;class Ne extends se{constructor(t,e,s,i,n=!1,o=0,a=0){super(e,s,i);const h=Lt(t),l=h.length,c=e.keyframes,u=c?ft(((t,e)=>{const s={};if(P(t)){const e=[].concat(...t.map((t=>Object.keys(t)))).filter(H);for(let i=0,r=e.length;i{const e={};for(let s in t){const i=t[s];H(s)?s===r&&(e.to=i):e[s]=i}return e}));s[r]=n}}else{const i=Xt(e.duration,D.defaults.duration),r=Object.keys(t).map((e=>({o:parseFloat(e)/100,p:t[e]}))).sort(((t,e)=>t.o-e.o));r.forEach((t=>{const e=t.o,r=t.p;for(let t in r)if(H(t)){let n=s[t];n||(n=s[t]=[]);const o=e*i;let a=n.length,h=n[a-1];const l={to:r[t]};let c=0;for(let t=0;t=p?r.none:O(v)?S.composition:v,L={},A=this._offset+(s?s._offset:0);let N=NaN,F=NaN,X=0,M=0;for(let t=0;t2&&e?(De=[],h.forEach(((t,e)=>{e?1===e?(Ce[1]=t,De.push(Ce)):De.push(t):Ce[0]=t}))):De=h}else Ee[0]=h,De=Ee;let f=null,g=null,_=NaN,y=0,v=0;for(let t=De.length;v1?Mt($,e,i,c)/t:$),e,i,c),x=Mt(Xt(Le.delay,v?0:E),e,i,c),T=Mt(Xt(Le.composition,B),e,i,c),w=Y(T)?T:r[T],D=Le.modifier||C,N=!O(u),F=!O(l),z=P(l),I=z||N&&F,W=g?y+x:x,V=A+W;M||!N&&!z||(M=1);let U=g;if(w!==r.none){f||(f=Qt(e,a));let t=f._head;for(;t&&!t._isOverridden&&t._absoluteStartTime<=V;)if(U=t,t=t._nextRep,t&&t._absoluteStartTime>=V)for(;t;)Gt(t),t=t._nextRep}if(I?(Vt(z?Mt(l[0],e,i,c):u,we),Vt(z?Mt(l[1],e,i,c,$e):l,ke),0===we.t&&(U?1===U._valueType&&(we.t=1,we.u=U._unit):(Vt(It(e,a,o,L),Ht),1===Ht.t&&(we.t=1,we.u=Ht.u)))):(F?Vt(l,ke):g?Ut(g,ke):Vt(s&&U&&U.parent.parent===s?U._value:It(e,a,o,L),ke),N?Vt(u,we):g?Ut(g,we):Vt(s&&U&&U.parent.parent===s?U._value:It(e,a,o,L),we)),we.o&&(we.n=Wt(U?U._toNumber:Vt(It(e,a,o,L),Ht).n,we.n,we.o)),ke.o&&(ke.n=Wt(we.n,ke.n,ke.o)),we.t!==ke.t)if(3===we.t||3===ke.t){const t=3===we.t?we:ke,e=3===we.t?ke:we;e.t=3,e.s=mt(t.s),e.d=t.d.map((()=>e.n))}else if(1===we.t||1===ke.t){const t=1===we.t?we:ke,e=1===we.t?ke:we;e.t=1,e.u=t.u}else if(2===we.t||2===ke.t){const t=2===we.t?we:ke,e=2===we.t?ke:we;e.t=2,e.s=t.s,e.d=[0,0,0,1]}if(we.u!==ke.u){let t=ke.u?we:ke;t=xe(e,t,ke.u?ke.u:we.u,!1)}if(ke.d&&we.d&&ke.d.length!==we.d.length){const t=we.d.length>ke.d.length?we:ke,e=t===we?ke:we;e.d=t.d.map(((t,s)=>O(e.d[s])?0:e.d[s])),e.s=mt(t.s)}const H=lt(+S||d,12),q={parent:this,id:Ae++,property:a,target:e,_value:null,_func:$e.func,_ease:_e(b),_fromNumbers:mt(we.d),_toNumbers:mt(ke.d),_strings:mt(ke.s),_fromNumber:we.n,_toNumber:ke.n,_numbers:mt(we.d),_number:we.n,_unit:ke.u,_modifier:D,_currentTime:0,_startTime:W,_delay:+x,_updateDuration:H,_changeDuration:H,_absoluteStartTime:V,_tweenType:o,_valueType:ke.t,_composition:w,_isOverlapped:0,_isOverridden:0,_renderTransforms:0,_prevRep:null,_nextRep:null,_prevAdd:null,_nextAdd:null,_prev:null,_next:null};w!==r.none&&Zt(q,f),isNaN(_)&&(_=q._startTime),y=lt(W+H,12),g=q,X++,yt(this,q)}(isNaN(F)||_N)&&(N=y),3===o&&(p=X-v,m=X)}if(!isNaN(p)){let t=0;gt(this,(e=>{t>=p&&t{t.id===e.id&&(t._renderTransforms=1)}))),t++}))}}l||console.warn("No target found. Make sure the element you're trying to animate is accessible before creating your animation."),F?(gt(this,(t=>{t._startTime-t._delay||(t._delay-=F),t._startTime-=F})),N-=F):F=0,N||(N=d,this.iterationCount=0),this.targets=h,this.duration=N===d?d:ut((N+this._loopDelay)*this.iterationCount-this._loopDelay)||d,this.onRender=b||S.onRender,this._ease=T,this._delay=F,this.iterationDuration=N,this._inlineStyles=L,!this._autoplay&&M&&this.onRender(this)}stretch(t){const e=this.duration;if(e===pt(t))return this;const s=t/e;return gt(this,(t=>{t._updateDuration=pt(t._updateDuration*s),t._changeDuration=pt(t._changeDuration*s),t._currentTime*=s,t._startTime*=s,t._absoluteStartTime*=s})),super.stretch(t)}refresh(){return gt(this,(t=>{const e=It(t.target,t.property,t._tweenType);Vt(e,Ht),t._fromNumbers=mt(Ht.d),t._fromNumber=Ht.n,t._func&&(Vt(t._func(),ke),t._toNumbers=mt(ke.d),t._strings=mt(ke.s),t._toNumber=ke.n)})),this}revert(){return super.revert(),Te(this)}then(t){return super.then(t)}}const Fe=(t,e=100)=>{const s=[];for(let i=0;i<=e;i++)s.push(t(i/e));return`linear(${s.join(", ")})`},Pe={in:"ease-in",out:"ease-out",inOut:"ease-in-out"},Re=(()=>{const t={};for(let e in pe)t[e]=t=>pe[e](de(t));return t})(),Ye=t=>{let e=Pe[t];if(e)return e;if(e="linear",X(t)){if(N(t,"linear")||N(t,"cubic-")||N(t,"steps")||N(t,"ease"))e=t;else if(N(t,"cubicB"))e=A(t);else{const s=me(t,Re,Pe);M(s)&&(e=s===ie?"linear":Fe(s))}Pe[t]=e}else if(M(t)){const s=Fe(t);s&&(e=s)}else t.ease&&(e=Fe(t.ease));return e},Xe=["x","y","z"],Me=["perspective","width","height","margin","padding","top","right","bottom","left","borderWidth","fontSize","borderRadius",...Xe],Oe=[...Xe,...g.filter((t=>["X","Y","Z"].some((e=>t.endsWith(e)))))];let ze=e&&(O(CSS)||!Object.hasOwnProperty.call(CSS,"registerProperty"));const Ie={_head:null,_tail:null},We=(t,e,s)=>{let i=Ie._head;for(;i;){const r=i._next,n=i.$el===t,o=!e||i.property===e,a=!s||i.parent===s;if(n&&o&&a){const t=i.animation;try{t.commitStyles()}catch{}t.cancel(),_t(Ie,i);const e=i.parent;e&&(e._completed++,e.animations.length===e._completed&&(e.completed=!0,e.muteCallbacks||(e.paused=!0,e.onComplete(e),e._resolve(e))))}i=r}},Ve=(t,e,s,i,r)=>{const n=e.animate(i,r),o=r.delay+ +r.duration*r.iterations;n.playbackRate=t._speed,t.paused&&n.pause(),t.duration{We(e,s,t)};return n.onremove=a,n.onfinish=a,n},Ue=(t,e,s,i,r)=>{let n=Mt(e,s,i,r);return Y(n)?Me.includes(t)||N(t,"translate")?`${n}px`:N(t,"rotate")||N(t,"skew")?`${n}deg`:`${n}`:n},He=(t,e,s,i,r,n)=>{let o="0";const a=O(i)?getComputedStyle(t)[e]:Ue(e,i,t,r,n);return o=O(s)?P(i)?i.map((s=>Ue(e,s,t,r,n))):a:[Ue(e,s,t,r,n),a],o};class qe{constructor(t,e){D.scope&&D.scope.revertibles.push(this),ze||(g.forEach((t=>{const e=N(t,"skew"),s=N(t,"scale"),i=N(t,"rotate"),r=N(t,"translate"),n=i||e,o=n?"":s?"":r?"":"*";try{CSS.registerProperty({name:"--"+t,syntax:o,inherits:!1,initialValue:r?"0px":n?"0deg":s?"1":"0"})}catch{}})),ze=!0);const s=Lt(t),i=s.length;i||console.warn("No target found. Make sure the element you're trying to animate is accessible before creating your animation.");const r=Xt(e.ease,Ye(D.defaults.ease)),n=r.ease&&r,o=Xt(e.autoplay,D.defaults.autoplay),a=!(!o||!o.link)&&o,l=e.alternate&&!0===e.alternate,c=e.reversed&&!0===e.reversed,d=Xt(e.loop,D.defaults.loop),u=!0===d||d===1/0?1/0:Y(d)?d+1:1,v=l?c?"alternate-reverse":"alternate":c?"reverse":"normal",b=Ye(r),S=1===D.timeScale?1:p;this.targets=s,this.animations=[],this.controlAnimation=null,this.onComplete=e.onComplete||y,this.duration=0,this.muteCallbacks=!1,this.completed=!1,this.paused=!o||!1!==a,this.reversed=c,this.autoplay=o,this._speed=Xt(e.playbackRate,D.defaults.playbackRate),this._resolve=y,this._completed=0,this._inlineStyles=s.map((t=>t.getAttribute("style"))),s.forEach(((t,s)=>{const o=t[h],a=Oe.some((t=>e.hasOwnProperty(t))),l=(n?n.duration:Mt(Xt(e.duration,D.defaults.duration),t,s,i))*S,c=Mt(Xt(e.delay,D.defaults.delay),t,s,i)*S,d=Xt(e.composition,"replace");for(let n in e){if(!H(n))continue;const h={},p={iterations:u,direction:v,fill:"forwards",easing:b,duration:l,delay:c,composite:d},m=e[n],_=!!a&&(g.includes(n)?n:f.get(n));let y;if(R(m)){const e=m,a=Xt(e.ease,r),u=a.ease&&a,f=e.to,g=e.from;if(p.duration=(u?u.duration:Mt(Xt(e.duration,l),t,s,i))*S,p.delay=Mt(Xt(e.delay,c),t,s,i)*S,p.composite=Xt(e.composition,d),p.easing=Ye(a),y=He(t,n,g,f,s,i),_?(h[`--${_}`]=y,o[_]=y):h[n]=He(t,n,g,f,s,i),Ve(this,t,n,h,p),!O(g))if(_){const e=`--${_}`;t.style.setProperty(e,h[e][0])}else t.style[n]=h[n][0]}else y=P(m)?m.map((e=>Ue(n,e,t,s,i))):Ue(n,m,t,s,i),_?(h[`--${_}`]=y,o[_]=y):h[n]=y,Ve(this,t,n,h,p)}if(a){let e=m;for(let t in o)e+=`${_[t]}var(--${t})) `;t.style.transform=e}})),a&&this.autoplay.link(this)}forEach(t){const e=X(t)?e=>e[t]():t;return this.animations.forEach(e),this}get speed(){return this._speed}set speed(t){this._speed=+t,this.forEach((e=>e.playbackRate=t))}get currentTime(){const t=this.controlAnimation,e=D.timeScale;return this.completed?this.duration:t?+t.currentTime*(1===e?1:e):0}set currentTime(t){const e=t*(1===D.timeScale?1:p);this.forEach((t=>{e>=this.duration&&t.play(),t.currentTime=e}))}get progress(){return this.currentTime/this.duration}set progress(t){this.forEach((e=>e.currentTime=t*this.duration||0))}resume(){return this.paused?(this.paused=!1,this.forEach("play")):this}pause(){return this.paused?this:(this.paused=!0,this.forEach("pause"))}alternate(){return this.reversed=!this.reversed,this.forEach("reverse"),this.paused&&this.forEach("pause"),this}play(){return this.reversed&&this.alternate(),this.resume()}reverse(){return this.reversed||this.alternate(),this.resume()}seek(t,e=!1){return e&&(this.muteCallbacks=!0),tt.setAttribute("style",this._inlineStyles[e]))),this}then(t=y){const e=this.then,s=()=>{this.then=null,t(this),this.then=e,this._resolve=y};return new Promise((t=>(this._resolve=()=>t(s()),this.completed&&this._resolve(),this)))}}const Qe={animate:(t,e)=>new qe(t,e),convertEase:Fe},je=(t=y)=>new se({duration:1*D.timeScale,onComplete:t},null,0).resume();function Ge(t,e,s){const i=Lt(t);if(!i.length)return;const[r]=i,n=Ot(r,e),o=ve(e,r,n);let a=It(r,o);if(O(s))return a;if(Vt(a,Ht),0===Ht.t||1===Ht.t){if(!1===s)return Ht.n;{const t=xe(r,Ht,s,!1);return`${lt(t.n,D.precision)}${t.u}`}}}const Ze=(t,e)=>{if(!O(e))return e.duration=d,e.composition=Xt(e.composition,r.none),new Ne(t,e,null,0,!0).resume()},Je=(t,e,s)=>{let i=!1;return gt(e,(r=>{const n=r.target;if(t.includes(n)){const t=r.property,o=r._tweenType,a=ve(s,n,o);(!a||a&&a===t)&&(r.parent._tail===r&&3===r._tweenType&&r._prev&&3===r._prev._tweenType&&(r._prev._renderTransforms=1),_t(e,r),Jt(r),i=!0)}}),!0),i},Ke=(t,e,s)=>{const i=Dt(t),r=e||$t,n=e&&e.controlAnimation&&e;for(let t=0,e=i.length;t{if(!n._hasChildren)if(o=Je(i,n,s),o&&!n._head)n.cancel(),_t(r,n);else{const t=n._offset+n._delay+n.duration;t>e&&(e=t)}n._head?Ke(t,n,s):n._hasChildren=!1}),!0),O(r.iterationDuration)||(r.iterationDuration=e)}else o=Je(i,r,s);return o&&!r._head&&(r._hasChildren=!1,r.cancel&&r.cancel()),i},ts=(t,e,s)=>{const i=10**(s||0);return et((Math.random()*(e-t+1/i)+t)*i)/i},es=(t,e,s,i,r)=>i+(t-e)/(s-e)*(r-i),ss=(t,e,s,i)=>{let r=p/D.defaults.frameRate;if(!1!==i){const t=i||$t._hasChildren&&$t;t&&t.deltaTime&&(r=t.deltaTime)}const n=1-Math.exp(-s*r*.1);return s?1===s?e:(1-n)*t+n*e:t},is=t=>(...e)=>{const s=t(...e);return new Proxy(y,{apply:(t,e,[i])=>s(i),get:(t,e)=>is(((...t)=>{const i=ns[e](...t);return t=>i(s(t))}))})},rs=(t,e=0)=>(...s)=>(s.length(...s)=>e?e=>t(...s,e):e=>t(e,...s))(t,e)):t)(...s),ns={$:Lt,get:Ge,set:Ze,remove:Ke,cleanInlineStyles:Te,random:ts,randomPick:t=>t[ts(0,t.length-1)],shuffle:t=>{let e,s,i=t.length;for(;i;)s=ts(0,--i),e=t[i],t[i]=t[s],t[s]=e;return t},lerp:ss,sync:je,clamp:rs(at),round:rs(lt),snap:rs(ct),wrap:rs(((t,e,s)=>((t-e)%(s-e)+(s-e))%(s-e)+e)),interpolate:rs(dt,1),mapRange:rs(es),roundPad:rs(((t,e)=>(+t).toFixed(e))),padStart:rs(((t,e,s)=>`${t}`.padStart(e,s))),padEnd:rs(((t,e,s)=>`${t}`.padEnd(e,s))),degToRad:rs((t=>t*nt/180)),radToDeg:rs((t=>180*t/nt))},os=(t,e)=>{let s=t.iterationDuration;if(s===d&&(s=0),O(e))return s;if(Y(+e))return+e;const i=e,r=t?t.labels:null,n=!z(r),o=((t,e)=>{if(N(e,"<")){const s="<"===e[1],i=t._tail,r=i?i._offset+i._delay:0;return s?r:r+i.duration}})(t,i),a=!O(o),h=C.exec(i);if(h){const t=h[0],e=i.split(t),l=n&&e[0]?r[e[0]]:s,c=a?o:n?l:s,d=+e[1];return Wt(c,d,t[0])}return a?o:n?O(r[i])?s:r[i]:s};function as(t,e,s,i,r,n){const o=Y(t.duration)&&t.duration<=d?s-d:s;St(e,o,1,1,1);const a=i?new Ne(i,t,e,o,!1,r,n):new se(t,e,o);return a.init(1),yt(e,a),gt(e,(t=>{const s=t._offset+t._delay+t.duration;s>e.iterationDuration&&(e.iterationDuration=s)})),e.duration=function(t){return ut((t.iterationDuration+t._loopDelay)*t.iterationCount-t._loopDelay)||d}(e),e}class hs extends se{constructor(t={}){super(t,null,0),this.duration=0,this.labels={};const e=t.defaults,s=D.defaults;this.defaults=e?ft(e,s):s,this.onRender=t.onRender||s.onRender;const i=Xt(t.playbackEase,s.playbackEase);this._ease=i?_e(i):null,this.iterationDuration=0}add(t,e,s){const i=R(e),r=R(t);if(i||r){if(this._hasChildren=!0,i){const i=e;if(M(s)){const e=s,r=Dt(t),n=this.duration,o=this.iterationDuration,a=i.id;let h=0;const l=r.length;r.forEach((t=>{const s={...i};this.duration=n,this.iterationDuration=o,O(a)||(s.id=a+"-"+h),as(s,this,e(t,h,l,this),t,h,l),h++}))}else as(i,this,os(this,s),t)}else as(t,this,os(this,e));return this.init(1)}}sync(t,e){if(O(t)||t&&O(t.pause))return this;t.pause();const s=+(t.effect?t.effect.getTiming().duration:t.duration);return this.add(t,{currentTime:[0,s],duration:s,ease:"linear"},e)}set(t,e,s){return O(e)?this:(e.duration=d,e.composition=r.replace,this.add(t,e,s))}call(t,e){return O(t)||t&&!M(t)?this:this.add({duration:0,onComplete:()=>t(this)},e)}label(t,e){return O(t)||t&&!X(t)||(this.labels[t]=os(this,e)),this}remove(t,e){return Ke(t,this,e),this}stretch(t){const e=this.duration;if(e===pt(t))return this;const s=t/e,i=this.labels;gt(this,(t=>t.stretch(t.duration*s)));for(let t in i)i[t]*=s;return super.stretch(t)}refresh(){return gt(this,(t=>{t.refresh&&t.refresh()})),this}revert(){return super.revert(),gt(this,(t=>t.revert),!0),Te(this)}then(t){return super.then(t)}}class ls{constructor(t,e){D.scope&&D.scope.revertibles.push(this);const s={},i={};if(this.targets=[],this.animations={},!O(t)&&!O(e)){for(let t in e){const r=e[t];H(t)?i[t]=r:s[t]=r}for(let e in i){const n=i[e],o=R(n);let a={},h="+=0";if(o){const t=n.unit;X(t)&&(h+=t)}else a.duration=n;a[e]=o?ft({to:h},n):h;const l=ft(s,a);l.composition=r.replace,l.autoplay=!1;const c=this.animations[e]=new Ne(t,l,null,0,!1).init();this.targets.length||this.targets.push(...c.targets),this[e]=(t,e,s)=>{const i=c._head;if(O(t)&&i){const t=i._numbers;return t&&t.length?t:i._modifier(i._number)}return gt(c,(e=>{if(P(t))for(let s=0,i=t.length;s0===t||1===t?t:this.solve(t*this.solverDuration)}solve(t){const{zeta:e,w0:s,wd:i,b:r}=this;let n=t;return n=e<1?K(-n*e*s)*(1*Z(i*n)+r*G(i*n)):(1+r*n)*K(-n*s),1-n}compute(){const{maxRestSteps:t,maxIterations:e,restThreshold:s,timeStep:i,m:r,d:n,s:o,v:a}=this,h=this.w0=at(j(o/r),d,p),l=this.zeta=n/(2*j(o*r)),c=this.wd=l<1?h*j(1-l*l):0;this.b=l<1?(l*h-a)/c:-a+h;let u=0,m=0,f=0;for(;mnew cs(t),us=t=>{t.cancelable&&t.preventDefault()};class ps{constructor(t){this.el=t,this.zIndex=0,this.parentElement=null,this.classList={add:y,remove:y}}get x(){return this.el.x||0}set x(t){this.el.x=t}get y(){return this.el.y||0}set y(t){this.el.y=t}get width(){return this.el.width||0}set width(t){this.el.width=t}get height(){return this.el.height||0}set height(t){this.el.height=t}getBoundingClientRect(){return{top:this.y,right:this.x,bottom:this.y+this.height,left:this.x+this.width}}}class ms{constructor(t){this.$el=t,this.inlineTransforms=[],this.point=new DOMPoint,this.inversedMatrix=this.getMatrix().inverse()}normalizePoint(t,e){return this.point.x=t,this.point.y=e,this.point.matrixTransform(this.inversedMatrix)}traverseUp(t){let e=this.$el.parentElement,s=0;for(;e&&e!==i;)t(e,s),e=e.parentElement,s++}getMatrix(){const t=new DOMMatrix;return this.traverseUp((e=>{const s=getComputedStyle(e).transform;if(s){const e=new DOMMatrix(s);t.preMultiplySelf(e)}})),t}remove(){this.traverseUp(((t,e)=>{this.inlineTransforms[e]=t.style.transform,t.style.transform="none"}))}revert(){this.traverseUp(((t,e)=>{const s=this.inlineTransforms[e];""===s?t.style.removeProperty("transform"):t.style.transform=s}))}}const fs=(t,e)=>t&&M(t)?t(e):t;let gs=0;class _s{constructor(t,e={}){if(!t)return;D.scope&&D.scope.revertibles.push(this);const r=e.x,n=e.y,o=e.trigger,a=e.modifier,h=e.releaseEase,l=h&&_e(h),c=!O(h)&&!O(h.ease),d=R(r)&&!O(r.mapTo)?r.mapTo:"translateX",p=R(n)&&!O(n.mapTo)?n.mapTo:"translateY",m=fs(e.container,this);this.containerArray=P(m)?m:null,this.$container=m&&!this.containerArray?Dt(m)[0]:i.body,this.useWin=this.$container===i.body,this.$scrollContainer=this.useWin?s:this.$container,this.$target=R(t)?new ps(t):Dt(t)[0],this.$trigger=Dt(o||t)[0],this.fixed="fixed"===Ge(this.$target,"position"),this.isFinePointer=!0,this.containerPadding=[0,0,0,0],this.containerFriction=0,this.releaseContainerFriction=0,this.snapX=0,this.snapY=0,this.scrollSpeed=0,this.scrollThreshold=0,this.dragSpeed=0,this.maxVelocity=0,this.minVelocity=0,this.velocityMultiplier=0,this.cursor=!1,this.releaseXSpring=c?h:ds({mass:Xt(e.releaseMass,1),stiffness:Xt(e.releaseStiffness,80),damping:Xt(e.releaseDamping,20)}),this.releaseYSpring=c?h:ds({mass:Xt(e.releaseMass,1),stiffness:Xt(e.releaseStiffness,80),damping:Xt(e.releaseDamping,20)}),this.releaseEase=l||fe.outQuint,this.hasReleaseSpring=c,this.onGrab=e.onGrab||y,this.onDrag=e.onDrag||y,this.onRelease=e.onRelease||y,this.onUpdate=e.onUpdate||y,this.onSettle=e.onSettle||y,this.onSnap=e.onSnap||y,this.onResize=e.onResize||y,this.onAfterResize=e.onAfterResize||y,this.disabled=[0,0];const f={};if(a&&(f.modifier=a),O(r)||!0===r)f[d]=0;else if(R(r)){const t=r,e={};t.modifier&&(e.modifier=t.modifier),t.composition&&(e.composition=t.composition),f[d]=e}else!1===r&&(f[d]=0,this.disabled[0]=1);if(O(n)||!0===n)f[p]=0;else if(R(n)){const t=n,e={};t.modifier&&(e.modifier=t.modifier),t.composition&&(e.composition=t.composition),f[p]=e}else!1===n&&(f[p]=0,this.disabled[1]=1);this.animate=new ls(this.$target,f),this.xProp=d,this.yProp=p,this.destX=0,this.destY=0,this.deltaX=0,this.deltaY=0,this.scroll={x:0,y:0},this.coords=[this.x,this.y,0,0],this.snapped=[0,0],this.pointer=[0,0,0,0,0,0,0,0],this.scrollView=[0,0],this.dragArea=[0,0,0,0],this.containerBounds=[-1e12,u,u,-1e12],this.scrollBounds=[0,0,0,0],this.targetBounds=[0,0,0,0],this.window=[0,0],this.velocityStack=[0,0,0],this.velocityStackIndex=0,this.velocityTime=F(),this.velocity=0,this.angle=0,this.cursorStyles=null,this.triggerStyles=null,this.bodyStyles=null,this.targetStyles=null,this.touchActionStyles=null,this.transforms=new ms(this.$target),this.overshootCoords={x:0,y:0},this.overshootXTicker=new se({autoplay:!1},null,0).init(),this.overshootYTicker=new se({autoplay:!1},null,0).init(),this.updateTicker=new se({autoplay:!1},null,0).init(),this.overshootXTicker.onUpdate=()=>{this.disabled[0]||(this.updated=!0,this.manual=!0,this.animate[this.xProp](this.overshootCoords.x,0))},this.overshootXTicker.onComplete=()=>{this.disabled[0]||(this.manual=!1,this.animate[this.xProp](this.overshootCoords.x,0))},this.overshootYTicker.onUpdate=()=>{this.disabled[1]||(this.updated=!0,this.manual=!0,this.animate[this.yProp](this.overshootCoords.y,0))},this.overshootYTicker.onComplete=()=>{this.disabled[1]||(this.manual=!1,this.animate[this.yProp](this.overshootCoords.y,0))},this.updateTicker.onUpdate=()=>this.update(),this.contained=!O(m),this.manual=!1,this.grabbed=!1,this.dragged=!1,this.updated=!1,this.released=!1,this.canScroll=!1,this.enabled=!1,this.initialized=!1,this.activeProp=this.disabled[1]?d:p,this.animate.animations[this.activeProp].onRender=()=>{const t=this.updated,e=!(this.grabbed&&t)&&this.released,s=this.x,i=this.y,r=s-this.coords[2],n=i-this.coords[3];this.deltaX=r,this.deltaY=n,this.coords[2]=s,this.coords[3]=i,t&&this.onUpdate(this),e?(this.computeVelocity(r,n),this.angle=rt(n,r)):this.updated=!1},this.animate.animations[this.activeProp].onComplete=()=>{!this.grabbed&&this.released&&(this.released=!1),this.manual||(this.deltaX=0,this.deltaY=0,this.velocity=0,this.velocityStack[0]=0,this.velocityStack[1]=0,this.velocityStack[2]=0,this.velocityStackIndex=0,this.onSettle(this))},this.resizeTicker=new se({autoplay:!1,duration:150*D.timeScale,onComplete:()=>{this.onResize(this),this.refresh(),this.onAfterResize(this)}}).init(),this.parameters=e,this.resizeObserver=new ResizeObserver((()=>{this.initialized?this.resizeTicker.restart():this.initialized=!0})),this.enable(),this.refresh(),this.resizeObserver.observe(this.$container),R(t)||this.resizeObserver.observe(this.$target)}computeVelocity(t,e){const s=this.velocityTime,i=F(),r=i-s;if(r<17)return this.velocity;this.velocityTime=i;const n=this.velocityStack,o=this.velocityMultiplier,a=this.minVelocity,h=this.maxVelocity,l=this.velocityStackIndex;n[l]=lt(at(j(t*t+e*e)/r*o,a,h),5);const c=it(n[0],n[1],n[2]);return this.velocity=c,this.velocityStackIndex=(l+1)%3,c}setX(t,e=!1){if(this.disabled[0])return;const s=lt(t,5);return this.overshootXTicker.pause(),this.manual=!0,this.updated=!e,this.destX=s,this.snapped[0]=ct(s,this.snapX),this.animate[this.xProp](s,0),this.manual=!1,this}setY(t,e=!1){if(this.disabled[1])return;const s=lt(t,5);return this.overshootYTicker.pause(),this.manual=!0,this.updated=!e,this.destY=s,this.snapped[1]=ct(s,this.snapY),this.animate[this.yProp](s,0),this.manual=!1,this}get x(){return lt(this.animate[this.xProp](),D.precision)}set x(t){this.setX(t,!1)}get y(){return lt(this.animate[this.yProp](),D.precision)}set y(t){this.setY(t,!1)}get progressX(){return es(this.x,this.containerBounds[3],this.containerBounds[1],0,1)}set progressX(t){this.setX(es(t,0,1,this.containerBounds[3],this.containerBounds[1]),!1)}get progressY(){return es(this.y,this.containerBounds[0],this.containerBounds[2],0,1)}set progressY(t){this.setY(es(t,0,1,this.containerBounds[0],this.containerBounds[2]),!1)}updateScrollCoords(){const t=lt(this.useWin?s.scrollX:this.$container.scrollLeft,0),e=lt(this.useWin?s.scrollY:this.$container.scrollTop,0),[i,r,n,o]=this.containerPadding,a=this.scrollThreshold;this.scroll.x=t,this.scroll.y=e,this.scrollBounds[0]=e-this.targetBounds[0]+i-a,this.scrollBounds[1]=t-this.targetBounds[1]-r+a,this.scrollBounds[2]=e-this.targetBounds[2]-n+a,this.scrollBounds[3]=t-this.targetBounds[3]+o-a}updateBoundingValues(){const t=this.$container,e=this.x,r=this.y,n=this.coords[2],o=this.coords[3];this.coords[2]=0,this.coords[3]=0,this.setX(0,!0),this.setY(0,!0),this.transforms.remove();const a=this.window[0]=s.innerWidth,h=this.window[1]=s.innerHeight,l=this.useWin,c=t.scrollWidth,d=t.scrollHeight,u=this.fixed,p=t.getBoundingClientRect(),[m,f,g,_]=this.containerPadding;this.dragArea[0]=l?0:p.left,this.dragArea[1]=l?0:p.top,this.scrollView[0]=l?at(c,a,c):c,this.scrollView[1]=l?at(d,h,d):d,this.updateScrollCoords();const{width:y,height:v,left:b,top:S,right:x,bottom:T}=t.getBoundingClientRect();this.dragArea[2]=lt(l?at(y,a,a):y,0),this.dragArea[3]=lt(l?at(v,h,h):v,0);const w=Ge(t,"overflow"),k="visible"===w,$="hidden"===w;if(this.canScroll=!u&&this.contained&&(t===i.body&&k||!$&&!k)&&(c>this.dragArea[2]+_-f||d>this.dragArea[3]+m-g)&&(!this.containerArray||this.containerArray&&!P(this.containerArray)),this.contained){const e=this.scroll.x,s=this.scroll.y,i=this.canScroll,r=this.$target.getBoundingClientRect(),n=i?l?0:t.scrollLeft:0,o=i?l?0:t.scrollTop:0,c=i?this.scrollView[0]-n-y:0,d=i?this.scrollView[1]-o-v:0;this.targetBounds[0]=lt(r.top+s-(l?0:S),0),this.targetBounds[1]=lt(r.right+e-(l?a:x),0),this.targetBounds[2]=lt(r.bottom+s-(l?h:T),0),this.targetBounds[3]=lt(r.left+e-(l?0:b),0),this.containerArray?(this.containerBounds[0]=this.containerArray[0]+m,this.containerBounds[1]=this.containerArray[1]-f,this.containerBounds[2]=this.containerArray[2]-g,this.containerBounds[3]=this.containerArray[3]+_):(this.containerBounds[0]=-lt(r.top-(u?at(S,0,h):S)+o-m,0),this.containerBounds[1]=-lt(r.right-(u?at(x,0,a):x)-c+f,0),this.containerBounds[2]=-lt(r.bottom-(u?at(T,0,h):T)-d+g,0),this.containerBounds[3]=-lt(r.left-(u?at(b,0,a):b)+n-_,0))}this.transforms.revert(),this.coords[2]=n,this.coords[3]=o,this.setX(e,!0),this.setY(r,!0)}isOutOfBounds(t,e,s){if(!this.contained)return 0;const[i,r,n,o]=t,[a,h]=this.disabled,l=!a&&er,c=!h&&sn;return l&&!c?1:!l&&c?2:l&&c?3:0}refresh(){const t=this.parameters,e=t.x,r=t.y,n=fs(t.container,this),o=fs(t.containerPadding,this)||0,a=P(o)?o:[o,o,o,o],h=this.x,l=this.y,c=fs(t.cursor,this),d={onHover:"grab",onGrab:"grabbing"};if(c){const{onHover:t,onGrab:e}=c;t&&(d.onHover=t),e&&(d.onGrab=e)}this.containerArray=P(n)?n:null,this.$container=n&&!this.containerArray?Dt(n)[0]:i.body,this.useWin=this.$container===i.body,this.$scrollContainer=this.useWin?s:this.$container,this.isFinePointer=matchMedia("(pointer:fine)").matches,this.containerPadding=Xt(a,[0,0,0,0]),this.containerFriction=at(Xt(fs(t.containerFriction,this),.8),0,1),this.releaseContainerFriction=at(Xt(fs(t.releaseContainerFriction,this),this.containerFriction),0,1),this.snapX=fs(R(e)&&!O(e.snap)?e.snap:t.snap,this),this.snapY=fs(R(r)&&!O(r.snap)?r.snap:t.snap,this),this.scrollSpeed=Xt(fs(t.scrollSpeed,this),1.5),this.scrollThreshold=Xt(fs(t.scrollThreshold,this),20),this.dragSpeed=Xt(fs(t.dragSpeed,this),1),this.minVelocity=Xt(fs(t.minVelocity,this),0),this.maxVelocity=Xt(fs(t.maxVelocity,this),50),this.velocityMultiplier=Xt(fs(t.velocityMultiplier,this),1),this.cursor=!1!==c&&d,this.updateBoundingValues();const[u,p,m,f]=this.containerBounds;this.setX(at(h,f,p),!0),this.setY(at(l,u,m),!0)}update(){if(this.updateScrollCoords(),this.canScroll){const[t,e,s,i]=this.containerPadding,[r,n]=this.scrollView,o=this.dragArea[2],a=this.dragArea[3],h=this.scroll.x,l=this.scroll.y,c=this.$container.scrollWidth,d=this.$container.scrollHeight,u=this.useWin?at(c,this.window[0],c):c,p=this.useWin?at(d,this.window[1],d):d,m=r-u,f=n-p;this.dragged&&m>0&&(this.coords[0]-=m,this.scrollView[0]=u),this.dragged&&f>0&&(this.coords[1]-=f,this.scrollView[1]=p);const g=10*this.scrollSpeed,_=this.scrollThreshold,[y,v]=this.coords,[b,S,x,T]=this.scrollBounds,w=lt(at((v-b+t)/_,-1,0)*g,0),k=lt(at((y-S-e)/_,0,1)*g,0),$=lt(at((v-x-s)/_,0,1)*g,0),E=lt(at((y-T+i)/_,-1,0)*g,0);if(w||$||E||k){const[t,e]=this.disabled;let s=h,i=l;t||(s=lt(at(h+(E||k),0,r-o),0),this.coords[0]-=h-s),e||(i=lt(at(l+(w||$),0,n-a),0),this.coords[1]-=l-i),this.useWin?this.$scrollContainer.scrollBy(-(h-s),-(l-i)):this.$scrollContainer.scrollTo(s,i)}}const[t,e,s,i]=this.containerBounds,[r,n,o,a,h,l]=this.pointer;this.coords[0]+=(r-h)*this.dragSpeed,this.coords[1]+=(n-l)*this.dragSpeed,this.pointer[4]=r,this.pointer[5]=n;const[c,d]=this.coords,[u,p]=this.snapped,m=(1-this.containerFriction)*this.dragSpeed;this.setX(c>e?e+(c-e)*m:cs?s+(d-s)*m:d{this.canScroll=!1,this.$scrollContainer.scrollTo(n.x,n.y)}}).init().then((()=>{this.canScroll=a}))}return this}handleHover(){this.isFinePointer&&this.cursor&&!this.cursorStyles&&(this.cursorStyles=Ze(this.$trigger,{cursor:this.cursor.onHover}))}animateInView(t,e=0,s=fe.inOutQuad){this.stop(),this.updateBoundingValues();const i=this.x,r=this.y,[n,o,a,h]=this.containerPadding,l=this.scroll.y-this.targetBounds[0]+n+e,c=this.scroll.x-this.targetBounds[1]-o-e,d=this.scroll.y-this.targetBounds[2]-a-e,u=this.scroll.x-this.targetBounds[3]+h+e,p=this.isOutOfBounds([l,c,d,u],i,r);if(p){const[e,n]=this.disabled,o=at(ct(i,this.snapX),u,c),a=at(ct(r,this.snapY),l,d),h=O(t)?350*D.timeScale:t;e||1!==p&&3!==p||this.animate[this.xProp](o,h,s),n||2!==p&&3!==p||this.animate[this.yProp](a,h,s)}return this}handleDown(t){const e=t.target;if(this.grabbed||"range"===e.type)return;t.stopPropagation(),this.grabbed=!0,this.released=!1,this.stop(),this.updateBoundingValues();const s=t.changedTouches,r=s?s[0].clientX:t.clientX,n=s?s[0].clientY:t.clientY,{x:o,y:a}=this.transforms.normalizePoint(r,n),[h,l,c,d]=this.containerBounds,u=(1-this.containerFriction)*this.dragSpeed,p=this.x,m=this.y;this.coords[0]=this.coords[2]=u?p>l?l+(p-l)/u:pc?c+(m-c)/u:mgs?f:gs)+1,this.targetStyles=Ze(this.$target,{zIndex:gs}),this.triggerStyles&&(this.triggerStyles.revert(),this.triggerStyles=null),this.cursorStyles&&(this.cursorStyles.revert(),this.cursorStyles=null),this.isFinePointer&&this.cursor&&(this.bodyStyles=Ze(i.body,{cursor:this.cursor.onGrab})),this.scrollInView(100,0,fe.out(3)),this.onGrab(this),i.addEventListener("touchmove",this),i.addEventListener("touchend",this),i.addEventListener("touchcancel",this),i.addEventListener("mousemove",this),i.addEventListener("mouseup",this),i.addEventListener("selectstart",this)}handleMove(t){if(!this.grabbed)return;const e=t.changedTouches,s=e?e[0].clientX:t.clientX,i=e?e[0].clientY:t.clientY,{x:r,y:n}=this.transforms.normalizePoint(s,i),o=r-this.pointer[6],a=n-this.pointer[7];let h=t.target,l=!1,c=!1,d=!1;for(;e&&h&&h!==this.$trigger;){const t=Ge(h,"overflow-y");if("hidden"!==t&&"visible"!==t){const{scrollTop:t,scrollHeight:e,clientHeight:s}=h;if(e>s){d=!0,l=t<=3,c=t>=e-s-3;break}}h=h.parentNode}d&&(!l&&!c||l&&a<0||c&&a>0)?(this.pointer[0]=r,this.pointer[1]=n,this.pointer[2]=r,this.pointer[3]=n,this.pointer[4]=r,this.pointer[5]=n,this.pointer[6]=r,this.pointer[7]=n):(us(t),this.triggerStyles||(this.triggerStyles=Ze(this.$trigger,{pointerEvents:"none"})),this.$trigger.addEventListener("touchstart",us,{passive:!1}),this.$trigger.addEventListener("touchmove",us,{passive:!1}),this.$trigger.addEventListener("touchend",us),(!this.disabled[0]&&J(o)>3||!this.disabled[1]&&J(a)>3)&&(this.updateTicker.resume(),this.pointer[2]=this.pointer[0],this.pointer[3]=this.pointer[1],this.pointer[0]=r,this.pointer[1]=n,this.dragged=!0,this.released=!1,this.onDrag(this)))}handleUp(){if(!this.grabbed)return;this.updateTicker.pause(),this.triggerStyles&&(this.triggerStyles.revert(),this.triggerStyles=null),this.bodyStyles&&(this.bodyStyles.revert(),this.bodyStyles=null);const[t,e]=this.disabled,[s,n,o,a,h,l]=this.pointer,[c,d,u,p]=this.containerBounds,[m,f]=this.snapped,g=this.releaseXSpring,_=this.releaseYSpring,y=this.releaseEase,v=this.hasReleaseSpring,b=this.overshootCoords,S=this.x,x=this.y,T=this.computeVelocity(s-h,n-l),w=this.angle=rt(n-a,s-o),k=150*T,$=(1-this.releaseContainerFriction)*this.dragSpeed,E=S+Z(w)*k,C=x+G(w)*k,B=E>d?d+(E-d)*$:Eu?u+(C-u)*$:Cd?-1:1:SM&&(M=P)}if(!e){const e=N===u?x>u?-1:1:xM&&(M=R)}if(!v&&F&&$&&(P||R)){const t=r.blend;new Ne(b,{x:{to:B,duration:.65*P},y:{to:L,duration:.65*R},ease:y,composition:t}).init(),new Ne(b,{x:{to:A,duration:P},y:{to:N,duration:R},ease:y,composition:t}).init(),this.overshootXTicker.stretch(P).restart(),this.overshootYTicker.stretch(R).restart()}else t||this.animate[this.xProp](A,P,Y),e||this.animate[this.yProp](N,R,X);this.scrollInView(M,this.scrollThreshold,y);let O=!1;A!==m&&(this.snapped[0]=A,this.snapX&&(O=!0)),N!==f&&this.snapY&&(this.snapped[1]=N,this.snapY&&(O=!0)),O&&this.onSnap(this),this.grabbed=!1,this.dragged=!1,this.updated=!0,this.released=!0,this.onRelease(this),this.$trigger.removeEventListener("touchstart",us),this.$trigger.removeEventListener("touchmove",us),this.$trigger.removeEventListener("touchend",us),i.removeEventListener("touchmove",this),i.removeEventListener("touchend",this),i.removeEventListener("touchcancel",this),i.removeEventListener("mousemove",this),i.removeEventListener("mouseup",this),i.removeEventListener("selectstart",this)}reset(){return this.stop(),this.resizeTicker.pause(),this.grabbed=!1,this.dragged=!1,this.updated=!1,this.released=!1,this.canScroll=!1,this.setX(0,!0),this.setY(0,!0),this.coords[0]=0,this.coords[1]=0,this.pointer[0]=0,this.pointer[1]=0,this.pointer[2]=0,this.pointer[3]=0,this.pointer[4]=0,this.pointer[5]=0,this.pointer[6]=0,this.pointer[7]=0,this.velocity=0,this.velocityStack[0]=0,this.velocityStack[1]=0,this.velocityStack[2]=0,this.velocityStackIndex=0,this.angle=0,this}enable(){return this.enabled||(this.enabled=!0,this.$target.classList.remove("is-disabled"),this.touchActionStyles=Ze(this.$trigger,{touchAction:this.disabled[0]?"pan-x":this.disabled[1]?"pan-y":"none"}),this.$trigger.addEventListener("touchstart",this,{passive:!0}),this.$trigger.addEventListener("mousedown",this,{passive:!0}),this.$trigger.addEventListener("mouseenter",this)),this}disable(){return this.enabled=!1,this.grabbed=!1,this.dragged=!1,this.updated=!1,this.released=!1,this.canScroll=!1,this.touchActionStyles.revert(),this.cursorStyles&&(this.cursorStyles.revert(),this.cursorStyles=null),this.triggerStyles&&(this.triggerStyles.revert(),this.triggerStyles=null),this.bodyStyles&&(this.bodyStyles.revert(),this.bodyStyles=null),this.targetStyles&&(this.targetStyles.revert(),this.targetStyles=null),this.stop(),this.$target.classList.add("is-disabled"),this.$trigger.removeEventListener("touchstart",this),this.$trigger.removeEventListener("mousedown",this),this.$trigger.removeEventListener("mouseenter",this),i.removeEventListener("touchmove",this),i.removeEventListener("touchend",this),i.removeEventListener("touchcancel",this),i.removeEventListener("mousemove",this),i.removeEventListener("mouseup",this),i.removeEventListener("selectstart",this),this}revert(){return this.reset(),this.disable(),this.$target.classList.remove("is-disabled"),this.updateTicker.revert(),this.overshootXTicker.revert(),this.overshootYTicker.revert(),this.resizeTicker.revert(),this.animate.revert(),this}handleEvent(t){switch(t.type){case"mousedown":case"touchstart":this.handleDown(t);break;case"mousemove":case"touchmove":this.handleMove(t);break;case"mouseup":case"touchend":case"touchcancel":this.handleUp();break;case"mouseenter":this.handleHover();break;case"selectstart":us(t)}}}class ys{constructor(t={}){D.scope&&D.scope.revertibles.push(this);const e=t.root;let r=i;e&&(r=e.current||e.nativeElement||Dt(e)[0]||i);const n=t.defaults,o=D.defaults,a=t.mediaQueries;if(this.defaults=n?ft(n,o):o,this.root=r,this.constructors=[],this.revertConstructors=[],this.revertibles=[],this.methods={},this.matches={},this.mediaQueryLists={},this.data={},a)for(let t in a){const e=s.matchMedia(a[t]);this.mediaQueryLists[t]=e,e.addEventListener("change",this)}}execute(t){let e=D.scope,s=D.root,i=D.defaults;D.scope=this,D.root=this.root,D.defaults=this.defaults;const r=this.mediaQueryLists;for(let t in r)this.matches[t]=r[t].matches;const n=t(this);return D.scope=e,D.root=s,D.defaults=i,n}refresh(){return this.execute((()=>{let t=this.revertibles.length,e=this.revertConstructors.length;for(;t--;)this.revertibles[t].revert();for(;e--;)this.revertConstructors[e](this);this.revertibles.length=0,this.revertConstructors.length=0,this.constructors.forEach((t=>{const e=t(this);e&&this.revertConstructors.push(e)}))})),this}add(t,e){if(M(t)){const e=t;this.constructors.push(e),this.execute((()=>{const t=e(this);t&&this.revertConstructors.push(t)}))}else this.methods[t]=(...t)=>this.execute((()=>e(...t)));return this}handleEvent(t){"change"===t.type&&this.refresh()}revert(){const t=this.revertibles,e=this.revertConstructors,s=this.mediaQueryLists;let i=t.length,r=e.length;for(;i--;)t[i].revert();for(;r--;)e[r](this);for(let t in s)s[t].removeEventListener("change",this);t.length=0,e.length=0,this.constructors.length=0,this.matches={},this.methods={},this.mediaQueryLists={},this.data={}}}const vs=(t,e)=>t&&M(t)?t(e):t,bs=new Map;class Ss{constructor(t){this.element=t,this.useWin=this.element===i.body,this.winWidth=0,this.winHeight=0,this.width=0,this.height=0,this.left=0,this.top=0,this.zIndex=0,this.scrollX=0,this.scrollY=0,this.prevScrollX=0,this.prevScrollY=0,this.scrollWidth=0,this.scrollHeight=0,this.velocity=0,this.backwardX=!1,this.backwardY=!1,this.scrollTicker=new se({autoplay:!1,onBegin:()=>this.dataTimer.resume(),onUpdate:()=>{const t=this.backwardX||this.backwardY;gt(this,(t=>t.handleScroll()),t)},onComplete:()=>this.dataTimer.pause()}).init(),this.dataTimer=new se({autoplay:!1,frameRate:30,onUpdate:t=>{const e=t.deltaTime,s=this.prevScrollX,i=this.prevScrollY,r=this.scrollX,n=this.scrollY,o=s-r,a=i-n;this.prevScrollX=r,this.prevScrollY=n,o&&(this.backwardX=s>r),a&&(this.backwardY=i>n),this.velocity=lt(e>0?Math.sqrt(o*o+a*a)/e:0,5)}}).init(),this.resizeTicker=new se({autoplay:!1,duration:250*D.timeScale,onComplete:()=>{this.updateWindowBounds(),this.refreshScrollObservers(),this.handleScroll()}}).init(),this.wakeTicker=new se({autoplay:!1,duration:500*D.timeScale,onBegin:()=>{this.scrollTicker.resume()},onComplete:()=>{this.scrollTicker.pause()}}).init(),this._head=null,this._tail=null,this.updateScrollCoords(),this.updateWindowBounds(),this.updateBounds(),this.refreshScrollObservers(),this.handleScroll(),this.resizeObserver=new ResizeObserver((()=>this.resizeTicker.restart())),this.resizeObserver.observe(this.element),(this.useWin?s:this.element).addEventListener("scroll",this,!1)}updateScrollCoords(){const t=this.useWin,e=this.element;this.scrollX=lt(t?s.scrollX:e.scrollLeft,0),this.scrollY=lt(t?s.scrollY:e.scrollTop,0)}updateWindowBounds(){this.winWidth=s.innerWidth,this.winHeight=(()=>{const t=document.createElement("div");i.body.appendChild(t),t.style.height="100lvh";const e=t.offsetHeight;return i.body.removeChild(t),e})()}updateBounds(){const t=getComputedStyle(this.element),e=this.element;let s,i;if(this.scrollWidth=e.scrollWidth+parseFloat(t.marginLeft)+parseFloat(t.marginRight),this.scrollHeight=e.scrollHeight+parseFloat(t.marginTop)+parseFloat(t.marginBottom),this.updateWindowBounds(),this.useWin)s=this.winWidth,i=this.winHeight;else{const t=e.getBoundingClientRect();s=t.width,i=t.height,this.top=t.top,this.left=t.left}this.width=s,this.height=i}refreshScrollObservers(){gt(this,(t=>{t._debug&&t.removeDebug()})),this.updateBounds(),gt(this,(t=>{t.refresh(),t._debug&&t.debug()}))}refresh(){this.updateWindowBounds(),this.updateBounds(),this.refreshScrollObservers(),this.handleScroll()}handleScroll(){this.updateScrollCoords(),this.wakeTicker.restart()}handleEvent(t){"scroll"===t.type&&this.handleScroll()}revert(){this.scrollTicker.cancel(),this.dataTimer.cancel(),this.resizeTicker.cancel(),this.wakeTicker.cancel(),this.resizeObserver.unobserve(this.element),(this.useWin?s:this.element).removeEventListener("scroll",this),bs.delete(this.element)}}const xs=(t,e,s,i,r)=>{const n="min"===e,o="max"===e,a="top"===e||"left"===e||"start"===e||n?0:"bottom"===e||"right"===e||"end"===e||o?"100%":"center"===e?"50%":e,{n:h,u:l}=Vt(a,Ht);let c=h;return"%"===l?c=h/100*s:l&&(c=xe(t,Ht,"px",!0).n),o&&i<0&&(c+=i),n&&r>0&&(c+=r),c},Ts=(t,e,s,i,r)=>{let n;if(X(e)){const o=C.exec(e);if(o){const a=o[0],h=a[0],l=e.split(a),c="min"===l[0],d="max"===l[0],u=xs(t,l[0],s,i,r),p=xs(t,l[1],s,i,r);if(c){const e=Wt(xs(t,"min",s),p,h);n=eu?u:e}else n=Wt(u,p,h)}else n=xs(t,e,s,i,r)}else n=e;return lt(n,0)},ws=t=>{let e;const s=t.targets;for(let t=0,i=s.length;t()=>{const e=this.linked;return e&&e[t]?e[t]():null})):null,l=a&&h.length>2;this.index=ks++,this.id=O(t.id)?this.index:t.id,this.container=(t=>{const e=t&&Dt(t)[0]||i.body;let s=bs.get(e);return s||(s=new Ss(e),bs.set(e,s)),s})(t.container),this.target=null,this.linked=null,this.repeat=null,this.horizontal=null,this.enter=null,this.leave=null,this.sync=n||o||!!h,this.syncEase=n?s:null,this.syncSmooth=o?!0===e||r?1:e:null,this.onSyncEnter=h&&!l&&h[0]?h[0]:y,this.onSyncLeave=h&&!l&&h[1]?h[1]:y,this.onSyncEnterForward=h&&l&&h[0]?h[0]:y,this.onSyncLeaveForward=h&&l&&h[1]?h[1]:y,this.onSyncEnterBackward=h&&l&&h[2]?h[2]:y,this.onSyncLeaveBackward=h&&l&&h[3]?h[3]:y,this.onEnter=t.onEnter||y,this.onLeave=t.onLeave||y,this.onEnterForward=t.onEnterForward||y,this.onLeaveForward=t.onLeaveForward||y,this.onEnterBackward=t.onEnterBackward||y,this.onLeaveBackward=t.onLeaveBackward||y,this.onUpdate=t.onUpdate||y,this.onSyncComplete=t.onSyncComplete||y,this.reverted=!1,this.completed=!1,this.began=!1,this.isInView=!1,this.forceEnter=!1,this.hasEntered=!1,this.offsets=[],this.offset=0,this.offsetStart=0,this.offsetEnd=0,this.distance=0,this.prevProgress=0,this.thresholds=["start","end","end","start"],this.coords=[0,0,0,0],this.debugStyles=null,this.$debug=null,this._params=t,this._debug=Xt(t.debug,!1),this._next=null,this._prev=null,yt(this.container,this),je((()=>{if(!this.reverted){if(!this.target){const e=Dt(t.target)[0];this.target=e||i.body,this.refresh()}this._debug&&this.debug()}}))}link(t){if(t&&(t.pause(),this.linked=t,!this._params.target)){let e;O(t.targets)?gt(t,(t=>{t.targets&&!e&&(e=ws(t))})):e=ws(t),this.target=e||i.body,this.refresh()}return this}get velocity(){return this.container.velocity}get backward(){return this.horizontal?this.container.backwardX:this.container.backwardY}get scroll(){return this.horizontal?this.container.scrollX:this.container.scrollY}get progress(){const t=(this.scroll-this.offsetStart)/this.distance;return t===1/0||isNaN(t)?0:lt(at(t,0,1),6)}refresh(){this.reverted=!1;const t=this._params;return this.repeat=Xt(vs(t.repeat,this),!0),this.horizontal="x"===Xt(vs(t.axis,this),"y"),this.enter=Xt(vs(t.enter,this),"end start"),this.leave=Xt(vs(t.leave,this),"start end"),this.updateBounds(),this.handleScroll(),this}removeDebug(){return this.$debug&&(this.$debug.parentNode.removeChild(this.$debug),this.$debug=null),this.debugStyles&&(this.debugStyles.revert(),this.$debug=null),this}debug(){this.removeDebug();const t=this.container,e=this.horizontal,s=t.element.querySelector(":scope > .animejs-onscroll-debug"),r=i.createElement("div"),n=i.createElement("div"),o=i.createElement("div"),a=$s[this.index%$s.length],h=t.useWin,l=h?t.winWidth:t.width,c=h?t.winHeight:t.height,d=t.scrollWidth,u=t.scrollHeight,p=this.container.width>360?320:260,m=e?0:10,f=e?10:0,g=e?24:p/2,_=e?g:15,y=e?60:g,v=e?y:_,b=e?"repeat-x":"repeat-y",S=t=>e?"0px "+t+"px":t+"px 2px",x=t=>`linear-gradient(${e?90:0}deg, ${t} 2px, transparent 1px)`,T=(t,e,s,i,r)=>`position:${t};left:${e}px;top:${s}px;width:${i}px;height:${r}px;`;r.style.cssText=`${T("absolute",m,f,e?d:p,e?p:u)}\n pointer-events: none;\n z-index: ${this.container.zIndex++};\n display: flex;\n flex-direction: ${e?"column":"row"};\n filter: drop-shadow(0px 1px 0px rgba(0,0,0,.75));\n `,n.style.cssText=`${T("sticky",0,0,e?l:g,e?g:c)}`,s||(n.style.cssText+=`background:\n ${x("#FFFF")}${S(g-10)} / 100px 100px ${b},\n ${x("#FFF8")}${S(g-10)} / 10px 10px ${b};\n `),o.style.cssText=`${T("relative",0,0,e?d:g,e?g:u)}`,s||(o.style.cssText+=`background:\n ${x("#FFFF")}${S(0)} / ${e?"100px 10px":"10px 100px"} ${b},\n ${x("#FFF8")}${S(0)} / ${e?"10px 0px":"0px 10px"} ${b};\n `);const w=[" enter: "," leave: "];this.coords.forEach(((t,s)=>{const r=s>1,h=(r?0:this.offset)+t,m=s%2,f=h(r?e?l:c:e?d:u)-v,b=(r?m&&!f:!m&&!f)||g,S=i.createElement("div"),x=i.createElement("div"),k=e?b?"right":"left":b?"bottom":"top",$=b?(e?y:_)+(r?e?-1:g?0:-2:e?-1:-2):e?1:0;x.innerHTML=`${this.id}${w[m]}${this.thresholds[s]}`,S.style.cssText=`${T("absolute",0,0,y,_)}\n display: flex;\n flex-direction: ${e?"column":"row"};\n justify-content: flex-${r?"start":"end"};\n align-items: flex-${b?"end":"start"};\n border-${k}: 2px solid ${a};\n `,x.style.cssText=`\n overflow: hidden;\n max-width: ${p/2-10}px;\n height: ${_};\n margin-${e?b?"right":"left":b?"bottom":"top"}: -2px;\n padding: 1px;\n font-family: ui-monospace, monospace;\n font-size: 10px;\n letter-spacing: -.025em;\n line-height: 9px;\n font-weight: 600;\n text-align: ${e&&b||!e&&!r?"right":"left"};\n white-space: pre;\n text-overflow: ellipsis;\n color: ${m?a:"rgba(0,0,0,.75)"};\n background-color: ${m?"rgba(0,0,0,.65)":a};\n border: 2px solid ${m?a:"transparent"};\n border-${e?b?"top-left":"top-right":b?"top-left":"bottom-left"}-radius: 5px;\n border-${e?b?"bottom-left":"bottom-right":b?"top-right":"bottom-right"}-radius: 5px;\n `,S.appendChild(x);let E=h-$+(e?1:0);S.style[e?"left":"top"]=`${E}px`,(r?n:o).appendChild(S)})),r.appendChild(n),r.appendChild(o),t.element.appendChild(r),s||r.classList.add("animejs-onscroll-debug"),this.$debug=r,"static"===Ge(t.element,"position")&&(this.debugStyles=Ze(t.element,{position:"relative "}))}updateBounds(){let t;this._debug&&this.removeDebug();const e=this.target,s=this.container,r=this.horizontal,n=this.linked;let o,a=e,h=0,l=0,c=a;n&&(o=n.currentTime,n.seek(0,!0));const d="static"===Ge(s.element,"position")&&Ze(s.element,{position:"relative "});for(;a&&a!==s.element&&a!==i.body;){const e="sticky"===Ge(a,"position")&&Ze(a,{position:"static"});a===c&&(h+=a.offsetLeft||0,l+=a.offsetTop||0,c=a.offsetParent),a=a.parentElement,e&&(t||(t=[]),t.push(e))}d&&d.revert();const u=r?h:l,p=r?e.offsetWidth:e.offsetHeight,m=r?s.width:s.height,f=(r?s.scrollWidth:s.scrollHeight)-m,g=this.enter,_=this.leave;let y="start",v="end",b="end",S="start";if(X(g)){const t=g.split(" ");b=t[0],y=t.length>1?t[1]:y}else if(R(g)){const t=g;O(t.container)||(b=t.container),O(t.target)||(y=t.target)}else Y(g)&&(b=g);if(X(_)){const t=_.split(" ");S=t[0],v=t.length>1?t[1]:v}else if(R(_)){const t=_;O(t.container)||(S=t.container),O(t.target)||(v=t.target)}else Y(_)&&(S=_);const x=Ts(e,y,p),T=Ts(e,v,p),w=x+u-m,k=T+u-f,$=Ts(e,b,m,w,k),E=Ts(e,S,m,w,k),C=x+u-$,B=T+u-E,D=B-C;this.offsets[0]=h,this.offsets[1]=l,this.offset=u,this.offsetStart=C,this.offsetEnd=B,this.distance=D<=0?0:D,this.thresholds=[y,v,b,S],this.coords=[x,T,$,E],t&&t.forEach((t=>t.revert())),n&&n.seek(o,!0),this._debug&&this.debug()}handleScroll(){const t=this.linked,e=this.sync,s=this.syncEase,i=this.syncSmooth,r=t&&(s||i),n=this.horizontal,o=this.container,a=this.scroll,h=a<=this.offsetStart,l=a>=this.offsetEnd,c=!h&&!l,d=a===this.offsetStart||a===this.offsetEnd,u=!this.hasEntered&&d,p=this._debug&&this.$debug;let m=!1,f=!1,g=this.progress;if(h&&this.began&&(this.began=!1),g>0&&!this.began&&(this.began=!0),r){const e=t.progress;if(i&&Y(i)){if(i<1){const t=eg&&!g?-1e-4:0;g=lt(ss(e,g,dt(.01,.2,i),!1)+t,6)}}else s&&(g=s(g));m=g!==this.prevProgress,f=1===e,m&&!f&&i&&e&&o.wakeTicker.restart()}if(p){const t=n?o.scrollY:o.scrollX;p.style[n?"top":"left"]=t+10+"px"}(c&&!this.isInView||u&&!this.forceEnter&&!this.hasEntered)&&(c&&(this.isInView=!0),this.forceEnter&&this.hasEntered?c&&(this.forceEnter=!1):(p&&c&&(p.style.zIndex=""+this.container.zIndex++),this.onSyncEnter(this),this.onEnter(this),this.backward?(this.onSyncEnterBackward(this),this.onEnterBackward(this)):(this.onSyncEnterForward(this),this.onEnterForward(this)),this.hasEntered=!0,u&&(this.forceEnter=!0))),(c||!c&&this.isInView)&&(m=!0),m&&(r&&t.seek(t.duration*g),this.onUpdate(this)),!c&&this.isInView&&(this.isInView=!1,this.onSyncLeave(this),this.onLeave(this),this.backward?(this.onSyncLeaveBackward(this),this.onLeaveBackward(this)):(this.onSyncLeaveForward(this),this.onLeaveForward(this)),e&&!i&&(f=!0)),g>=1&&this.began&&!this.completed&&(e&&f||!e)&&(e&&this.onSyncComplete(this),this.completed=!0,(!this.repeat&&!t||!this.repeat&&t&&t.completed)&&this.revert()),g<1&&this.completed&&(this.completed=!1),this.prevProgress=g}revert(){if(this.reverted)return;const t=this.container;return _t(t,this),t._head||t.revert(),this._debug&&this.removeDebug(),this.reverted=!0,this}}return t.Animatable=ls,t.Draggable=_s,t.JSAnimation=Ne,t.Scope=ys,t.ScrollObserver=Es,t.Spring=cs,t.Timeline=hs,t.Timer=se,t.WAAPIAnimation=qe,t.animate=(t,e)=>new Ne(t,e,null,0,!1).init(),t.createAnimatable=(t,e)=>new ls(t,e),t.createDraggable=(t,e)=>new _s(t,e),t.createScope=t=>new ys(t),t.createSpring=ds,t.createTimeline=t=>new hs(t).init(),t.createTimer=t=>new se(t,null,0).init(),t.eases=fe,t.engine=$t,t.onScroll=(t={})=>new Es(t),t.scrollContainers=bs,t.stagger=(t,e={})=>{let s=[],i=0;const r=e.from,n=e.reversed,o=e.ease,a=!O(o),h=a&&!O(o.ease)?o.ease:a?_e(o):null,l=e.grid,c=e.axis,d=O(r)||0===r||"first"===r,u="center"===r,p="last"===r,f=P(t),g=q(f?t[0]:t),_=f?q(t[1]):0,y=k.exec((f?t[1]:t)+m),v=e.start||0+(f?g:0);let b=d?0:Y(r)?r:0;return(t,r,o,a)=>{if(u&&(b=(o-1)/2),p&&(b=o-1),!s.length){for(let t=0;th(t/i)*i))),n&&(s=s.map((t=>c?t<0?-1*t:-t:J(i-t))))}const d=f?(_-g)/i:g;let m=(a?os(a,O(e.start)?a.iterationDuration:v):v)+(d*lt(s[r],2)||0);return e.modifier&&(m=e.modifier(m)),y&&(m=`${m}${y[2]}`),m}},t.svg=Rt,t.utils=ns,t.waapi=Qe,t}({});
diff --git a/assets/stylesheets/_mobile.scss b/assets/stylesheets/_mobile.scss
index 468356ffc..653ac0d94 100644
--- a/assets/stylesheets/_mobile.scss
+++ b/assets/stylesheets/_mobile.scss
@@ -1,39 +1,4 @@
@media only screen and (max-width: 62rem) {
- .navigation-links {
- display: none;
- }
-
- .mobile-navigation {
- display: none;
-
- &.open {
- display: block;
- }
- }
-
- .site-navigation .wrapper {
- justify-content: space-between;
- }
-
- .menu-toggle {
- display: block;
- appearance: none;
- -webkit-appearance: none;
- -moz-appearance: none;
- border: none;
- background-color: transparent;
- height: 20px;
- width: 20px;
- background-image: var(--menu-icon-close);
- background-repeat: no-repeat;
- background-position: center center;
- cursor: pointer;
-
- &.open {
- background-image: var(--menu-icon);
- }
- }
-
.section-toggle {
appearance: none;
-webkit-appearance: none;
@@ -53,36 +18,6 @@
transform: rotate(180deg);
}
}
-
- .section-menu {
- display: none;
-
- &.open {
- display: block;
- }
-
- li a {
- display: block;
- padding: 0.5rem 2rem;
- font-size: 0.6em;
- opacity: 0.8;
- }
- }
-
- .link-container {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
-
- a {
- flex: 1 1 auto;
- }
-
- button {
- flex: 0 0 auto;
- padding: 1rem;
- }
- }
}
@media only screen and (max-width: 767px) {
@@ -92,17 +27,6 @@
margin-left: 0;
}
- footer[role="contentinfo"] {
- margin-left: 0;
- flex-direction: column;
- }
-
- .footer-other {
- display: flex;
- justify-content: space-between;
- margin-top: var(--content-margin-bottom);
- }
-
h1 {
font-size: 48px;
font-weight: 300;
@@ -228,10 +152,3 @@
hyphens: auto;
}
}
-
-.nav-menu-container {
- display: grid;
- grid-template-columns: 1fr;
- grid-template-rows: 1fr;
- align-items: center;
-}
diff --git a/assets/stylesheets/_pages.scss b/assets/stylesheets/_pages.scss
index 4ac6d3445..02d58dc6d 100644
--- a/assets/stylesheets/_pages.scss
+++ b/assets/stylesheets/_pages.scss
@@ -1,4 +1,3 @@
-@use "pages/landing";
@use "pages/swift-evolution";
@use "pages/packages";
@use "pages/download";
diff --git a/assets/stylesheets/_print.scss b/assets/stylesheets/_print.scss
index c2dacb54f..cd989f55a 100644
--- a/assets/stylesheets/_print.scss
+++ b/assets/stylesheets/_print.scss
@@ -52,7 +52,6 @@
main {
width: auto;
- padding: 0;
border: 0;
float: none !important;
color: black;
diff --git a/assets/stylesheets/_screen.scss b/assets/stylesheets/_screen.scss
index ecc53c5fe..a1928b45f 100644
--- a/assets/stylesheets/_screen.scss
+++ b/assets/stylesheets/_screen.scss
@@ -1,13 +1,5 @@
@use './core/_helpers' as mixhelpers;
-*,
-*:before,
-*:after {
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
-}
-
html,
body {
display: flex;
@@ -17,17 +9,20 @@ body {
}
body {
- font-family: -apple-system, BlinkMacSystemFont, "SF Hello", "Helvetica Neue",
- Helvetica, Arial, Verdana, sans-serif;
- font-size: 18px;
- line-height: 1.5;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
+ Cantarell, 'Helvetica Neue', sans-serif;
+
+ line-height: 1.6;
+ font-size: 17px;
+ font-weight: 400;
background-color: var(--color-fill);
color: var(--color-text);
- font-weight: 300;
pre,
code {
- font-family: "SF Mono", ui-monospace, Menlo, Consolas, Monaco, "Courier New",
+ font-family:
+ 'SF Mono', ui-monospace, Menlo, Consolas, Monaco, 'Courier New',
monospace, serif;
}
}
@@ -178,15 +173,17 @@ cite {
display: block;
&:before {
- content: "— ";
+ content: '— ';
}
}
.header-with-anchor {
+ scroll-margin-top: 80px;
+
a {
display: none;
color: var(--color-text);
- margin-left: .2em;
+ margin-left: 0.2em;
text-decoration: none;
svg {
@@ -203,226 +200,9 @@ h2.header-with-anchor {
}
}
-#logo {
- margin-bottom: 0;
-
- a {
- display: flex;
- width: 150px;
- }
-
- svg {
- flex: 1;
- }
-
- #logotype {
- fill: var(--color-header-text);
- }
-}
-
-.site-navigation {
- padding: 1rem;
- background: var(--color-nav-background);
- border-bottom: 1px solid var(--color-nav-rule);
-
- .wrapper {
- align-items: center;
- display: flex;
- justify-content: space-between;
- margin: auto;
- max-width: var(--navigation-mobile-breakpoint);
- }
-}
-
-.menu-toggle {
- display: none;
-}
-
-.navigation-links {
- list-style: none;
- margin: 0;
- padding: 0;
-
- li {
- display: inline-block;
- margin-left: 0.3em;
- text-align: center;
-
- .active a {
- font-weight: 700;
- color: var(--color-active-nav-item);
- }
-
- a {
- display: inline-block;
- }
-
- a::before {
- display: block;
- content: attr(data-text);
- font-weight: bold;
- height: 0;
- overflow: hidden;
- visibility: hidden;
- }
-
- &.nav-section {
- color: var(--color-nav-color);
- font-size: 0.7rem;
- text-transform: uppercase;
- letter-spacing: 1px;
- margin-bottom: 0.5rem;
- padding: 1rem 0 0.5rem;
- border-bottom: 1px solid var(--color-nav-rule);
- }
-
- &.nav-cta {
- margin-left: 1em;
-
- a {
- border: 2px solid var(--color-nav-rule);
- border-radius: 0.5rem;
- padding: 0.8em 0.9em;
- text-align: center;
-
- &:hover {
- border-color: var(--color-link);
- }
- }
- }
-
- & a,
- & > span {
- @include mixhelpers.nav-link-style;
- padding: 0.5em;
- }
- }
-}
-
-.navigation-links a:hover {
- color: var(--color-link);
-}
-
-/* Navigation Dropdown */
-.nav-item {
- transition: all 0.1s ease;
-}
-
-.nav-submenu {
- display: none;
- position: absolute;
- background-color: var(--color-nav-background);
- backdrop-filter: blur(20px);
- -webkit-backdrop-filter: blur(5px);
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.05);
- border-radius: 8px;
- border: 1px solid var(--color-nav-rule);
- min-width: 160px;
- z-index: 1;
- list-style: none;
- padding: 1rem;
- animation: fade-in-down 0.3s;
-
- li {
- display: block;
- padding: 0;
- margin: 0;
- text-align: left;
-
- a {
- display: block;
- padding: 0.7em;
- border-radius: 8px;
- transition: all 0.1s ease;
-
- &:hover {
- background-color: rgba(gray, 0.1);
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.05),
- 0 1px 3px rgba(0, 0, 0, 0.08);
- }
- }
- }
-
- hr {
- border: none;
- border-top: 1px solid gray;
- margin: 0.5rem 0;
- }
-}
-
-.nav-item span {
- display: inline-block;
- cursor: pointer;
-}
-
-.nav-item span i {
- display: inline-block;
- margin-left: -0.75em;
- font-style: normal;
- font-weight: 100;
- opacity: 0.2;
- line-height: 1em;
- padding-top: 0.2em;
-}
-
-.nav-item:hover > span {
- color: var(--color-link);
-}
-
-.nav-item:hover .nav-submenu,
-.nav-item:focus-within .nav-submenu {
- display: block;
-}
-
-/* Mobile Navigation */
-.mobile-navigation {
- display: none;
-}
-
-.mobile-navigation-links {
- list-style: none;
- margin: 1rem 0;
- padding: 0;
-
- li {
- border-top: 1px solid var(--color-nav-rule);
- display: block;
-
- &:last-child {
- border-bottom: 1px solid var(--color-nav-rule);
- }
-
- &.active,
- .link-container.active {
- a {
- font-weight: 700;
- color: var(--color-active-nav-item);
- }
- }
-
- &.nav-section {
- color: var(--color-nav-color);
- font-size: 0.7rem;
- text-transform: uppercase;
- letter-spacing: 1px;
- margin-bottom: 0.5rem;
- padding: 1rem 1rem 0.5rem;
- }
-
- & a {
- display: inline-block;
- padding: 1rem;
- }
-
- & a,
- & > span {
- @include mixhelpers.nav-link-style;
- }
- }
-}
-
main {
- padding: 4rem 0 0;
+ padding-top: 66px; // height of nav
+ background-color: var(--color-fill);
.callout {
display: grid;
@@ -441,94 +221,14 @@ main {
max-width: var(--content-mobile-breakpoint);
padding: 0;
margin: auto;
-
- @media only screen and (max-width: 1280px) {
- padding: 30px 30px 0;
- }
+ padding: 30px;
}
.post,
.page {
max-width: 50em;
margin: 0 auto;
- padding: 0 30px;
-
- @media only screen and (max-width: 1280px) {
- padding-top: 30px;
- }
-
- @media only screen and (max-width: 767px) {
- padding: 30px 30px 0;
- }
- }
-
- @media only screen and (max-width: 1280px) {
- padding: 0;
- }
-}
-
-footer[role="contentinfo"] {
- background: var(--color-nav-background);
- border-top: 1px solid var(--color-nav-rule);
- color: var(--color-nav-color);
- padding: 20px 30px;
- min-height: 74px;
- margin-top: auto;
-
- p {
- font-size: 0.625em;
- color: var(--color-nav-link-color);
- line-height: 1em;
- margin-bottom: var(--content-margin-bottom);
-
- &.privacy {
- a {
- color: var(--color-nav-link-color);
- border-right: 1px solid var(--color-nav-rule);
- margin-right: 6px;
- padding-right: 8px;
-
- &:last-child {
- border: none;
- margin: 0;
- padding: 0;
- }
- }
- }
-
- &:last-child {
- margin-bottom: 0;
- }
- }
-
- aside {
- position: relative;
- width: 100%;
- max-width: 700px;
-
- i {
- width: 16px;
- height: 16px;
- background-repeat: no-repeat;
- background-size: 16px;
- display: block;
- margin-left: 1em;
- float: right;
-
- &.x {
- background-image: url("/assets/images/icon-x.svg");
- }
- &.mastodon {
- background-image: url("/assets/images/icon-mastodon.svg");
- }
- &.bluesky {
- background-image: url("/assets/images/icon-bluesky.svg");
- }
-
- &.feed {
- background-image: url("/assets/images/icon-feed.svg");
- }
- }
+ padding: 30px;
}
}
@@ -644,7 +344,7 @@ article {
margin: 2em 0 1em 0;
&:after {
- content: "";
+ content: '';
display: table;
clear: both;
}
@@ -714,14 +414,14 @@ article {
}
summary:after {
- content: "Expand";
+ content: 'Expand';
text-transform: lowercase;
font-variant: small-caps;
border-bottom: 1px var(--color-fill-gray) dashed;
}
&[open] summary:after {
- content: "Collapse";
+ content: 'Collapse';
}
&[open] *:not(summary) {
@@ -770,7 +470,7 @@ article {
}
.good pre:before,
pre.good:before {
- content: "✅";
+ content: '✅';
float: right;
}
.bad pre,
@@ -780,7 +480,7 @@ article {
}
.bad pre:before,
pre.bad:before {
- content: "⛔️";
+ content: '⛔️';
float: right;
}
@@ -793,18 +493,18 @@ article {
}
}
a:after {
- content: " ›";
+ content: ' ›';
}
}
.links .link-external:after, // Needed for specificity of existing styles
.links-external a:after, // Needed for Jekyll html + markdown link markup
.link-external:after {
- content: " ↗";
+ content: ' ↗';
}
.links-download a:after {
- content: " ⬇";
+ content: ' ⬇';
}
.links-list-nostyle {
@@ -833,29 +533,29 @@ article {
border-top: 1px var(--color-dropdown-border) solid;
&:after {
- content: "";
+ content: '';
display: table;
clear: both;
}
nav {
- [rel="prev"] {
+ [rel='prev'] {
width: 45%;
float: left;
text-align: left;
&:before {
- content: "← ";
+ content: '← ';
}
}
- [rel="next"] {
+ [rel='next'] {
width: 45%;
float: right;
text-align: right;
&:after {
- content: " →";
+ content: ' →';
}
}
}
@@ -914,8 +614,8 @@ pre code .graphic {
pre code .commentary,
pre code .graphic {
- font-family: "SF Hello", "Helvetica Neue", Helvetica, Arial, Verdana,
- sans-serif;
+ font-family:
+ 'SF Hello', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
}
@supports (overflow: -webkit-marquee) and (justify-content: inherit) {
@@ -934,19 +634,19 @@ pre code .graphic {
}
.success:before {
- content: "✅";
+ content: '✅';
}
.info:before {
- content: "ℹ️";
+ content: 'ℹ️';
}
.warning:before {
- content: "⚠️";
+ content: '⚠️';
}
.danger:before {
- content: "❗️";
+ content: '❗️';
}
}
@@ -1007,10 +707,10 @@ table.downloads {
a:not([download]) {
font-weight: 400;
&:before {
- content: "(";
+ content: '(';
}
&:after {
- content: ")";
+ content: ')';
}
}
}
@@ -1035,7 +735,7 @@ table.downloads {
}
article {
- input.detail[type="checkbox"] {
+ input.detail[type='checkbox'] {
visibility: hidden;
cursor: pointer;
height: 0;
@@ -1051,7 +751,7 @@ article {
-moz-appearance: none;
}
- p + input.detail[type="checkbox"] {
+ p + input.detail[type='checkbox'] {
margin-top: auto;
}
@@ -1062,35 +762,37 @@ article {
.screenonly {
display: inherit;
}
- input.detail[type="checkbox"]:before {
- content: "▶ ";
+ input.detail[type='checkbox']:before {
+ content: '▶ ';
visibility: visible;
font-size: 80%;
}
- input.detail[type="checkbox"]:after {
+ input.detail[type='checkbox']:after {
text-transform: lowercase;
font-variant: small-caps;
border-bottom: 1px var(--color-fill-gray) dashed;
color: var(--color-figure-gray-secondary);
- content: "More detail";
+ content: 'More detail';
visibility: visible;
}
- input.detail[type="checkbox"]:checked:before {
- content: "▼ ";
+ input.detail[type='checkbox']:checked:before {
+ content: '▼ ';
}
- input.detail[type="checkbox"]:checked:after {
- content: "Less detail";
+ input.detail[type='checkbox']:checked:after {
+ content: 'Less detail';
}
- input.detail[type="checkbox"] + .more {
- transition: 0.5s opacity ease, 0.5s max-height ease;
+ input.detail[type='checkbox'] + .more {
+ transition:
+ 0.5s opacity ease,
+ 0.5s max-height ease;
}
- input.detail[type="checkbox"]:checked + .more {
+ input.detail[type='checkbox']:checked + .more {
visibility: visible;
max-height: 1000rem;
}
- input.detail[type="checkbox"]:not(:checked) + .more {
+ input.detail[type='checkbox']:not(:checked) + .more {
overflow: hidden;
max-height: 0px;
opacity: 0;
@@ -1141,11 +843,6 @@ article {
}
}
-[role="contentinfo"] {
- display: flex;
- justify-content: space-between;
-}
-
.visuallyhidden {
@include mixhelpers.visuallyhidden();
}
diff --git a/assets/stylesheets/application.scss b/assets/stylesheets/application.scss
index ecad74507..1b21ff66b 100644
--- a/assets/stylesheets/application.scss
+++ b/assets/stylesheets/application.scss
@@ -10,3 +10,28 @@ layout: source
@use "mobile";
@use "pages";
@use "print";
+@use "new-stylesheets/themes" as *;
+@use 'new-stylesheets/includes/header';
+@use 'new-stylesheets/includes/navigation';
+@use 'new-stylesheets/includes/footer';
+
+body {
+ @include light-theme;
+
+ &[data-color-scheme='light'] {
+ color-scheme: light;
+ }
+
+ &[data-color-scheme='dark'] {
+ color-scheme: dark;
+
+ @include dark-theme;
+ }
+
+ // Use linear-gradient so over scroll color matches footer background color, when user rubberbands.
+ background-image: linear-gradient(
+ 180deg,
+ var(--nav-scroller-gradient-start) 50%,
+ var(--nav-scroller-gradient-end) 50%
+ );
+}
diff --git a/assets/stylesheets/new-stylesheets/_colors.scss b/assets/stylesheets/new-stylesheets/_colors.scss
new file mode 100644
index 000000000..19da64c02
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_colors.scss
@@ -0,0 +1,2 @@
+$accent: #051416;
+$nav-bg: gray;
diff --git a/assets/stylesheets/new-stylesheets/_core.scss b/assets/stylesheets/new-stylesheets/_core.scss
new file mode 100644
index 000000000..bc42414e6
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_core.scss
@@ -0,0 +1,59 @@
+@use 'reset';
+@use 'print';
+@use 'graphics' as *;
+@use 'fonts';
+@use 'themes' as *;
+
+body {
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
+ Cantarell, 'Helvetica Neue', sans-serif;
+ font-weight: 400;
+ color: #051416;
+ font-size: 17px;
+ line-height: 1.6;
+ color-scheme: light dark;
+ transition:
+ background-color 0.3s ease,
+ color 0.3s ease;
+ @include light-theme;
+
+ &[data-color-scheme='light'] {
+ color-scheme: light;
+ }
+
+ &[data-color-scheme='dark'] {
+ color-scheme: dark;
+ @include dark-theme;
+ }
+
+ // TODO: Remove this and move the rule in body
+ #install {
+ color: var(--site-text-color);
+ }
+
+ // Use linear-gradient so over scroll color matches footer background color, when user rubberbands.
+ background-image: linear-gradient(
+ 180deg,
+ var(--nav-scroller-gradient-start) 50%,
+ var(--nav-scroller-gradient-end) 50%
+ );
+}
+
+h2 {
+ font-weight: 600;
+}
+
+main {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ background-color: var(--page-bg);
+}
+
+code {
+ font-family:
+ 'SF Mono', ui-monospace, Menlo, Consolas, Monaco, 'Courier New', monospace,
+ serif;
+ font-weight: 400;
+}
diff --git a/assets/stylesheets/new-stylesheets/_fonts.scss b/assets/stylesheets/new-stylesheets/_fonts.scss
new file mode 100644
index 000000000..3a8b306be
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_fonts.scss
@@ -0,0 +1,31 @@
+@font-face {
+ font-family: 'Anonymous Pro';
+ src: url('/assets/fonts/Anonymous-Pro.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Anonymous Pro';
+ src: url('/assets/fonts/Anonymous-Pro-B.ttf') format('truetype');
+ font-weight: 700;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Anonymous Pro';
+ src: url('/assets/fonts/Anonymous-Pro-I.ttf') format('truetype');
+ font-weight: 400;
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Anonymous Pro';
+ src: url('/assets/fonts/Anonymous-Pro-BI.ttf') format('truetype');
+ font-weight: 700;
+ font-style: italic;
+ font-display: swap;
+}
diff --git a/assets/stylesheets/new-stylesheets/_graphics.scss b/assets/stylesheets/new-stylesheets/_graphics.scss
new file mode 100644
index 000000000..caf5ef355
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_graphics.scss
@@ -0,0 +1,8 @@
+$pattern: url('/assets/images/icon-swift.svg');
+$menu-icon: url('/assets/images/icon-menu.svg');
+$menu-icon-close: url('/assets/images/icon-close.svg');
+$icon-x: url('/assets/images/icon-x.svg');
+$icon-mastodon: url('/assets/images/icon-mastodon.svg');
+$icon-bluesky: url('/assets/images/icon-bluesky.svg');
+$icon-feed: url('/assets/images/icon-feed.svg');
+$icon-github: url('/assets/images/icon-github.svg');
diff --git a/assets/stylesheets/new-stylesheets/_helpers.scss b/assets/stylesheets/new-stylesheets/_helpers.scss
new file mode 100644
index 000000000..4eb05388e
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_helpers.scss
@@ -0,0 +1,202 @@
+@use 'sass:list';
+
+@mixin flex-between {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+@mixin inline-link-style {
+ padding: 0.5em;
+ display: inline-block;
+ color: black;
+
+ &::before {
+ content: attr(data-text);
+ display: block;
+ font-weight: bold;
+ height: 0;
+ overflow: hidden;
+ visibility: hidden;
+ }
+}
+
+@mixin link-with-right-arrow {
+ color: var(--site-link-with-right-arrow-color);
+ text-decoration: none;
+ align-items: center;
+ display: inline-flex;
+
+ i {
+ display: inline-block;
+ margin-left: 6px;
+ background: url(/assets/images/icon-arrow-right-circle.svg) no-repeat center;
+ filter: var(--site-link-with-right-arrow-icon-filter);
+
+ width: 17px;
+ height: 17px;
+ }
+}
+
+@mixin appearance-none {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+}
+
+@mixin mobile-toggle-btn($bg-img) {
+ display: block;
+ @include appearance-none;
+ border: none;
+ background-color: transparent;
+ height: 20px;
+ width: 20px;
+ background-image: $bg-img;
+ background-repeat: no-repeat;
+ background-position: center;
+ cursor: pointer;
+}
+
+@mixin visuallyhidden() {
+ position: absolute;
+ clip: rect(1px, 1px, 1px, 1px);
+ clip-path: inset(0px 0px 99.9% 99.9%);
+ overflow: hidden;
+ height: 1px;
+ width: 1px;
+ padding: 0;
+ border: 0;
+}
+
+@mixin nav-link-style {
+ color: var(--color-nav-link-color);
+ transition:
+ color 0.2s ease,
+ border 0.2s ease;
+ text-decoration: none;
+ text-transform: uppercase;
+ font-size: 0.8rem;
+ letter-spacing: 1px;
+ font-weight: normal;
+}
+
+@mixin swoop-ratio($width, $height, $multiplier) {
+ aspect-ratio: list.slash($width, calc($height * $multiplier));
+}
+
+@mixin noise {
+ &::before {
+ content: '';
+ display: block;
+ height: 100%;
+ width: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: url(/assets/images/noise.png);
+ opacity: 0.04;
+ z-index: 1;
+ pointer-events: none;
+ }
+}
+
+@mixin big-button {
+ z-index: 5;
+ position: relative;
+ display: inline-block;
+ line-height: 1.2;
+ font-size: 35px;
+ color: #ffffff;
+ letter-spacing: 0;
+ font-weight: 400;
+ text-decoration: none;
+ padding: 15px 81px;
+ background-image: linear-gradient(to bottom right, #ff7f00, #f05238);
+ border-radius: 43px;
+ white-space: nowrap;
+ cursor: pointer;
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease;
+
+ &:hover,
+ &:focus {
+ background-color: #ff7f00;
+ color: #e0e0e0;
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: 2px solid dodgerblue;
+ outline-offset: 2px;
+ }
+}
+
+@mixin lazyloadBg($url) {
+ background-image: none;
+ opacity: 0;
+
+ &.visible {
+ opacity: 1;
+ background-image: url($url);
+ }
+}
+
+@mixin button-style {
+ text-decoration: none;
+ color: #801a1a;
+ font-weight: 400;
+ background-color: rgba(255, 177, 100, 0.9);
+ border-radius: 36px;
+ font-size: 14px;
+ white-space: nowrap;
+ padding: 12px;
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease;
+
+ @media only screen and (max-width: 1024px) {
+ padding: 6px;
+ min-width: 80px;
+ }
+
+ & > div {
+ display: inline-block;
+ margin-left: 14px;
+ }
+
+ &[aria-pressed='true'],
+ &:hover,
+ &:focus {
+ background-color: rgba(200, 100, 12, 0.9);
+ border: 0 !important;
+ color: white;
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: 2px solid dodgerblue;
+ outline-offset: 2px;
+ }
+
+ span {
+ display: block;
+ }
+
+ .title {
+ font-size: 24px;
+ font-weight: 600;
+ margin-bottom: 8px;
+ }
+
+ .subtitle {
+ font-size: 14px;
+ white-space: normal;
+ }
+}
+
+@mixin underline {
+ text-decoration: underline;
+ text-decoration-color: color-mix(in srgb, currentColor 50%, transparent);
+ text-underline-offset: 2px;
+}
\ No newline at end of file
diff --git a/assets/stylesheets/new-stylesheets/_includes.scss b/assets/stylesheets/new-stylesheets/_includes.scss
new file mode 100644
index 000000000..f8be3ff08
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_includes.scss
@@ -0,0 +1,7 @@
+@use 'includes/navigation';
+@use 'includes/footer';
+@use 'includes/header';
+@use 'includes/interactive-tabs';
+@use 'includes/callout';
+@use 'includes/overlapping-containers';
+@use 'includes/carousel';
diff --git a/assets/stylesheets/new-stylesheets/_pages.scss b/assets/stylesheets/new-stylesheets/_pages.scss
new file mode 100644
index 000000000..3706381da
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_pages.scss
@@ -0,0 +1,4 @@
+@use 'pages/index';
+@use 'pages/exception';
+@use 'pages/install';
+@use 'pages/get-started';
diff --git a/assets/stylesheets/new-stylesheets/_print.scss b/assets/stylesheets/new-stylesheets/_print.scss
new file mode 100644
index 000000000..72c6ca6c9
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_print.scss
@@ -0,0 +1,90 @@
+@media only print {
+ html body {
+ background: white;
+ font-size: 12pt;
+ padding: 0.5in;
+
+ * {
+ -webkit-print-color-adjust: exact;
+ }
+ }
+
+ a {
+ color: black !important;
+ text-decoration: underline !important;
+
+ &[href^="http://"]:after
+ {
+ content: ' (' attr(href) ') ';
+ color: #444;
+ }
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ p,
+ article > div,
+ pre,
+ table {
+ page-break-inside: avoid;
+ }
+
+ details:not([open]) {
+ visibility: visible;
+ }
+
+ details:not([open]) summary {
+ display: none !important;
+ }
+
+ details:not([open]) > *,
+ details:not([open]) {
+ display: block;
+ }
+
+ .alert {
+ margin: 1.5em 0;
+ }
+
+ main {
+ width: auto;
+ padding: 0;
+ border: 0;
+ float: none !important;
+ color: black;
+ background: transparent;
+ margin: 0;
+ max-width: 100%;
+ min-height: 1in;
+ }
+
+ nav[role='navigation'] {
+ background: transparent;
+ border: none;
+ width: auto;
+ position: static;
+ padding: 0;
+
+ h2,
+ ul {
+ display: none;
+ }
+
+ #logo {
+ position: static;
+ margin-bottom: 1.5em;
+
+ a {
+ background-position: -15px;
+ }
+ }
+ }
+
+ footer[role='contentinfo'] {
+ display: none;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/_reset.scss b/assets/stylesheets/new-stylesheets/_reset.scss
new file mode 100644
index 000000000..51223da66
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_reset.scss
@@ -0,0 +1,109 @@
+html {
+ font-size: 100%;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ background-color: var(--color-fill);
+ color: var(--color-text);
+}
+
+ul,
+ol,
+li,
+dl,
+dt,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hgroup,
+p,
+blockquote,
+figure,
+form,
+fieldset,
+input,
+legend,
+pre,
+abbr {
+ margin: 0;
+ padding: 0;
+}
+
+ul {
+ list-style: none;
+}
+
+pre,
+code,
+address,
+caption,
+th,
+figcaption {
+ font-size: 1em;
+ font-weight: normal;
+ font-style: normal;
+}
+
+fieldset,
+iframe,
+img {
+ width: 100%;
+ border: none;
+}
+
+caption,
+th {
+ text-align: left;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+article,
+aside,
+footer,
+header,
+nav,
+main,
+section,
+summary,
+details,
+hgroup,
+figure,
+figcaption {
+ display: block;
+}
+
+audio,
+canvas,
+video,
+progress {
+ display: inline-block;
+ vertical-align: baseline;
+}
+
+button {
+ font: inherit;
+ vertical-align: middle;
+}
+
+nav {
+ a {
+ &:link,
+ &:visited,
+ &:hover,
+ &:active {
+ text-decoration: none;
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/_syntax.scss b/assets/stylesheets/new-stylesheets/_syntax.scss
new file mode 100644
index 000000000..09de01765
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_syntax.scss
@@ -0,0 +1,210 @@
+[class^='language-'] .highlight,
+.code-box pre {
+ position: relative;
+
+ button {
+ position: absolute;
+ top: 1em;
+ right: 1em;
+ background: none;
+ border: medium;
+ cursor: pointer;
+ padding: 7px 6px;
+ border-radius: 6px;
+ transition: all 0.2s ease-in-out;
+ display: none;
+ background-color: var(--color-syntax-clipboard-bg);
+
+ svg {
+ width: 20px;
+ height: 20px;
+ opacity: 0.8;
+ }
+
+ &.copied {
+ svg {
+ color: var(--color-syntax-clipboard-check-color);
+ }
+ }
+
+ &:hover {
+ background-color: var(--color-syntax-clipboard-hover-bg);
+
+ svg {
+ opacity: 1;
+ }
+ }
+ }
+
+ &:hover {
+ button {
+ display: flex;
+ }
+ }
+}
+
+pre.highlight {
+ background: var(--color-code-background);
+ font-size: 14px;
+ line-height: 1.5;
+ overflow-x: auto;
+
+ .c, /* Comment */
+ .cm, /* Comment.Multiline */
+ .cp, /* Comment.Preproc */
+ .c1, /* Comment.Single */
+ .cs {
+ /* Comment.Special */
+ color: var(--color-syntax-comments);
+ }
+
+ .k, /* Keyword */
+ .kc, /* Keyword.Constant */
+ .kd, /* Keyword.Declaration */
+ .kp, /* Keyword.Pseudo */
+ .kr,
+ .kt, /* Keyword.Reserved */
+ .nb {
+ /* Name.Builtin */
+ color: var(--color-syntax-keywords);
+ }
+
+ .nv, /* Name.Variable */
+ .nf {
+ /* Name.Function */
+ color: var(--color-syntax-project-constants);
+ }
+
+ .n {
+ color: #b181ec;
+ }
+
+ .o,
+ .p {
+ color: var(--color-syntax-brackets-dots);
+ }
+
+ .s, /* Literal.String */
+ .sb, /* Literal.String.Backtick */
+ .sc, /* Literal.String.Char >> --color-syntax-characters */
+ .sd, /* Literal.String.Doc */
+ .s2, /* Literal.String.Double */
+ .se, /* Literal.String.Escape */
+ .sh, /* Literal.String.Heredoc */
+ .si, /* Literal.String.Interpol */
+ .s1, /* Literal.String.Single */
+ .sx {
+ /* Literal.String.Other */
+ color: var(--color-syntax-strings);
+ }
+
+ .na {
+ /* Name.Attribute */
+ color: var(--color-syntax-attributes);
+ }
+
+ .nc, /* Name.Class */
+ .ni, /* Name.Entity */
+ .no, /* Name.Constant */
+ .vc, /* Name.Variable.Class */
+ .vg, /* Name.Variable.Global */
+ .vi {
+ /* Name.Variable.Instance */
+ color: var(--color-syntax-other-type-names);
+ }
+
+ .err, /* Error */
+ .gr, /* Generic.Error */
+ .gt, /* Generic.Traceback */
+ .ne {
+ /* Name.Exception */
+ color: var(--color-syntax-strings);
+ }
+
+ .m, /* Literal.Number */
+ .mf, /* Literal.Number.Float */
+ .mh, /* Literal.Number.Hex */
+ .mi, /* Literal.Number.Integer */
+ .il, /* Literal.Number.Integer.Long */
+ .mo {
+ /* Literal.Number.Oct */
+ color: var(--color-syntax-numbers);
+ }
+
+ .ge {
+ /* Generic.Emph */
+ font-style: italic;
+ }
+
+ .nt {
+ /* Name.Tag */
+ color: var(--color-syntax-characters);
+ }
+
+ .gd, /* Generic.Deleted */
+ .gd .x {
+ /* Generic.Deleted.Specific */
+ color: var(--color-syntax-plain-text);
+ background-color: var(--color-fill-red-secondary);
+ }
+
+ .gi, /* Generic.Inserted */
+ .gi .x {
+ /* Generic.Inserted.Specific */
+ color: var(--color-syntax-plain-text);
+ background-color: var(--color-fill-green-secondary);
+ }
+
+ .gh, /* Generic.Heading */
+ .bp, /* Name.Builtin.Pseudo */
+ .go, /* Generic.Output */
+ .gp, /* Generic.Prompt */
+ .gu, /* Generic.Subheading */
+ .w {
+ /* Text.Whitespace */
+ color: var(--color-syntax-comments);
+ }
+
+ .nn {
+ /* Name.Namespace */
+ color: var(--color-syntax-other-declarations);
+ }
+
+ .sr {
+ /* Literal.String.Regex */
+ color: var(--color-figure-green);
+ }
+
+ .ss {
+ /* Literal.String.Symbol */
+ color: var(--color-syntax-heading);
+ }
+
+ /* Make prompts non-selectable, to make it easy to copy and paste */
+ .gp {
+ -webkit-user-select: none;
+ user-select: none;
+
+ & + .w {
+ -webkit-user-select: none;
+ user-select: none;
+ }
+ }
+}
+
+.language-console {
+ color: var(--color-syntax-plain-text);
+}
+
+// Explicit syntax highlighting for C++ code blocks:
+
+.language-cpp .cp,
+.language-cpp .kt,
+.language-cpp .nl,
+.language-cpp .o,
+.language-c\+\+ .cp,
+.language-c\+\+ .kt,
+.language-c\+\+ .nl,
+.language-c\+\+ .o {
+ color: var(--color-syntax-keywords);
+}
diff --git a/assets/stylesheets/new-stylesheets/_themes.scss b/assets/stylesheets/new-stylesheets/_themes.scss
new file mode 100644
index 000000000..715d4faa9
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/_themes.scss
@@ -0,0 +1,208 @@
+@mixin light-theme() {
+ --site-text-color: #051416;
+ --site-navigation-border-bottom: linear-gradient(
+ 0deg,
+ #f6b391 0%,
+ #f8ce6e 92%
+ );
+ --site-navigation-box-shadow:
+ rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px,
+ rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
+ --site-navigation-background: rgba(255, 255, 255, 0.5);
+ --site-navigation-text-color: #3d3d3d;
+ --site-navigation-item-background: rgba(0, 0, 0, 0.05);
+ --site-tabs-background: rgba(255, 255, 255, 0.8);
+ --site-tabs-active-background: #ffffff;
+ --site-navigation-menu-toggle-invert: invert(0);
+ --site-navigation-item-border: 1px solid #051416;
+ --site-code-box-text: #3d3d3d;
+ --site-link-with-right-arrow-color: #384fea;
+ --site-link-with-right-arrow-icon-filter: none;
+ --site-content-link-with-right-arrow-icon-filter: brightness(0);
+
+ --page-bg: #fff;
+
+ --exception-page-bg: #fac685;
+
+ --install-page-bg: linear-gradient(0deg, #f6b391 0%, #f8ce6e 92%);
+ --install-site-code-box-bg: #ffffff;
+ --install-site-code-box-pre-bg: #f2f2f2;
+ --install-release-box-th-bg: #f2f2f2;
+ --install-release-box-th-color: #333;
+ --install-release-box-tr-border-bottom: 1px solid #f2f2f2;
+ --install-release-box-tr-bg: #ffffff;
+
+ --get-started-page-bg: #fafafa;
+ --get-started-card-primary-bg: rgba(255, 255, 255, 0.9);
+ --get-started-card-secondary-bg: rgba(236, 236, 236, 1);
+ --get-started-boxes-bg: rgba(255, 255, 255, 0.5);
+ --get-started-code-box-pre-bg: #fff;
+ --get-started-code-box-pre-border: 1px solid #d5d5d5;
+
+ --homepage-hero-bg: linear-gradient(
+ 179deg,
+ #fac685 3%,
+ #fbdab0 87%,
+ #ffffff 100%
+ );
+ --homepage-install-text: #3d3d3d;
+ --homepage-pillar-1-bg: linear-gradient(
+ to bottom,
+ #ffffff 0%,
+ #d9f2ff 75%,
+ #fff3d8 90%
+ );
+ --homepage-pillar-2-bg: linear-gradient(
+ to top,
+ #e4937f 0%,
+ #fdd9a1 72%,
+ #fff3d8 100%
+ );
+ --homepage-pillar-3-bg: linear-gradient(
+ 180deg,
+ #e4937f 0%,
+ #a268c1 36%,
+ #4b3773 100%
+ );
+ --home-quicklinks-bg: rgba(255, 177, 100, 0.9);
+ --home-quicklinks-color: #801a1a;
+
+ // rubber band
+ --nav-scroller-gradient-start: #1e162e;
+ --nav-scroller-gradient-end: #fff;
+
+ // syntax
+ --color-syntax-clipboard-bg: rgb(223, 223, 247);
+ --color-syntax-clipboard-hover-bg: rgb(216, 216, 242);
+ --color-syntax-clipboard-check-color: rgb(12, 156, 12);
+
+ --color-syntax-attributes: rgb(148, 113, 0);
+ --color-syntax-characters: rgb(39, 42, 216);
+ --color-syntax-comments: rgb(112, 127, 140);
+ --color-syntax-documentation-markup: rgb(80, 99, 117);
+ --color-syntax-documentation-markup-keywords: rgb(80, 99, 117);
+ --color-syntax-brackets-dots: rgba(45, 100, 105);
+ --color-syntax-heading: rgb(186, 45, 162);
+ --color-syntax-keywords: rgb(173, 61, 164);
+ --color-syntax-marks: rgb(0, 0, 0);
+ --color-syntax-numbers: rgb(39, 42, 216);
+ --color-syntax-other-class-names: rgb(112, 61, 170);
+ --color-syntax-other-constants: rgb(75, 33, 176);
+ --color-syntax-other-declarations: rgb(4, 124, 176);
+ --color-syntax-other-function-and-method-names: rgb(75, 33, 176);
+ --color-syntax-other-instance-variables-and-globals: rgb(112, 61, 170);
+ --color-syntax-other-preprocessor-macros: rgb(120, 73, 42);
+ --color-syntax-other-type-names: rgb(112, 61, 170);
+ --color-syntax-param-internal-name: rgb(64, 64, 64);
+ --color-syntax-plain-text: rgb(0, 0, 0);
+ --color-syntax-preprocessor-statements: rgb(120, 73, 42);
+ --color-syntax-project-class-names: rgb(62, 128, 135);
+ --color-syntax-project-constants: rgb(45, 100, 105);
+ --color-syntax-project-function-and-method-names: rgb(45, 100, 105);
+ --color-syntax-project-instance-variables-and-globals: rgb(62, 128, 135);
+ --color-syntax-project-preprocessor-macros: rgb(120, 73, 42);
+ --color-syntax-project-type-names: rgb(62, 128, 135);
+ --color-syntax-strings: rgb(209, 47, 27);
+ --color-syntax-type-declarations: rgb(3, 99, 140);
+ --color-syntax-urls: rgb(19, 55, 255);
+}
+
+@mixin dark-theme() {
+ --site-text-color: #ffffff;
+ --site-navigation-border-bottom: 0;
+ --site-navigation-box-shadow: none;
+ --site-navigation-background: rgba(0, 0, 0, 0.3);
+ --site-navigation-text-color: #ffffff;
+ --site-navigation-item-background: rgba(0, 0, 0, 0.4);
+ --site-tabs-background: rgba(35, 52, 74, 1);
+ --site-tabs-active-background: #505f83;
+ --site-navigation-menu-toggle-invert: invert(1);
+ --site-navigation-item-border: 1px solid #ffffff;
+ --site-code-box-text: #ffffff;
+ --site-link-with-right-arrow-color: #1ec1fd;
+ --site-link-with-right-arrow-icon-filter: invert(66%) sepia(89%)
+ saturate(602%) hue-rotate(172deg) brightness(102%) contrast(101%);
+ --site-content-link-with-right-arrow-icon-filter: brightness(0) invert(1);
+
+ --page-bg: #fff;
+
+ --exception-page-bg: #23344a;
+
+ --install-page-bg: linear-gradient(0deg, #ff8115 0%, #b7451b 92%);
+ --install-site-code-box-bg: #23344a;
+ --install-site-code-box-pre-bg: #111727;
+ --install-release-box-th-bg: #111727;
+ --install-release-box-th-color: #ffffff;
+ --install-release-box-tr-border-bottom: 1px solid #051416;
+ --install-release-box-tr-bg: #384461;
+
+ --get-started-page-bg: rgb(5, 20, 35);
+ --get-started-card-primary-bg: rgba(35, 52, 74, 0.9);
+ --get-started-card-secondary-bg: rgba(56, 68, 97, 1);
+ --get-started-boxes-bg: rgba(25, 52, 74, 0.5);
+ --get-started-code-box-pre-bg: #111727;
+ --get-started-code-box-pre-border: 1px solid #575757;
+
+ --homepage-install-text: #dedede;
+ --homepage-hero-bg: linear-gradient(
+ 180deg,
+ #144173 0%,
+ #141228 68%,
+ #144173 99%
+ );
+ --homepage-pillar-1-bg: linear-gradient(
+ 179deg,
+ #144173 1%,
+ #000000 57%,
+ #350839 88%,
+ #df6b40 99%
+ );
+ --homepage-pillar-2-bg: linear-gradient(0deg, #ffac64 0, #df6b40 100%);
+ --homepage-pillar-3-bg: linear-gradient(
+ 180deg,
+ #ffac64 0%,
+ #a268c1 28%,
+ #4b3773 100%
+ );
+
+ --home-quicklinks-bg: #23344a;
+ --home-quicklinks-color: #ffffff;
+
+ // rubber band
+ --nav-scroller-gradient-start: #1e162e;
+ --nav-scroller-gradient-end: #000;
+
+ // syntax
+ --color-syntax-clipboard-bg: rgb(71, 79, 110);
+ --color-syntax-clipboard-hover-bg: rgb(80, 89, 124);
+ --color-syntax-clipboard-check-color: rgb(11, 242, 11);
+
+ --color-syntax-attributes: rgb(204, 151, 104);
+ --color-syntax-characters: rgb(217, 201, 124);
+ --color-syntax-comments: rgb(127, 140, 152);
+ --color-syntax-documentation-markup: rgb(127, 140, 152);
+ --color-syntax-documentation-markup-keywords: rgb(163, 177, 191);
+ --color-syntax-brackets-dots: rgba(255, 255, 255);
+ --color-syntax-keywords: rgb(255, 121, 179);
+ --color-syntax-marks: rgb(255, 255, 255);
+ --color-syntax-numbers: rgb(217, 201, 124);
+ --color-syntax-other-class-names: rgb(218, 186, 255);
+ --color-syntax-other-constants: rgb(167, 235, 221);
+ --color-syntax-other-declarations: rgb(78, 176, 204);
+ --color-syntax-other-function-and-method-names: rgb(178, 129, 235);
+ --color-syntax-other-instance-variables-and-globals: rgb(178, 129, 235);
+ --color-syntax-other-preprocessor-macros: rgb(255, 161, 79);
+ --color-syntax-other-type-names: rgb(218, 186, 255);
+ --color-syntax-param-internal-name: rgb(191, 191, 191);
+ --color-syntax-plain-text: rgb(255, 255, 255);
+ --color-syntax-preprocessor-statements: rgb(255, 161, 79);
+ --color-syntax-project-class-names: rgb(172, 242, 228);
+ --color-syntax-project-constants: rgb(120, 194, 179);
+ --color-syntax-project-function-and-method-names: rgb(120, 194, 179);
+ --color-syntax-project-instance-variables-and-globals: rgb(120, 194, 179);
+ --color-syntax-project-preprocessor-macros: rgb(255, 161, 79);
+ --color-syntax-project-type-names: rgb(172, 242, 228);
+ --color-syntax-strings: rgb(255, 129, 112);
+ --color-syntax-type-declarations: rgb(107, 223, 255);
+ --color-syntax-urls: rgb(102, 153, 255);
+}
diff --git a/assets/stylesheets/new-stylesheets/application.scss b/assets/stylesheets/new-stylesheets/application.scss
new file mode 100644
index 000000000..8b867eb16
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/application.scss
@@ -0,0 +1,8 @@
+---
+layout: source
+---
+
+@use 'core';
+@use 'syntax';
+@use 'includes';
+@use 'pages';
diff --git a/assets/stylesheets/new-stylesheets/elements/_os-selection-navigation.scss b/assets/stylesheets/new-stylesheets/elements/_os-selection-navigation.scss
new file mode 100644
index 000000000..19a7ed2e8
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/elements/_os-selection-navigation.scss
@@ -0,0 +1,85 @@
+@use '../helpers' as *;
+
+.os-selection-navigation {
+ max-width: 980px;
+ width: 100%;
+ margin: 0 auto;
+ color: white;
+ box-sizing: border-box;
+ padding-bottom: 20px;
+ position: relative;
+ z-index: 2;
+
+ h1 {
+ font-size: 48px;
+ // TODO double check lineheight
+ line-height: 1.2;
+ margin-bottom: 25px;
+ text-align: center;
+ color: var(--site-text-color);
+ }
+
+ @media only screen and (max-width: 1024px) {
+ padding: 0 20px;
+ }
+
+ & > h1 {
+ font-size: 44px;
+ }
+
+ & > h2 {
+ color: var(--site-text-color);
+ margin-top: 60px;
+ }
+
+ & > p {
+ font-size: 1.4em;
+ margin: 20px 0 40px;
+ }
+
+ a {
+ color: white;
+ }
+
+ label {
+ margin: 10px 0 20px;
+ display: block;
+ color: var(--site-text-color);
+ }
+
+ .tab-nav {
+ @media only screen and (max-width: 1024px) {
+ max-width: 100%;
+ }
+
+ .tabs {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ width: fit-content;
+ margin: auto;
+ background: var(--site-tabs-background);
+ border-radius: 10px;
+
+ a {
+ text-align: center;
+ padding: 8px 18px;
+ color: var(--site-text-color);
+ text-decoration: none;
+ font-weight: 400;
+
+ &.active {
+ background: var(--site-tabs-active-background);
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.08);
+ border-radius: 10px;
+ color: var(--site-text-color);;
+ font-weight: 600;
+ }
+ }
+
+ @media only screen and (max-width: 1024px) {
+ gap: 6px;
+ }
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/_callout.scss b/assets/stylesheets/new-stylesheets/includes/_callout.scss
new file mode 100644
index 000000000..16075503b
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_callout.scss
@@ -0,0 +1,2 @@
+@use 'callout/base' as calloutBase;
+@use 'callout/mobile' as calloutMobile;
diff --git a/assets/stylesheets/new-stylesheets/includes/_carousel.scss b/assets/stylesheets/new-stylesheets/includes/_carousel.scss
new file mode 100644
index 000000000..53974c8c6
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_carousel.scss
@@ -0,0 +1 @@
+@use 'carousel/base' as carouselBase;
diff --git a/assets/stylesheets/new-stylesheets/includes/_footer.scss b/assets/stylesheets/new-stylesheets/includes/_footer.scss
new file mode 100644
index 000000000..97e63e377
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_footer.scss
@@ -0,0 +1,3 @@
+@use 'footer/base' as footerBase;
+@use 'footer/mobile' as footerMobile;
+@use 'footer/theme' as footerTheme;
diff --git a/assets/stylesheets/new-stylesheets/includes/_header.scss b/assets/stylesheets/new-stylesheets/includes/_header.scss
new file mode 100644
index 000000000..17e83124f
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_header.scss
@@ -0,0 +1 @@
+@use 'header/theme' as headerTheme;
diff --git a/assets/stylesheets/new-stylesheets/includes/_interactive-tabs.scss b/assets/stylesheets/new-stylesheets/includes/_interactive-tabs.scss
new file mode 100644
index 000000000..fd1c496cc
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_interactive-tabs.scss
@@ -0,0 +1 @@
+@use 'interactive-tabs/base' as interactiveTabsBase;
diff --git a/assets/stylesheets/new-stylesheets/includes/_navigation.scss b/assets/stylesheets/new-stylesheets/includes/_navigation.scss
new file mode 100644
index 000000000..d73f79c6a
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_navigation.scss
@@ -0,0 +1,3 @@
+@use 'navigation/base' as navigationBase;
+@use 'navigation/mobile' as navigationMobile;
+@use 'navigation/theme' as navigationTheme;
diff --git a/assets/stylesheets/new-stylesheets/includes/_overlapping-containers.scss b/assets/stylesheets/new-stylesheets/includes/_overlapping-containers.scss
new file mode 100644
index 000000000..0602db12d
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/_overlapping-containers.scss
@@ -0,0 +1,2 @@
+@use 'overlapping-containers/base' as overlappingContainersBase;
+@use 'overlapping-containers/mobile' as overlappingContainersMobile;
diff --git a/assets/stylesheets/new-stylesheets/includes/callout/_base.scss b/assets/stylesheets/new-stylesheets/includes/callout/_base.scss
new file mode 100644
index 000000000..542fdc1df
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/callout/_base.scss
@@ -0,0 +1,79 @@
+@use '../../helpers' as *;
+
+.callout {
+ gap: 40px;
+ align-items: flex-start;
+ padding: 1em;
+ margin: 2.5em auto;
+ max-width: 980px;
+ box-sizing: border-box;
+ text-align: center;
+
+ > div {
+ min-width: 0;
+ }
+
+ &.with-code {
+ display: grid;
+ grid-template-columns: 2.2fr 3.2fr;
+ text-align: left;
+
+ .text {
+ width: 100%;
+ }
+
+ .code {
+ width: 100%;
+ pre.highlight {
+ border: 1px solid #d5d5d5;
+ }
+ }
+ }
+
+ .links {
+ margin-top: 30px;
+
+ a {
+ @include link-with-right-arrow();
+ display: block;
+ color: white;
+ @include underline;
+ margin-top: 14px;
+
+ i {
+ filter: brightness(0) invert(1);
+ }
+ }
+ }
+}
+
+.callout.reverse {
+ direction: rtl;
+}
+
+.callout.reverse > * {
+ direction: ltr;
+}
+
+.callout-title {
+ margin: -4px 0 3px;
+ font-size: 48px;
+ font-weight: 600;
+ line-height: 1.2;
+}
+
+.callout-subtitle {
+ line-height: 1.25;
+ margin-bottom: 4px;
+ font-size: 24px;
+}
+
+.callout-text {
+ text-align: left;
+}
+
+.hide-small {
+ @media only screen and (max-width: 767px) {
+ display: none;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/callout/_mobile.scss b/assets/stylesheets/new-stylesheets/includes/callout/_mobile.scss
new file mode 100644
index 000000000..d8b823d3a
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/callout/_mobile.scss
@@ -0,0 +1,5 @@
+@media only screen and (max-width: 1024px) {
+ .callout.with-code {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/carousel/_base.scss b/assets/stylesheets/new-stylesheets/includes/carousel/_base.scss
new file mode 100644
index 000000000..532c17f20
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/carousel/_base.scss
@@ -0,0 +1,56 @@
+.carousel-container {
+ width: 100%;
+ max-width: 100vw;
+ margin: auto;
+}
+
+.carousel {
+ overflow-x: auto;
+ scroll-snap-type: x mandatory;
+ -webkit-overflow-scrolling: touch;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+
+.carousel::-webkit-scrollbar {
+ display: none;
+}
+
+.carousel-track {
+ display: flex;
+ gap: 1rem;
+ padding: 1rem 0;
+}
+
+.carousel-item {
+ scroll-snap-align: start;
+ flex: 0 0 calc((100% - 3rem) / 3.5);
+ background-color: #f3f4f6;
+ border-radius: 10px;
+ padding: 2rem;
+ min-height: 250px;
+ font-size: 1.2rem;
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
+ box-sizing: border-box;
+}
+
+.carousel-buttons {
+ text-align: center;
+ margin-top: 1rem;
+}
+
+.carousel-btn {
+ padding: 0.75rem 1.5rem;
+ margin: 0 0.5rem;
+ border: none;
+ border-radius: 8px;
+ background-color: #e5e7eb;
+ font-size: 1.2rem;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+
+.carousel-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/footer/_base.scss b/assets/stylesheets/new-stylesheets/includes/footer/_base.scss
new file mode 100644
index 000000000..a199674f4
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/footer/_base.scss
@@ -0,0 +1,230 @@
+@use '../../colors' as *;
+@use '../../graphics' as *;
+@use '../../helpers' as *;
+
+@mixin icon-style($icon) {
+ width: 22px;
+ height: 22px;
+ background-repeat: no-repeat;
+ background-size: 22px;
+ display: block;
+ background-image: $icon;
+}
+
+footer.global-footer {
+ background-color: #1e162e;
+ padding: 20px;
+ text-align: center;
+ padding: 6rem 3rem 3rem 3.5em;
+ color: rgb(235, 236, 240);
+ position: relative;
+ z-index: 10;
+
+ .container {
+ max-width: 980px;
+ margin: 0 auto;
+ }
+
+ .footer-navigation-container {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ margin-bottom: 5em;
+
+ .logo {
+ display: flex;
+ height: 36px;
+ margin-bottom: 15px;
+
+ svg {
+ height: 100%;
+ }
+
+ #logotype {
+ fill: #ebecf0;
+ }
+ }
+
+ h3 {
+ height: 36px;
+ margin-bottom: 15px;
+ color: #fca76c;
+ font-size: 1.17em;
+ line-height: 1.2;
+ font-weight: bold;
+ display: flex;
+ align-items: center;
+ }
+
+ nav {
+ margin-bottom: 20px;
+ text-align: left;
+
+ ul {
+ list-style: none;
+ padding: 0;
+
+ li {
+ a {
+ font-size: 14px;
+ border-bottom: 1px solid transparent;
+ color: rgb(235, 236, 240);
+ display: inline-block;
+ padding: 0.35em 0;
+
+ &:hover {
+ border-bottom-color: rgb(235, 236, 240);
+ }
+ }
+ }
+ }
+
+ &.governance {
+ display: flex;
+ flex-direction: column;
+
+ // theme toggle
+ .color-scheme-toggle {
+ display: inline-flex;
+ font-size: 14px;
+ border: 1px solid #d1d2d4;
+ border-radius: 15px;
+ padding: 1px;
+ outline: none;
+ margin-top: auto;
+
+ input,
+ legend {
+ @include visuallyhidden;
+ appearance: none;
+ }
+
+ .scheme-light {
+ .color-scheme-toggle-label {
+ border-top-left-radius: 15px;
+ border-bottom-left-radius: 15px;
+ }
+ }
+
+ .scheme-auto-wrapper {
+ .color-scheme-toggle-label {
+ border-top-right-radius: 15px;
+ border-bottom-right-radius: 15px;
+ }
+ }
+ }
+
+ .color-scheme-toggle-label {
+ border: 1px solid transparent;
+ background-color: #1e162e;
+ color: #d1d2d4;
+ display: inline-block;
+ text-align: center;
+ padding: 1px 6px;
+ min-width: 42px;
+ box-sizing: border-box;
+ transition: background-color 0.3s ease;
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ input:checked + .color-scheme-toggle-label {
+ background: #fca76c;
+ color: #1e162e;
+ }
+ }
+ }
+ }
+
+ .sub-navigation {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ align-items: flex-end;
+ color: #d1d2d4;
+
+ nav {
+ display: inline-block;
+
+ ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: inline-flex;
+
+ a {
+ color: #d1d2d4;
+ }
+ }
+ }
+
+ .legals {
+ font-size: 11px;
+ text-align: left;
+
+ .copyright {
+ margin-bottom: 1.5em;
+ line-height: 1.5em;
+
+ p {
+ margin: 0;
+ }
+
+ a {
+ color: #d1d2d4;
+ }
+ }
+
+ nav ul {
+ li {
+ margin-right: 1.75em;
+
+ a {
+ padding: 0.35em 0;
+ border-bottom: 1px solid transparent;
+
+ &:hover {
+ border-bottom-color: #d1d2d4;
+ }
+ }
+ }
+ }
+ }
+
+ .socials {
+ ul li a {
+ display: block;
+ padding: 0 0.6em;
+
+ &:hover {
+ // color: #ebecf0;
+ // color: red;
+ }
+
+ i {
+ &.github {
+ @include icon-style($icon-github);
+ }
+
+ &.bluesky {
+ @include icon-style($icon-bluesky);
+ }
+
+ &.feed {
+ @include icon-style($icon-feed);
+ }
+
+ &.mastodon {
+ @include icon-style($icon-mastodon);
+ }
+
+ &.x {
+ @include icon-style($icon-x);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/footer/_mobile.scss b/assets/stylesheets/new-stylesheets/includes/footer/_mobile.scss
new file mode 100644
index 000000000..2e6ebfd90
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/footer/_mobile.scss
@@ -0,0 +1,41 @@
+@media only screen and (max-width: 1024px) {
+ footer.global-footer {
+ .footer-navigation-container {
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 3em;
+
+ .logo {
+ margin-bottom: 3em;
+ }
+
+ h3 {
+ height: auto;
+ display: block;
+ align-items: unset;
+ }
+
+ nav {
+ text-align: center;
+ margin-bottom: 30px;
+
+ &.governance {
+ // theme toggle
+ .color-scheme-toggle {
+ margin-top: 3em;
+ }
+ }
+ }
+ }
+
+ .sub-navigation {
+ flex-direction: column;
+ align-items: center;
+
+ .legals {
+ text-align: center;
+ margin-bottom: 50px;
+ }
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/footer/_theme.scss b/assets/stylesheets/new-stylesheets/includes/footer/_theme.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/assets/stylesheets/new-stylesheets/includes/header/_theme.scss b/assets/stylesheets/new-stylesheets/includes/header/_theme.scss
new file mode 100644
index 000000000..14a2c9aa7
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/header/_theme.scss
@@ -0,0 +1,7 @@
+body[data-color-scheme="dark"] .logo svg #logotype {
+ fill: #ffffff;
+}
+
+body[data-color-scheme="light"] .logo svg #logotype {
+ fill: #000000;
+}
\ No newline at end of file
diff --git a/assets/stylesheets/new-stylesheets/includes/interactive-tabs/_base.scss b/assets/stylesheets/new-stylesheets/includes/interactive-tabs/_base.scss
new file mode 100644
index 000000000..2f9d26f6f
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/interactive-tabs/_base.scss
@@ -0,0 +1,17 @@
+.interactive-tabs .tabs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.interactive-tabs .tabs a {
+ padding: 0.4rem 0.8rem;
+ text-decoration: none;
+ font-family: sans-serif;
+ color: white;
+}
+
+.interactive-tabs .tabs a[aria-pressed='true'] {
+ color: white;
+ border-bottom: 1px solid white;
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/navigation/_base.scss b/assets/stylesheets/new-stylesheets/includes/navigation/_base.scss
new file mode 100644
index 000000000..1619a0889
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/navigation/_base.scss
@@ -0,0 +1,108 @@
+@use '../../colors' as *;
+@use '../../helpers' as *;
+@use '../../graphics' as *;
+@use '../../themes' as *;
+
+.site-navigation {
+ position: fixed;
+ width: 100%;
+ top: 0;
+ z-index: 9999;
+ line-height: initial;
+ background: var(--site-navigation-background);
+ backdrop-filter: blur(20px);
+ border-bottom: var(--site-navigation-border-bottom);
+ box-shadow: var(--site-navigation-box-shadow);
+
+ .wrapper {
+ @include flex-between;
+ max-width: 1234px;
+ padding: 0 20px;
+ margin: 0 auto;
+ }
+
+ .logo {
+ margin: 0;
+
+ a {
+ display: flex;
+ width: 116px;
+
+ svg {
+ flex: 1;
+ }
+ }
+ }
+
+ // hide mobile navigation
+ .menu-toggle,
+ .mobile-navigation {
+ display: none;
+ }
+
+ .navigation-items {
+ display: flex;
+ list-style: none;
+
+ li {
+ a {
+ display: block;
+ padding: 22px 5px;
+ font-size: 19px;
+ color: var(--site-navigation-text-color);
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease; // smooth hover
+
+ & > span {
+ padding: 12px 15px;
+ border-radius: 36px;
+ }
+
+ // hover/focus states
+ &:hover,
+ &:focus {
+ outline: none; // basic focus outline removal
+
+ & > span {
+ background-color: var(--site-navigation-item-background);
+ }
+ }
+
+ // visual focus indicator for accessibility
+ &:focus-visible {
+ outline: 2px solid dodgerblue;
+ outline-offset: 2px;
+ }
+ }
+
+ &.active {
+ a {
+ outline: none; // basic focus outline removal
+
+ & > span {
+ background-color: rgba(230, 150, 80, .9);
+ }
+ }
+ }
+ }
+ }
+
+ // use a border to separate "Install"
+ .desktop-navigation {
+ .navigation-items {
+ li.border {
+ display: flex;
+ align-items: center;
+ padding: 0 15px;
+
+ span {
+ display: block;
+ width: 2px;
+ height: 18px;
+ background-color: var(--site-navigation-text-color);
+ }
+ }
+ }
+ }
+} // .site-navigation
diff --git a/assets/stylesheets/new-stylesheets/includes/navigation/_mobile.scss b/assets/stylesheets/new-stylesheets/includes/navigation/_mobile.scss
new file mode 100644
index 000000000..0a58462eb
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/navigation/_mobile.scss
@@ -0,0 +1,60 @@
+@use '../../colors' as *;
+@use '../../helpers' as *;
+@use '../../graphics' as *;
+
+@media only screen and (max-width: 1024px) {
+ .site-navigation {
+
+ // hide desktop navigation
+ .desktop-navigation {
+ display: none;
+ }
+
+ .menu-toggle {
+ display: inline-block;
+ @include mobile-toggle-btn($menu-icon-close);
+ filter: var(--site-navigation-menu-toggle-invert);
+ padding: 33px 0;
+
+ &.open {
+ background-image: $menu-icon;
+ }
+ }
+
+ .mobile-navigation {
+ &.open {
+ display: block;
+ }
+
+ .navigation-items {
+ display: block;
+
+ li {
+ display: block;
+ border-top: var(--site-navigation-item-border);
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ a {
+ padding: 0;
+ display: block;
+
+ & > span {
+ padding: 1rem;
+ border-radius: 0;
+ display: block;
+ }
+ }
+
+ &.border {
+ display: none;
+ }
+ }
+ }
+ } // .mobile-navigation
+
+ } // .site-navigation
+
+} // max-width: 1024px
\ No newline at end of file
diff --git a/assets/stylesheets/new-stylesheets/includes/navigation/_theme.scss b/assets/stylesheets/new-stylesheets/includes/navigation/_theme.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_base.scss b/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_base.scss
new file mode 100644
index 000000000..54e5f6f2d
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_base.scss
@@ -0,0 +1,34 @@
+.overlapping-containers {
+ position: relative;
+ width: fit-content;
+ margin: 0 auto;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ max-width: 1024px;
+
+ .box-left {
+ background: white;
+ width: 50%;
+ padding: 1rem 1.5rem;
+ font-size: 1rem;
+ display: inline-block;
+ position: relative;
+ z-index: 2;
+ }
+
+ .box-right {
+ background: rgba(0, 0, 0, 0.7);
+ width: 50%;
+ color: white;
+ padding: 3rem 1rem 3rem 12rem;
+ display: inline-block;
+ position: relative;
+ z-index: 1;
+ font-size: 1rem;
+ line-height: 1.5;
+ margin-left: -10rem;
+ text-align: left;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_mobile.scss b/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_mobile.scss
new file mode 100644
index 000000000..083a038aa
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/includes/overlapping-containers/_mobile.scss
@@ -0,0 +1,20 @@
+@media only screen and (max-width: 1024px) {
+ .overlapping-containers {
+ max-width: 100%;
+ flex-direction: column;
+ margin: 0 20px;
+
+ .box-left {
+ width: 100%;
+ box-sizing: border-box;
+ margin-bottom: 20px;
+ }
+
+ .box-right {
+ width: 100%;
+ box-sizing: border-box;
+ margin-left: 0;
+ padding-left: 1rem;
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/pages/_exception.scss b/assets/stylesheets/new-stylesheets/pages/_exception.scss
new file mode 100644
index 000000000..325592775
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/pages/_exception.scss
@@ -0,0 +1,22 @@
+#exception {
+ display: flex;
+ flex-direction: column;
+ background-color: var(--exception-page-bg);
+ color: var(--site-text-color);
+
+ .content {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ padding: 18vw 0;
+
+ h1 {
+ font-size: 48px;
+ }
+
+ @media only screen and (max-width: 1024px) {
+ margin: 90px 0;
+ }
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/pages/_get-started.scss b/assets/stylesheets/new-stylesheets/pages/_get-started.scss
new file mode 100644
index 000000000..2c27a130e
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/pages/_get-started.scss
@@ -0,0 +1,975 @@
+@use '../helpers' as *;
+
+.get-started {
+ color: var(--site-text-color);
+ position: relative;
+ background: var(--get-started-page-bg);
+ @include noise();
+}
+
+.content-wrapper {
+ width: min(980px, calc(100vw - 20px));
+ margin: auto;
+ // to place above noise
+ position: relative;
+ z-index: 1;
+}
+
+.hero-card {
+ aspect-ratio: 980 / 473;
+ border-radius: 22px;
+ overflow: hidden;
+ margin-bottom: 50px;
+ position: relative;
+ z-index: 2;
+}
+
+#get-started-hero {
+ position: relative;
+ background-image: linear-gradient(-16deg, #c49db2 1%, #7959d3 70%);
+ padding: 160px 0 100px;
+
+ .hero-content {
+ margin-left: 10px;
+ margin-right: 10px;
+
+ & > a {
+ @include big-button();
+ background-image: linear-gradient(to bottom right, #b0585e, #fd8d81);
+ padding: 15px 41px;
+ font-size: 28px;
+ }
+
+ h1 {
+ font-size: 48px;
+ font-weight: 600;
+ color: white;
+ letter-spacing: 0;
+ text-align: center;
+ margin-bottom: 20px;
+ position: relative;
+ z-index: 1;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ > p {
+ font-size: 24px;
+ color: white;
+ font-weight: 500;
+ margin-bottom: 60px;
+ z-index: 1;
+ position: relative;
+ max-width: 980px;
+ margin: auto;
+ }
+
+ ul {
+ max-width: 980px;
+ margin: 80px auto 40px;
+ position: relative;
+ z-index: 5;
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 20px;
+
+ @media only screen and (max-width: 768px) {
+ & {
+ grid-template-columns: 1fr;
+ }
+ }
+
+ li {
+ display: inline-block;
+ font-weight: 400;
+ padding: 16px 16px 20px;
+ background-color: var(--get-started-boxes-bg);
+ border-radius: 20px;
+ font-size: 14px;
+ white-space: nowrap;
+
+ span {
+ display: block;
+ text-align: left;
+
+ &.title {
+ font-size: 24px;
+ font-weight: 600;
+ margin-bottom: 10px;
+ line-height: 1.2;
+ }
+
+ &.text {
+ font-size: 14px;
+ white-space: normal;
+ line-height: 1.3;
+ }
+ }
+ }
+ }
+
+ .swoop {
+ z-index: 1;
+
+ &.swoop-1 {
+ @include swoop-ratio(2624, 1073, 1.33);
+ background-size: 144% auto;
+ background-position: 0% 0%;
+ top: -60vw;
+ background-image: url(/assets/images/get-started/cloud-services-hero-top.png);
+ }
+
+ &.swoop-2 {
+ aspect-ratio: 2271 / 682;
+ bottom: -6vw;
+ left: 0;
+ background: url(/assets/images/get-started/hero-bottom.png);
+ background-size: cover;
+ z-index: 0;
+ }
+ }
+ }
+}
+
+.card-grid {
+ line-height: 1.53;
+ margin-bottom: 50px;
+
+ .content {
+ padding: 30px 50px 20px;
+ background-color: var(--get-started-card-primary-bg);
+ max-width: 980px;
+ margin: 0 auto;
+ z-index: 3;
+ box-sizing: border-box;
+ position: relative;
+ border-radius: 22px;
+
+ @media only screen and (max-width: 1024px) {
+ width: auto;
+ margin: 0 10px;
+ }
+
+ @media only screen and (max-width: 768px) {
+ padding: 22px 15px 10px;
+ }
+
+ .section-icon {
+ width: 60px;
+ margin: 40px 0 0;
+ }
+
+ h2 {
+ text-align: center;
+ font-size: 48px;
+ margin-bottom: 52px;
+ color: var(--site-text-color);
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ margin-bottom: 22px;
+ }
+ }
+
+ a {
+ @include link-with-right-arrow();
+
+ @media only screen and (max-width: 768px) {
+ padding-bottom: 15px;
+ }
+ }
+
+ .primary-cards,
+ .secondary-cards,
+ .tertiary-cards {
+ margin-bottom: 22px;
+ li {
+ border-radius: 22px;
+ }
+ }
+
+ .secondary-cards {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+
+ li {
+ background-color: var(--get-started-card-secondary-bg);
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ min-height: 140px;
+ text-align: left;
+ border-radius: 22px;
+ overflow: hidden;
+
+ @media only screen and (max-width: 768px) {
+ flex-direction: column;
+ }
+
+ img {
+ width: 168px;
+ height: 180px;
+ object-fit: cover;
+ flex-shrink: 0;
+ background-color: #f6f6f6;
+
+ @media only screen and (max-width: 768px) {
+ width: 100%;
+ height: auto;
+ }
+ }
+
+ div {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 140px;
+ position: relative;
+ padding: 20px;
+
+ .name {
+ font-size: 24px;
+ line-height: 1.25;
+ margin-bottom: 10px;
+ }
+
+ .text {
+ font-size: 17px;
+ flex-grow: 1;
+ }
+ }
+ }
+ }
+
+ .tertiary-cards,
+ .primary-cards {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 20px;
+ // padding: 0 0 40px;
+
+ li {
+ background-color: var(--get-started-card-secondary-bg);
+ padding: 20px 30px 20px 20px;
+ display: flex;
+ text-align: left;
+
+ div {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ position: relative;
+
+ .name {
+ font-size: 24px;
+ line-height: 1.25;
+ margin-bottom: 10px;
+ }
+
+ .text {
+ font-size: 17px;
+ flex-grow: 1;
+ }
+ }
+ }
+
+ @media only screen and (max-width: 768px) {
+ grid-template-columns: 1fr;
+ }
+ }
+
+ .tertiary-cards {
+ img {
+ width: 45px;
+ height: 45px;
+ border-radius: 8px;
+ margin-right: 13px;
+ }
+ }
+
+ .primary-cards {
+ gap: 16px;
+
+ li {
+ flex-direction: column;
+ background: none;
+ padding: 0;
+
+ div {
+ background: none;
+
+ .name {
+ margin-bottom: 6px;
+ }
+
+ .text {
+ margin-bottom: 5px;
+ }
+ }
+ }
+
+ img {
+ aspect-ratio: 430 / 273;
+ object-fit: cover;
+ border-radius: 22px;
+ margin-bottom: 19px;
+ }
+ }
+ }
+}
+
+.image-text-row {
+ margin: 60px auto 70px;
+
+ &.background {
+ border-radius: 22px;
+ padding: 28px 50px 25px 50px;
+ background: var(--get-started-card-primary-bg);
+ box-sizing: border-box;
+
+ .card-wrapper:first-child {
+ // Maintain vertical space when there is no headline
+ margin-top: 10px;
+ }
+
+ @media only screen and (max-width: 768px) {
+ padding-bottom: 8px;
+
+ .card-wrapper:first-child {
+ // Maintain vertical space when there is no headline
+ margin-top: 0;
+ }
+ }
+ }
+
+ h2 {
+ font-size: 48px;
+ line-height: 1.2;
+ margin-bottom: 44px;
+ width: 100%;
+ text-align: center;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ .card-wrapper {
+ display: flex;
+ align-items: stretch;
+ }
+
+ img {
+ width: 350px;
+ object-fit: contain;
+ object-position: center;
+ }
+
+ h3 {
+ margin-bottom: 8px;
+ font-weight: 600;
+ }
+
+ h3,
+ span {
+ text-align: left;
+ font-size: 10px;
+ font-weight: 400;
+ }
+
+ .copy-wrapper {
+ border-radius: 4px;
+ padding: 3px 27px 19px 35px;
+ text-align: left;
+
+ h3 {
+ font-size: 22px;
+ font-weight: 600;
+ }
+
+ h3 {
+ margin-bottom: 17px;
+ }
+
+ p {
+ margin-bottom: 25px;
+ }
+
+ a {
+ @include link-with-right-arrow();
+ margin-top: 2px;
+ }
+ }
+
+ @media only screen and (max-width: 768px) {
+ .card-wrapper {
+ flex-direction: column;
+ }
+
+ img {
+ width: 100%;
+ margin-bottom: 20px;
+ }
+ }
+}
+
+.code-box {
+ // TODO consolidate styles from pages and move into elements partial
+ background-color: var(--install-site-code-box-bg);
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ text-align: left;
+ padding: 37px 50px 41px 50px;
+ margin-bottom: 70px;
+ box-sizing: border-box;
+ border-radius: 22px;
+
+ pre {
+ max-height: 400px;
+ border: var(--get-started-code-box-pre-border);
+
+ code {
+ white-space: pre-wrap;
+ }
+ }
+
+ &.code-box-with-tabs {
+ overflow: hidden;
+
+ h2 {
+ font-size: 22px;
+ line-height: 1.2;
+ margin-bottom: 5px;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ pre {
+ display: none;
+
+ &.active {
+ display: block;
+ }
+ }
+ }
+
+ &-tabs {
+ margin-bottom: 20px;
+ padding-left: 0 !important;
+
+ button {
+ outline: none;
+ border: none;
+ background: none;
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ li {
+ display: inline-block;
+ padding: 5px;
+
+ &.active {
+ border-bottom: 2px solid #8d8d8d;
+ margin-bottom: -1px;
+ }
+ }
+
+ @media only screen and (max-width: 768px) {
+ overflow: scroll;
+ padding-bottom: 1px;
+ }
+ }
+
+ .link-wrapper {
+ display: flex;
+ flex-direction: column;
+
+ a {
+ text-align: left;
+ margin-bottom: 10px;
+ }
+ }
+
+ .link-group {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ }
+
+ .link-single {
+ display: flex;
+ }
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 27px;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ p,
+ a {
+ font-size: 17px;
+ }
+
+ p {
+ margin-bottom: 26px;
+ }
+
+ pre {
+ border-radius: 22px;
+ background: var(--install-site-code-box-pre-bg);
+ align-self: stretch;
+ text-align: left;
+ font-size: 17px;
+ color: var(--site-code-box-text);
+ padding: 29px 22px;
+ margin-bottom: 18px;
+ overflow: scroll;
+
+ + .link-wrapper {
+ margin-top: 10px;
+ }
+ }
+
+ a {
+ @include link-with-right-arrow;
+ }
+
+ @media only screen and (max-width: 768px) {
+ nav {
+ width: 100%;
+
+ ul {
+ white-space: nowrap;
+ }
+ }
+ }
+}
+
+.headline-section {
+ margin: 0 auto 70px;
+
+ hr {
+ max-width: 536px;
+ background: #727272;
+ border-radius: 3px;
+ margin: 0;
+ height: 1px;
+ border: none;
+
+ &.top-hr {
+ margin: 0 auto 48px;
+ }
+
+ &.bottom-hr {
+ margin: 60px auto 0;
+ }
+ }
+
+ .copy-wrapper {
+ max-width: 777px;
+ margin: 0 auto;
+ text-align: center;
+ }
+
+ h2 {
+ font-size: 48px;
+ font-weight: 600;
+ margin-bottom: 29px;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ p {
+ font-size: 17px;
+ padding: 0 100px;
+ margin-bottom: 45px;
+
+ @media only screen and (max-width: 768px) {
+ padding: 0;
+ }
+ }
+
+ a {
+ font-size: 17px;
+ @include link-with-right-arrow;
+ }
+}
+
+.full-width-text-image-column {
+ margin: 0 auto 70px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ padding: 0 100;
+
+ .text-wrapper {
+ max-width: 598px;
+ padding: 0 10px;
+ margin-bottom: 32px;
+ }
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 30px;
+ line-height: 1.2;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ p {
+ margin-bottom: 11px;
+ }
+
+ a {
+ @include link-with-right-arrow;
+ }
+}
+
+.full-width-text-code-column {
+ &.background {
+ border-radius: 22px;
+ padding: 50px;
+ background: var(--get-started-card-primary-bg);
+ box-sizing: border-box;
+
+ .code {
+ background: var(--get-started-code-box-pre-bg);
+ max-height: 400px;
+ overflow: scroll;
+ }
+ }
+
+ margin: 0 auto 70px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+
+ .text-wrapper {
+ max-width: 598px;
+ padding: 0 10px;
+ margin-bottom: 32px;
+ }
+
+ .code {
+ max-width: none;
+ width: 100%;
+ border: var(--get-started-code-box-pre-border);
+ border-radius: 22px;
+ background: var(--get-started-code-box-pre-bg);
+ overflow: hidden;
+
+ .highlight {
+ background: var(--get-started-code-box-pre-bg);
+ }
+ }
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 30px;
+ line-height: 1.2;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ p {
+ margin-bottom: 11px;
+ }
+
+ a {
+ @include link-with-right-arrow;
+ }
+
+ @media only screen and (max-width: 768px) {
+ .code {
+ margin: 0 0 32px;
+ width: 100%;
+ }
+ }
+}
+
+.code-text-row {
+ margin: 60px auto 70px;
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 44px;
+ width: 100%;
+ text-align: center;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ .card-wrapper {
+ display: flex;
+ align-items: stretch;
+ }
+
+ .code {
+ flex: 1;
+ margin-right: 40px;
+ border: var(--get-started-code-box-pre-border);
+ border-radius: 22px;
+ height: fit-content;
+ overflow: hidden;
+ pre.highlight {
+ background: var(--get-started-code-box-pre-bg);
+ }
+ }
+
+ h3 {
+ margin-bottom: 8px;
+ font-weight: 600;
+ }
+
+ h3,
+ span {
+ text-align: left;
+ }
+
+ .copy-wrapper {
+ border-radius: 4px;
+ padding: 3px 0 19px 0px;
+ text-align: left;
+ width: 350px;
+
+ h3 {
+ font-size: 22px;
+ font-weight: 600;
+ }
+
+ h3 {
+ margin-bottom: 17px;
+ }
+
+ p {
+ margin-bottom: 25px;
+ }
+
+ a {
+ @include link-with-right-arrow();
+ margin-top: 2px;
+ }
+ }
+
+ @media only screen and (max-width: 768px) {
+ .card-wrapper {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .code {
+ width: 100%;
+ margin: 0 0 32px;
+ }
+
+ .copy-wrapper {
+ padding: 0;
+ width: auto;
+ }
+ }
+}
+
+.code-image-column {
+ margin: 60px auto 70px;
+
+ .text-wrapper {
+ max-width: 598px;
+ padding: 0 10px;
+ margin: 0 auto 32px;
+ text-align: center;
+ }
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 30px;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ p {
+ margin-bottom: 11px;
+ }
+
+ a {
+ @include link-with-right-arrow;
+ }
+
+ .card-wrapper {
+ display: flex;
+ align-items: stretch;
+ }
+
+ .code {
+ flex: 1;
+ margin-right: 40px;
+ border: var(--get-started-code-box-pre-border);
+ border-radius: 22px;
+ overflow: hidden;
+ pre.highlight {
+ background: var(--get-started-card-primary-bg);
+ }
+ }
+
+ h3 {
+ margin-bottom: 8px;
+ font-weight: 600;
+ }
+
+ h3,
+ span {
+ text-align: left;
+ }
+
+ img {
+ border-radius: 4px;
+ padding: 3px 0 19px 0px;
+ text-align: left;
+ width: 350px;
+ object-fit: contain;
+ object-position: top;
+
+ h3 {
+ font-size: 22px;
+ font-weight: 600;
+ }
+
+ h3 {
+ margin-bottom: 17px;
+ }
+
+ p {
+ margin-bottom: 25px;
+ }
+
+ a {
+ @include link-with-right-arrow();
+ margin-top: 2px;
+ }
+ }
+
+ @media only screen and (max-width: 768px) {
+ .card-wrapper {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .code {
+ margin: 0 0 32px;
+ width: 100%;
+ }
+
+ img {
+ max-width: none;
+ width: 100%;
+ padding: 0;
+ }
+ }
+}
+
+.link-columns {
+ padding-top: 37px;
+ margin-bottom: 70px;
+ border-radius: 22px;
+ background: var(--get-started-card-primary-bg);
+
+ h2 {
+ font-size: 48px;
+ margin-bottom: 44px;
+ text-align: center;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ h3 {
+ font-size: 22px;
+ font-weight: 600;
+ margin-bottom: 24px;
+ }
+
+ .link-grid {
+ padding: 0 60px 41px 60px;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ column-gap: 20px;
+
+ .link-column {
+ text-align: center;
+ }
+ }
+
+ a {
+ @include link-with-right-arrow();
+ margin-bottom: 20px;
+ font-size: 14px;
+ }
+
+ @media only screen and (max-width: 768px) {
+ .link-grid {
+ grid-template-columns: 1fr;
+ padding: 0 0 41px 0;
+
+ .link-column {
+ margin-bottom: 17px;
+ }
+ }
+ }
+}
+
+.stand-alone-link {
+ background: var(--get-started-card-primary-bg);
+ padding: 20px 50px;
+ opacity: 0.9;
+ border-radius: 20px;
+ width: fit-content;
+ margin: auto;
+ display: block;
+ margin-bottom: 90px;
+ position: relative;
+ z-index: 1;
+
+ &:hover {
+ cursor: pointer;
+ }
+
+ a {
+ @include link-with-right-arrow;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/pages/_index.scss b/assets/stylesheets/new-stylesheets/pages/_index.scss
new file mode 100644
index 000000000..4f6c67da8
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/pages/_index.scss
@@ -0,0 +1,422 @@
+@use 'sass:color';
+@use '../helpers' as *;
+@use '../graphics' as *;
+
+$icons: (
+ 'cloud',
+ 'mobile',
+ 'chip',
+ 'desktop',
+ 'websites',
+ 'games',
+ 'ai',
+ 'command-line',
+ 'packages'
+);
+
+.section {
+ text-align: center;
+
+ h2 {
+ font-size: 45px;
+ color: #3d3d3d;
+ letter-spacing: 0;
+ text-align: center;
+ font-weight: 600;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ .callout-subtitle {
+ margin-bottom: 22px;
+ }
+}
+
+.animation-container {
+ aspect-ratio: 1248 / 1116;
+ top: calc(66px - 9.5vw);
+ left: 0;
+ width: 57vw;
+ min-width: 500px;
+ position: absolute;
+ z-index: 1;
+ pointer-events: none;
+
+ @media only screen and (max-width: 800px) {
+ // start to crop in hero from the left
+ width: 500px;
+ left: initial;
+ right: 50%;
+ top: 11px;
+ transform: translateX(14%);
+ }
+
+ canvas {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ }
+}
+
+#what-is-swift {
+ padding-top: 72px; // height of navigation, plus standard
+ padding-bottom: 8vw;
+ text-align: center;
+ position: relative;
+ background-image: var(--homepage-hero-bg);
+ @include noise();
+
+ @media only screen and (max-width: 1024px) {
+ & {
+ padding: calc(72px + 142px) 10px 24vw;
+ padding-left: 10px;
+ padding-right: 10px;
+ }
+ }
+
+ .hero-content {
+ margin-top: 18vw;
+ z-index: 5;
+
+ @media only screen and (max-width: 1024px) {
+ margin-top: 48px;
+ }
+ }
+
+ h1 {
+ font-size: 48px;
+ line-height: 1.2;
+ color: var(--site-code-box-text);
+ letter-spacing: 0;
+ text-align: center;
+ font-weight: 600;
+ margin-bottom: 30px;
+ position: relative;
+ z-index: 3;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ /* Install */
+ .hero-content > a {
+ @include big-button();
+ }
+
+ /* Platform Support */
+ .hero-content > p {
+ opacity: 0.66;
+ font-size: 17px;
+ color: var(--homepage-install-text);
+ font-weight: 500;
+ margin-top: 11px;
+ }
+
+ /* Get Started */
+ h2 {
+ font-size: 32px;
+ color: var(--site-text-color);
+ letter-spacing: 0;
+ text-align: center;
+ font-weight: 400;
+ margin-top: 70px;
+ margin-bottom: 29px;
+ position: relative;
+ z-index: 1;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 32px;
+ line-height: 1.33;
+ }
+ }
+
+ .sub-text > h2 {
+ font-size: 32px;
+ color: var(--site-code-box-text);
+ letter-spacing: 0;
+ text-align: center;
+ font-weight: 400;
+ margin-top: 20px;
+ margin-bottom: 60px;
+ position: relative;
+ z-index: 1;
+
+ @media only screen and (max-width: 768px) {
+ font-size: 28px;
+ margin-bottom: 30px;
+ line-height: 1.33;
+ }
+ }
+
+ nav[aria-label='Get started with Swift'] {
+ max-width: 980px;
+ margin: 0 auto;
+ position: relative;
+ z-index: 5;
+
+ ul {
+ display: flex;
+
+ li {
+ a {
+ display: flex;
+ text-decoration: none;
+ color: var(--home-quicklinks-color);
+ background-color: var(--home-quicklinks-bg);
+ // background-color: #fff;
+ font-weight: 400;
+ border-radius: 36px;
+ font-size: 14px;
+ padding: 12px;
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease;
+
+ /* Icon inside button */
+ i {
+ width: 20px;
+ height: 20px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+ display: inline-block;
+ vertical-align: middle;
+ background-color: var(--home-quicklinks-color);
+
+ @each $name in $icons {
+ &.#{$name} {
+ mask: url('/assets/images/icon-#{$name}.svg')
+ center /
+ contain
+ no-repeat;
+ -webkit-mask: url('/assets/images/icon-#{$name}.svg')
+ center /
+ contain
+ no-repeat;
+ }
+ }
+ }
+
+ /* Hover/focus styles */
+ &:hover,
+ &:focus {
+ // background-color: rgba(230, 150, 80, 0.9);
+ // background-color: color.adjust($foo, $lightness: -10%);
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: 2px solid dodgerblue;
+ outline-offset: 2px;
+ }
+ }
+ }
+
+ &.primary-links {
+ gap: 20px;
+ margin-bottom: 20px;
+
+ li {
+ flex: 1; // equal width
+
+ a {
+ text-align: left;
+ padding: 25px;
+ gap: 12px;
+
+ .title {
+ font-size: 24px;
+ font-weight: 600;
+ text-transform: capitalize;
+ }
+
+ .subtitle {
+ line-height: 1.4;
+ }
+
+ i {
+ width: 40px;
+ height: 40px;
+ }
+ }
+ }
+ }
+
+ &.secondary-links {
+ gap: 15px;
+ flex-wrap: wrap;
+
+ li {
+ flex-grow: 1; // varied width
+
+ a {
+ justify-content: center;
+
+ .title {
+ font-weight: 400;
+ white-space: nowrap;
+ }
+ }
+ }
+ }
+ }
+
+ /* Mobile */
+ @media only screen and (max-width: 1024px) {
+ max-width: 100%;
+
+ ul {
+ &.primary-links {
+ flex-direction: column;
+ }
+
+ &.secondary-links {
+ gap: 0;
+
+ li {
+ a {
+ background: none;
+ padding: 8px 12px;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .swoop-0 {
+ @include swoop-ratio(2048, 687, 1.2);
+ @include lazyloadBg('/assets/images/landing-page/swoops/swoop-0.png');
+ z-index: 1;
+ background-size: 120%;
+ background-position: 45% 0;
+ }
+} // what-is-swift
+
+.pillar-wrapper {
+ text-align: center;
+ margin: auto;
+ padding: 4vw 0 32px;
+ max-width: 720px;
+ .pillar-headline {
+ font-size: 48px;
+ line-height: 1.2;
+ margin-bottom: 16px;
+ }
+
+ @media only screen and (max-width: 1024px) {
+ text-align: left;
+ padding: 4vw 0 32px;
+ max-width: none;
+
+ .pillar-headline {
+ text-align: left;
+ }
+ }
+
+ .pillar-intro {
+ font-size: 24px;
+ line-height: 1.45;
+ }
+}
+
+.pillar {
+ padding: 13.88vw 0;
+ position: relative;
+ overflow: visible;
+
+ @include noise();
+}
+
+.swoop {
+ transition: opacity 0.5s;
+ display: block;
+ background: none no-repeat;
+ background-size: 120%;
+ background-position: -25% 0;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: 100%;
+ transform: translateY(50%);
+ pointer-events: none;
+}
+
+.code {
+ text-align: left;
+ margin: 0 auto 10px;
+ max-width: 900px;
+ position: relative;
+ z-index: 10;
+
+ pre.highlight {
+ border-radius: 20px;
+ padding: 28px;
+ backdrop-filter: blur(10px);
+ background: rgba(255, 255, 255, 0.5);
+ }
+}
+
+body[data-color-scheme='dark'] {
+ .callout.with-code {
+ .code {
+ pre.highlight {
+ border: 1px solid #575757;
+ background: #111727;
+ }
+ }
+ }
+}
+
+#pillar-1 {
+ background-image: var(--homepage-pillar-1-bg);
+ padding: 11.88vw 0 16.88vw;
+ color: var(--site-text-color);
+
+ .swoop {
+ @include swoop-ratio(444, 97, 1.33);
+ z-index: 1;
+ background-size: 133%;
+ background-position: 60% 0;
+ @include lazyloadBg('/assets/images/landing-page/swoops/swoop-1.png');
+ }
+
+ @media only screen and (max-width: 768px) {
+ padding-top: 17.88vw;
+ }
+}
+
+#pillar-2 {
+ padding: 0.94vw 0 12.5vw;
+ background-image: var(--homepage-pillar-2-bg);
+
+ .swoop {
+ @include swoop-ratio(2624, 1073, 1.33);
+ z-index: 1;
+ background-size: 133%;
+ background-position: 45% 0;
+ @include lazyloadBg('/assets/images/landing-page/swoops/swoop-2.png');
+ bottom: -5vw;
+ }
+}
+
+#pillar-3 {
+ background-image: var(--homepage-pillar-3-bg);
+ padding: 5vw 0 40px;
+
+ .callout {
+ color: white;
+ max-width: 760px;
+ }
+
+ .callout-text {
+ text-align: center;
+ }
+}
diff --git a/assets/stylesheets/new-stylesheets/pages/_install.scss b/assets/stylesheets/new-stylesheets/pages/_install.scss
new file mode 100644
index 000000000..1d886c301
--- /dev/null
+++ b/assets/stylesheets/new-stylesheets/pages/_install.scss
@@ -0,0 +1,315 @@
+@use '../helpers' as *;
+@use '../elements/os-selection-navigation';
+
+#install {
+ @include noise();
+ position: relative;
+ background-image: var(--install-page-bg);
+ padding: 160px 0;
+
+ .content {
+ max-width: 980px;
+ width: 100%;
+ margin: 0 auto;
+ box-sizing: border-box;
+ border-radius: 22px;
+
+ @media only screen and (max-width: 1024px) {
+ padding: 20px;
+ }
+
+ h2 {
+ color: var(--site-text-color);
+ text-align: left;
+ margin-top: 60px;
+ position: relative;
+ z-index: 10;
+ line-height: 1.2em;
+ }
+
+ h3 {
+ color: var(--site-text-color);
+ text-align: left;
+ margin-top: 40px;
+ font-size: 22px;
+ }
+
+ div p.content-copy {
+ margin-bottom: 20px;
+ text-align: left;
+
+ &:only-child {
+ margin: 0;
+ }
+
+ a {
+ color: var(--site-text-color) !important;
+
+ &.content-link {
+ @include link-with-right-arrow;
+ margin-top: 10px;
+ display: flex;
+ @include underline;
+
+ &.block {
+ justify-content: center;
+ font-size: 2em;
+ }
+
+ i {
+ filter: var(--site-content-link-with-right-arrow-icon-filter);
+ }
+ }
+ }
+ }
+
+ .callout {
+ h2 {
+ text-align: inherit;
+ }
+
+ div p.content-copy {
+ text-align: inherit;
+ }
+ }
+ }
+
+ .swoop-1 {
+ @include swoop-ratio(2624, 1073, 1.33);
+ background-size: 166% auto;
+ background-position: 47% 0%;
+ top: -20vw;
+ background-image: url(/assets/images/install/swoops/swoop-0.png);
+
+ @media only screen and (max-width: 768px) {
+ top: -4vw;
+ }
+ }
+}
+
+.release-box {
+ width: 100%;
+ position: relative;
+ margin-top: 40px;
+
+ thead th {
+ border-collapse: separate;
+ background: var(--install-release-box-th-bg);
+
+ &:first-child {
+ border-top-left-radius: 10px;
+ }
+
+ &:last-child {
+ border-top-right-radius: 10px;
+ }
+ }
+
+ details {
+ summary {
+ font-size: 22px;
+ font-weight: 600;
+ display: list-item;
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ table {
+ width: 100%;
+ margin: 40px 0;
+ table-layout: auto;
+
+ td {
+ button {
+ border: 0;
+ background: var(--install-release-box-th-bg);
+ border-radius: 10px;
+ padding: 6px 15px;
+ color: var(--site-link-with-right-arrow-color);
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ a {
+ display: block;
+
+ &.debug {
+ font-size: 12px;
+ }
+ }
+ }
+ }
+
+ tr {
+ background-color: var(--install-release-box-tr-bg);
+ border-bottom: var(--install-release-box-tr-border-bottom);
+ }
+
+ table th,
+ table td {
+ padding: 12px 16px;
+ text-align: left;
+ }
+
+ table th.download {
+ font-weight: 600;
+ color: var(--install-release-box-th-color);
+ }
+
+ table td a {
+ color: var(--site-link-with-right-arrow-color);
+ text-decoration: none;
+ }
+
+ table td a:hover {
+ text-decoration: underline;
+ }
+
+ @media only screen and (max-width: 768px) {
+ table th,
+ table td {
+ padding: 10px 8px;
+ font-size: 14px;
+ }
+
+ table {
+ font-size: 14px;
+ }
+
+ table thead {
+ display: none;
+ }
+
+ table tr {
+ display: block;
+ margin-bottom: 6px;
+ border-bottom: 1px solid #f2f2f2;
+ }
+
+ table td {
+ display: block;
+ position: relative;
+ }
+
+ table td::before {
+ content: attr(data-label);
+ position: absolute;
+ left: 16px;
+ width: 45%;
+ text-align: left;
+ font-weight: bold;
+ color: #666;
+ }
+ }
+
+ .code-box {
+ width: 100%;
+ margin: 0;
+ padding: 20px;
+
+ h2 {
+ color: var(--site-code-box-text) !important;
+ font-size: 22px !important;
+ margin: 0 0 10px 0 !important;
+ }
+
+ pre {
+ overflow: scroll;
+ }
+
+ .button-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: flex-start;
+ }
+
+ ul {
+ list-style: disc;
+ padding-left: 20px;
+
+ li code {
+ word-break: break-word;
+ }
+ }
+
+ p.body-copy {
+ flex-grow: 1;
+
+ button {
+ border: 0;
+ background: var(--install-release-box-th-bg);
+ border-radius: 10px;
+ padding: 6px 15px;
+ color: var(--site-link-with-right-arrow-color);
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .content-body {
+ flex-grow: 1;
+ width: 100%;
+ }
+ }
+
+ .content {
+ background-color: var(--install-site-code-box-bg);
+ max-width: 900px;
+ width: 900px;
+ margin: 0 auto;
+ z-index: 3;
+ box-sizing: border-box;
+ position: relative;
+ text-align: left;
+ padding: 20px;
+ height: 100%;
+
+ & > h3 {
+ font-size: 24px;
+ font-weight: 600;
+ margin-bottom: 20px;
+ }
+
+ & > p {
+ margin-bottom: 10px;
+ }
+ }
+}
+
+.releases-grid {
+ display: inline-grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 40px;
+ width: 100%;
+ margin: 40px 0 0;
+
+ @media only screen and (max-width: 768px) {
+ grid-template-columns: 1fr;
+ }
+
+ .release-box {
+ display: flex;
+ flex-direction: column;
+ margin-top: 0;
+
+ .content {
+ display: flex;
+ flex-direction: column;
+
+ .code-box {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 150px;
+ }
+ }
+ }
+}
diff --git a/assets/stylesheets/pages/_landing.scss b/assets/stylesheets/pages/_landing.scss
deleted file mode 100644
index 4a30963bb..000000000
--- a/assets/stylesheets/pages/_landing.scss
+++ /dev/null
@@ -1,150 +0,0 @@
-.grid-layout-use-cases {
- @media (min-width: 1000px) {
- grid-template-columns: repeat(2, 1fr);
-
- li:nth-child(2n-1):nth-last-of-type(1) {
- grid-column: span 2;
- }
- }
-}
-
-.preamble {
- font-size: 40px;
- line-height: 1.4;
- margin-bottom: 0;
-
- strong {
- font-weight: 600;
- }
-
- span {
- display: block;
- padding-top: 2rem;
- }
-
- @media only screen and (max-width: 1280px) {
- width: 100%;
- font-size: 24px;
- margin-bottom: 1.6rem;
-
- span {
- display: block;
- padding-top: 0.5rem;
- }
- }
-}
-
-.featured-snippet {
- display: none;
- min-height: 18rem;
- max-width: 536px;
-
- &.visible {
- display: block;
- }
-
- .highlight {
- height: 100%;
- display: flex;
- justify-content: space-evenly;
- flex-direction: column;
- }
-
- pre {
- margin: 0;
-
- code {
- font-size: 1.2em;
- line-height: 1.6em;
-
- @media only screen and (max-width: 1280px) {
- font-size: 1em;
- }
- }
- }
-
- @media only screen and (max-width: 1280px) {
- margin-left: 0;
- width: 100%;
- max-width: 100%;
- min-height: auto;
- }
-}
-
-.link-grid {
- ul {
- display: grid;
- align-items: stretch;
- gap: 1rem;
- padding: 0;
- grid-template-columns: repeat(1, 1fr);
-
- @media (min-width: 1000px) {
- grid-template-columns: repeat(4, 1fr);
- }
- }
-
- li {
- list-style: none;
- padding-left: 0;
- display: flex;
-
- a {
- border-radius: var(--border-radius);
- border: 1px solid var(--color-text);
- color: var(--color-text);
- display: block;
- padding: 0.5rem 0;
- text-align: center;
- flex-grow: 1;
-
- .flex-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- height: 100%;
-
- .latest-release-container {
- height: 64px;
- flex-grow: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
-
- &:hover {
- background-color: var(--color-text);
- color: var(--color-fill);
- text-decoration: none;
-
- .latest-release-container {
- span {
- border-color: var(--color-fill);
- }
- }
-
- img {
- filter: var(--icon-filter-hover);
- }
- }
-
- img {
- height: 64px;
- width: 64px;
- display: block;
- margin: 0 auto;
- filter: var(--icon-filter);
- }
- }
- }
-}
-
-.latest-release-container {
- span {
- padding: 0.2rem 0.5rem;
- border: 2px solid currentColor;
- font-weight: bold;
- border-radius: 4px;
- }
-}
diff --git a/community/index.md b/community/index.md
index 15033ac06..53dca160a 100644
--- a/community/index.md
+++ b/community/index.md
@@ -3,60 +3,63 @@ layout: page
title: 社区概览
---
-Swift.org 社区有一个独特的目标:打造世界上最好的通用编程语言。我们将在开放环境下共同开发这门语言,欢迎任何人参与贡献。本指南文档描述了Swift社区的组织方式,以便我们能够协同工作,为Swift添加令人惊叹的新功能,并使其能够被更多开发者在更多平台上使用。
+Swift.org 社区的唯一目标是打造世界上最好的通用编程语言。我们将以开放的方式共同开发这门语言,欢迎任何想要参与的人做出贡献。这份指南文档描述了 Swift 社区的组织方式,以便我们能够共同努力为 Swift 添加令人惊叹的新功能,并让更多平台的开发者都能使用它。
## 交流方式
-Swift语言在开放环境下开发,所有关于语言或社区流程的技术或管理主题都应该在Swift公共论坛上讨论。我们鼓励公开对话,Swift语言的活跃开发者应关注相关的论坛分类。
+Swift 语言是开放开发的,所有关于语言或社区流程的技术或管理话题都应该在 Swift 公共论坛上讨论。我们鼓励公开对话,Swift 语言的活跃开发者应该关注相关的论坛类别。
-* 论坛分类目录和电子邮件说明在[论坛部分](#forums)。
-* 所有Swift项目的源代码可以在GitHub上找到:[github.com/apple][github]。
-* Swift语言的bug跟踪系统维护在[github.com/swiftlang/swift/issues][bugtracker]。
+* 论坛类别目录和邮件说明在[论坛部分](#forums)。
+* 所有 Swift 项目的源代码都可以在 GitHub 上找到:[github.com/apple][github]。
+* Swift 语言的问题跟踪系统维护在:[github.com/swiftlang/swift/issues][bugtracker]。
-项目空间内的所有交流都应遵守Swift项目的[行为准则](/code-of-conduct)。
+项目空间内的所有交流都应遵守 Swift 项目的[行为准则](/code-of-conduct)。
## 社区结构
-要以连贯、清晰的视角推进Swift编程语言的发展需要强有力的领导。领导层来自社区,并与更广泛的贡献者和用户群体密切合作。社区内的角色包括:
+要推动 Swift 编程语言的发展,使其具有连贯、清晰的演进方向,需要强有力的领导。领导层来自社区,并与更广泛的贡献者和用户群体密切合作。社区内的角色包括:
-* __[项目负责人](#project-lead)__ 从社区任命技术领导者。Apple Inc.是项目负责人,通过其代表与社区互动。
-* __[核心团队](#core-team)__ 是负责Swift项目战略方向和监督的小组。
-* __[代码所有者](#code-owners)__ 是负责Swift代码库特定领域的个人。
-* __[提交者](/contributing/#commit-access)__ 是拥有Swift代码库提交权限的任何人。
-* __[贡献者](/contributing/#contributing-code)__ 是提供补丁或帮助代码审查的任何人。
+* __[项目负责人](#project-lead)__ 从社区中任命技术领导者。Apple Inc. 是项目负责人,通过其代表与社区互动。
+* __[核心团队](#core-team)__ 是负责 Swift 项目战略方向和监督的小型团队。
+* __[代码所有者](/contributing/#code-owners)__ 是负责 Swift 代码库特定领域的个人。
+* __[提交者](/contributing/#commit-access)__ 是拥有 Swift 代码库提交权限的任何人。
+* __[成员](/contributing/#member)__ 是 GitHub 上 swiftlang 组织的任何成员。
+* __[贡献者](/contributing/#contributor)__ 是通过编写代码、在论坛上回答问题、报告或分类问题、参与 Swift 演进过程或其他方式为 Swift 做出贡献的任何人。
* __指导小组__
- * __[语言](#language-steering-group)__ 是推动Swift语言朝着连贯方向发展的专家小组。
- * __[平台](/platform-steering-group)__ 是使Swift语言及其工具能够在新环境中使用的专家小组。
+ * __[生态系统](/ecosystem-steering-group)__ 是一个专注于 Swift 包和工具方向的小型专家团队。
+ * __[语言](#language-steering-group)__ 是一个推动 Swift 语言朝着连贯方向前进的小型专家团队。
+ * __[平台](/platform-steering-group)__ 是一个使 Swift 语言及其工具能够在新环境中使用的小型专家团队。
* __工作组__
- * __[C++互操作性](/cxx-interop-workgroup)__ 是致力于添加Swift和C++之间双向互操作性支持的团队。
- * __[贡献者体验](/contributor-experience-workgroup)__ 是支持Swift项目贡献者的团队,包括在Swift论坛上的贡献。
- * __[文档](/documentation-workgroup)__ 是帮助指导Swift文档体验的团队。
- * __[服务器端Swift](/sswg)__ 是促进Swift在开发和部署服务器应用程序方面使用的团队。
- * __[网站](/website-workgroup/)__ 是帮助指导Swift.org网站发展的团队。
+ * __[C++ 互操作性](/cxx-interop-workgroup)__ 是一个致力于添加 Swift 和 C++ 之间双向互操作支持的团队。
+ * __[贡献者体验](/contributor-experience-workgroup)__ 是一个支持 Swift 项目贡献者的团队,包括在 Swift 论坛上的贡献。
+ * __[文档](/documentation-workgroup)__ 是一个帮助指导 Swift 文档体验的团队。
+ * __[服务器端 Swift](/sswg)__ 是一个推广使用 Swift 开发和部署服务器应用程序的团队。
+ * __[测试](/testing-workgroup)__ 是一个帮助指导 Swift 代码测试体验、库和工具的团队。
+ * __[网站](/website-workgroup/)__ 是一个帮助指导 Swift.org 网站演进的团队。
-最重要的是,每个使用Swift的人都是我们扩展社区中的重要成员。
+最重要的是,每个使用 Swift 的人都是我们扩展社区中宝贵的成员。
#### 项目负责人
[通过论坛联系](https://forums.swift.org/new-message?username=tkremenek)
-Apple Inc. 是项目负责人,作为项目的仲裁者。项目负责人任命领导职位的高级人员,这些领导者来自全球Swift贡献者社区。社区领导者和代码贡献者共同努力不断改进Swift,该语言将通过每个参与者的良好工作而不断进步。
+Apple Inc. 是项目负责人,并作为项目的仲裁者。项目负责人任命来自全球 Swift 贡献者社区的领导担任领导角色。社区领导者和代码贡献者共同努力不断改进 Swift,这门语言将通过所有参与者的良好工作而不断进步。
-[Ted Kremenek](mailto:kremenek@apple.com)是Apple指定的代表,作为项目负责人的发言人。
+[Ted Kremenek](mailto:kremenek@apple.com) 是 Apple 指定的代表,作为项目负责人的代言人。
#### 核心团队
[通过论坛联系](https://forums.swift.org/new-message?groupname=core-team)
-核心团队为Swift社区的各个工作组和计划提供凝聚力,提供支持和战略调整。项目负责人任命核心团队成员,以带来经验、专业知识和领导力的混合,使该团队能够共同作为Swift项目和其社区的有效管理者。核心团队成员预计会随时间变化。
+核心团队为 Swift 社区的各种工作组和计划提供凝聚力,提供支持和战略协调。项目负责人任命核心团队成员,以带来经验、专业知识和领导力的组合,使团队能够共同作为 Swift 项目及其社区的有效管理者。核心团队成员预计会随时间变化。
-当前核心团队成员是:
+当前核心团队成员:
{% assign people = site.data.core_team | sort: "name" %}
{% for person in people %}* {{ person.name }}
{% endfor %}
-我们感谢以下荣誉退休核心团队成员的服务:
+我们感谢以下荣誉核心团队成员的服务:
{% assign people = site.data.core_team_emeriti | sort: "name" %}
{% for person in people %}* {{ person.name }}
@@ -66,52 +69,38 @@ Apple Inc. 是项目负责人,作为项目的仲裁者。项目负责人任命
[通过论坛联系](https://forums.swift.org/new-message?groupname=language-workgroup)
-语言指导小组由Swift项目负责人和核心团队认定的专家组成,这些专家具有平衡的视角和专业知识,可以审查、指导并战略性地调整语言的变化。语言指导小组审查并帮助迭代来自社区的[语言演进提案](/contributing/#evolution-process)。工作组成员帮助连贯地推动Swift语言向前发展,以创建最好的通用编程语言。语言指导小组成员预计会随时间变化。
+语言指导小组由 Swift 项目负责人和核心团队确定的专家组成,他们具有平衡的视角和专业知识,能够审慎地审查、指导和战略性地协调语言变更。语言指导小组审查并帮助迭代来自社区的[语言演进提案](/contributing/#evolution-process),作为这些提案的批准者。工作组成员帮助推动 Swift 语言朝着连贯的方向发展,以创建最好的通用编程语言。语言指导小组的成员预计会随时间变化。
-当前语言指导小组成员是:
+当前语言指导小组成员:
{% assign people = site.data.language_wg | sort: "name" %}
{% for person in people %}* {{ person.name }}
{% endfor %}
-#### 代码所有者
-
-[通过论坛联系](https://forums.swift.org/new-message?groupname=code-owners)
-
-代码所有者是被分配到Swift项目特定领域的个人,代码质量是他们的主要责任。Swift总项目由众多子项目组成,包括Swift标准库、LLDB调试器的扩展和Swift包管理器等。每个子项目都会被分配一个代码所有者。代码所有者负责获取所有贡献的审查、收集社区反馈,并将批准的补丁整合到产品中。
-
-任何人都可以审查代码,我们欢迎所有感兴趣的人进行代码审查。代码审查程序不由中央全局政策规定。相反,流程由每个代码所有者定义。
-
-任何活跃且表现出价值的社区成员都可以通过在论坛上发帖提出成为代码所有者的建议,或由其他成员提名。如果其他贡献者同意,项目负责人将进行任命并将新所有者的名字添加到代码所有者文件中。这个职位完全是自愿的,可以随时辞职。
+{% include_relative _forums.md %}
-当前代码所有者列表可以在Swift源代码树根目录下的`CODE_OWNERS.txt`文件中找到。我们还维护着一个邮件组,您可以[发送电子邮件][email-owners]给所有代码所有者。
-对Swift的成功而言,没有什么比强大、投入的代码所有者更重要。我们都欠他们尊重、感激之情,并应该提供我们能够给予的任何帮助。
+[homepage]: ./index.html "Swift.org home page"
+[community]: ./community.html "Swift.org community overview"
+[contributing_code]: /contributing/#contributing-code "Contributing Code"
+[test_guide]: ./test_guide.html "Detailed guide to writing good Swift tests"
+[blog]: ./blog_home.html "Swift.org engineering blog"
+[faq]: ./faq.html "The FAQ for all things Swift.org"
+[downloads]: ./downloads.html "Download recent builds of Swift tools"
+[forums]: ./forums.html
+[contributors]: ./CONTRIBUTORS.txt "View all Swift project authors"
+[owners]: ./CODE_OWNERS.txt "View all Swift project code owners"
+[license]: ./LICENSE.txt "View the Swift license"
-每个贡献者都负责将自己的名字添加到项目根目录的`CONTRIBUTORS.txt`文件中并维护联系信息。如果您是在公司umbrella下做出贡献,请添加您公司的信息,而不要将自己也列为额外的版权持有人。
-{% include_relative _forums.md %}
+[email-conduct]: mailto:conduct@swift.org "Send email to the code of conduct working group"
+[email-owners]: mailto:code-owners@forums.swift.org "Send email to the code owners"
+[email-users]: mailto:swift-users@swift.org "Email other users of Swift"
+[email-devs]: mailto:swift-dev@swift.org "Email the developer discussion list"
+[email-lead]: mailto:project-lead@swift.org "The leaders at Apple responsible for Swift.org"
-[homepage]: ./index.html "Swift.org主页"
-[community]: ./community.html "Swift.org社区概览"
-[contributing_code]: /contributing/#contributing-code "贡献代码"
-[test_guide]: ./test_guide.html "编写优质Swift测试的详细指南"
-[blog]: ./blog_home.html "Swift.org工程博客"
-[faq]: ./faq.html "Swift.org常见问题解答"
-[downloads]: ./downloads.html "下载Swift工具的最新构建版本"
-[forums]: ./forums.html
-[contributors]: ./CONTRIBUTORS.txt "查看所有Swift项目作者"
-[owners]: ./CODE_OWNERS.txt "查看所有Swift项目代码所有者"
-[license]: ./LICENSE.txt "查看Swift许可证"
-
-[email-conduct]: mailto:conduct@swift.org "向行为准则工作组发送电子邮件"
-[email-owners]: mailto:code-owners@forums.swift.org "向代码所有者发送电子邮件"
-[email-users]: mailto:swift-users@swift.org "向其他Swift用户发送电子邮件"
-[email-devs]: mailto:swift-dev@swift.org "向开发者讨论列表发送电子邮件"
-[email-lead]: mailto:project-lead@swift.org "负责Swift.org的Apple领导者"
-
-[github]: https://github.com/apple "Apple在GitHub上的主页"
-[repo]: git+ssh://github.com/apple "GitHub上托管的仓库链接"
+[github]: https://github.com/apple "Apple's home page on GitHub"
+[repo]: git+ssh://github.com/apple "Link to the repo hosted on GitHub"
[bugtracker]: http://github.com/swiftlang/swift/issues
-[swift-apple]: https://developer.apple.com/swift "Apple开发者Swift主页"
+[swift-apple]: https://developer.apple.com/swift "Apple developer home page for Swift"
diff --git a/ecosystem-steering-group/index.md b/ecosystem-steering-group/index.md
new file mode 100644
index 000000000..04616aa73
--- /dev/null
+++ b/ecosystem-steering-group/index.md
@@ -0,0 +1,203 @@
+---
+layout: page
+title: Ecosystem Steering Group
+---
+
+The Ecosystem Steering Group fosters a flourishing Swift package and tooling
+ecosystem. The Ecosystem Steering Group's primary goal is to **encourage and
+streamline development of new packages and evolution of existing packages that
+are fundamental to the Swift ecosystem and broadly used across platforms such as
+`swift-foundation`**. The group will work toward this goal by providing
+development tools and actionable guidance for Swift package authors and clients.
+Specifically, the Ecosystem Steering Group will:
+
+- work with the Swift Core Team to define a roadmap for developer experience
+ improvements and growing the package ecosystem,
+- work with the Platforms Steering Group to improve the experience of setting up
+ a Swift development environment on all supported platforms,
+- work with the Language Steering Group to create resources on best practices
+ for effective use of Swift in packages, such as adopting strict concurrency
+ checking or other new language features, or adopting tools such as the API
+ checker to facilitate source-stable package evolution, define and facilitate an
+ evolution process for new tools (or features of existing tools) for producing
+ and consuming Swift packages, adopting best practices (e.g. through linters and
+ formatters), etc, and
+- provide practical guidance to package authors on how to maintain and evaluate
+ the efficacy of their packages.
+
+## Membership
+
+The Ecosystem Steering Group is made up of Swift community members with a
+variety of backgrounds, including (but not limited to) involvement in key Swift
+libraries, engineering experience with developer tools such as IDEs or CI
+systems, or experience in software supply chain. The Swift Core Team is solely
+responsible for the membership of the steering group and may add or remove
+members as it sees fit.
+
+The Core Team selects one member of the steering group as the chair. The chair has no
+special authority over the steering group, but they are responsible for ensuring its
+smooth functioning, including by:
+
+- organizing and leading regular meetings,
+- ensuring that the steering group communicates effectively with the community, and
+- coordinating meetings between steering group representatives and other Swift
+ steering groups and workgroups or teams when necessary.
+
+The current members of the Ecosystem Steering Group are:
+
+- David Cummings [@daveyc123](https://github.com/daveyc123)
+- Franz Busch, Chair [@FranzBusch](https://github.com/FranzBusch)
+- Mikaela Caron [@mikaelacaron](https://github.com/mikaelacaron)
+- Mishal Shah, Core Team Representative [@shahmishal](https://github.com/shahmishal)
+- Tim Condon [@0xTim](https://github.com/0xTim)
+- Tina Liu [@itingliu](https://github.com/itingliu)
+
+
+# Decision making
+
+The Ecosystem Steering Group is commissioned by the Swift Core Team to make
+decisions on its behalf, and it typically works autonomously, with a goal of
+reaching consensus within the steering group whenever possible. Final
+decision-making authority about all ecosystem evolution topics rests with the
+Core Team.
+
+Specific responsibilities in this capacity include:
+
+- Evaluating and deciding on the inclusion of new libraries into the official
+ Swift project, ensuring alignment with established Swift project principles
+ and overall ecosystem strategy.
+- Ensuring the continuity and health of packages within the Swift project; this
+ includes identifying successor maintainers or alternative solutions if a
+ project package becomes unmaintained or vacated.
+- Providing oversight and guidance for official ecosystem libraries, intervening
+ with checks and balances if their development trajectory becomes
+ counterproductive to the broader goals or health of the Swift ecosystem.
+
+# Evolution
+
+The Ecosystem Steering Group has purview over a number of areas.
+Areas not covered are discussed [later](#areas-not-covered). The areas covered
+are:
+
+- SwiftPM dependency management features and specifications for package services
+- Build systems, including the current native SwiftPM build system, swift-build,
+ and llbuild and its variants
+- Tooling related to maintaining packages such as `swift-format`
+- Tooling related to documentation
+- Tooling related to code editing including IDE/editor integration
+- Tooling and documentation for continuous integration and deployment
+- Tooling and packages related to testing
+- `swift-foundation`
+
+Proposals or vision documents that intersect with platform specific behavior
+will be reviewed in collaboration with the Platform Steering Group.
+
+## Areas not covered
+
+Evolution authority of the Ecosystem Steering Group does not extend to:
+
+- The language or the standard library
+- The selection of low-level tools that are used by the build system on a
+ per-platform basis
+- The default invocation of low-level tools by the build system
+- The debugger
+- The linker
+- Libraries, such as the sanitizers
+
+All of these are under the purview of the Language Steering Group or Platform
+Steering Group.
+
+# Workgroups
+
+While the Ecosystem Steering group has purview over various areas that
+contribute to a flourishing and healthy ecosystem, some of those areas are
+already covered by existing workgroups that will fall under the governance of
+the Ecosystem Steering group. This includes:
+
+- [The Server Workgroup](/sswg/)
+- [The Documentation Workgroup](/documentation-workgroup/)
+- [The Foundation Workgroup](/foundation-workgroup/)
+- [The Testing Workgroup](/testing-workgroup/)
+
+## Workgroup authority
+
+These workgroups are the domain experts in their respective areas; hence, the
+authority is with the respective workgroups. Currently, the Foundation workgroup
+has the authority over swift-foundation and swift-corelibs-foundation. The
+Testing workgroup has authority over swift-testing and swift-corelibs-xctest.
+
+Not all changes to these libraries undergo the Swift evolution process, and some
+workgroups do not have a clear evolution process. The Ecosystem Steering Group
+will work with all existing and future workgroups together with the contributor
+experience workgroup to establish a definition of what exactly is under
+evolution and that all workgroups are following an aligned evolution process.
+
+## New workgroups
+
+To ensure coverage of all areas outlined in the 'Evolution' section, the
+Ecosystem Steering Group intends to establish new workgroups that are not
+currently overseen by an existing workgroup. Consistent with the model for
+existing workgroups, these new workgroups will then be responsible for driving
+the evolution of their respective projects and focus areas, fostering
+specialized expertise and community engagement within those domains.
+
+## Workgroup collaboration
+
+The Ecosystem Steering Group is going to foster collaboration among its overseen
+workgroups, ensuring they communicate effectively to build a cohesive ecosystem
+narrative and align on strategic goals. Crucially, it serves as a vital conduit,
+relaying the collective needs, progress, and challenges of these workgroups
+to the Core Team and other Swift steering groups, while also ensuring workgroups
+are informed of broader project directions and decisions.
+
+# Communication
+
+The Ecosystem Steering Group communicates with the community primarily using the
+[Ecosystem](https://forums.swift.org/c/ecosystem/120) category on the Swift forums. It may also prepare special
+posts for the Swift Blog.
+
+Furthermore, the Ecosystem Steering Group intends to establish a well defined
+communication process between itself and its workgroups that fosters close
+collaboration and synergetic effects. Additionally, this communication process
+is used to inform the other steering groups and the core team about the needs
+and challenges in the ecosystem.
+
+# Ecosystem Evolution process
+
+Existing workgroups that fall under the governance of the Ecosystem Steering
+Group may already run evolution processes. The Ecosystem Steering Group intends
+to established an aligned evolution process for all areas under its purview
+together with the existing workgroups, the contributor experience workgroup, and
+the platform and language steering groups. The goal is to have a clear
+definition for each area that covers:
+
+- What packages or libraries are under evolution?
+- What APIs or CLI arguments are under evolution?
+- Is the evolution delegated to a specific workgroup?
+- Where does the evolution process run?
+
+# Community participation
+
+The Ecosystem Steering Group is not separate from the Swift community. Steering
+Group members participate in ecosystem evolution discussions and propose changes
+just like any other member of the community. When the Steering Group develops a
+new idea about a proposal in the course of its internal deliberations, a
+Steering Group member is expected to bring that idea to the community for
+discussion before the review is considered complete.
+
+Proposals or feedback about the Swift ecosystem, the Ecosystem Evolution
+process, a specific Ecosystem Evolution proposal, or any other topic under the
+purview of the Ecosystem Steering Group are always welcome. The primary way to
+communicate with the Ecosystem Steering Group is simply to post in the Evolution
+category on the Swift forums, either by adding a reply to an existing review,
+pitch, or other discussion thread, or by creating a new thread in [Evolution >
+Discussion](https://forums.swift.org/c/evolution/discuss) or [Evolution >
+Pitches](https://forums.swift.org/c/evolution/pitches). Community members may
+also reach out privately to members of the Ecosystem Steering Group by private
+message on the forums using `@ecosystem-steering-group`.
+
+The Ecosystem Steering Group follows the [Swift Code of
+Conduct](/code-of-conduct/). Instances of abusive,
+harassing, or otherwise unacceptable behavior may be reported by contacting the
+Steering Group chair or a member of the Swift Core Team or by flagging the
+behavior for moderation, whether you are the target of that behavior or not.
diff --git a/get-started/cloud-services/index.md b/get-started/cloud-services/index.md
new file mode 100644
index 000000000..fbda20c67
--- /dev/null
+++ b/get-started/cloud-services/index.md
@@ -0,0 +1,27 @@
+---
+layout: new-layouts/base
+title: Use case
+---
+
+
+
+{% include new-includes/components/get-started-hero.html content = site.data.new-data.get-started.cloud-services.hero %}
+
+{% include new-includes/components/image-text-row.html content = site.data.new-data.get-started.cloud-services.image-text-row background = true %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.cloud-services.secondary-content %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.cloud-services.tertiary-content-cloud-native %}
+
+
+{% include new-includes/components/headline-section.html content = site.data.new-data.get-started.cloud-services.headline-section %}
+
+{% include new-includes/components/code-box.html content = site.data.new-data.get-started.cloud-services.code-box %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.cloud-services.tertiary-content %}
+
+
+
+{% include new-includes/components/link-columns.html content = site.data.new-data.get-started.cloud-services.link-columns %}
+
+
diff --git a/get-started/command-line-tools/index.md b/get-started/command-line-tools/index.md
new file mode 100644
index 000000000..b9a43d8f8
--- /dev/null
+++ b/get-started/command-line-tools/index.md
@@ -0,0 +1,19 @@
+---
+layout: new-layouts/base
+title: Command Line
+---
+
+
+{% include new-includes/components/get-started-hero.html content = site.data.new-data.get-started.command-line-tools.hero %}
+
+{% include new-includes/components/full-width-text-code-column.html content = site.data.new-data.get-started.command-line-tools.code-text-column-arg-parser background = true %}
+
+{% include new-includes/components/code-box.html content = site.data.new-data.get-started.command-line-tools.code-box-with-tabs with-tabs = true %}
+
+{% include new-includes/components/headline-section.html content = site.data.new-data.get-started.command-line-tools.headline-section %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.command-line-tools.tertiary-content %}
+
+{% include new-includes/components/full-width-text-code-column.html content=site.data.new-data.get-started.command-line-tools.full-width-text-code-column %}
+
+
diff --git a/get-started/embedded/index.md b/get-started/embedded/index.md
new file mode 100644
index 000000000..d31c94d9d
--- /dev/null
+++ b/get-started/embedded/index.md
@@ -0,0 +1,41 @@
+---
+redirect_from: "getting-started/embedded-swift"
+layout: new-layouts/base
+title: Embedded
+---
+
+
+
+
+
+{% include new-includes/components/get-started-hero.html content = site.data.new-data.get-started.embedded.hero %}
+
+
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.embedded.card-grid %}
+
+
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.embedded.primary-content %}
+
+
+
+{% include new-includes/components/headline-section.html content = site.data.new-data.get-started.embedded.headline-section %}
+
+
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.embedded.blogposts %}
+
+
+
+{% include new-includes/components/full-width-text-image-column.html content = site.data.new-data.get-started.embedded.full-width-text-image-column %}
+
+
+
+{% include new-includes/components/code-image-column.html content=site.data.new-data.get-started.embedded.code-image-column %}
+
+
+
+{% include new-includes/components/link-columns.html content = site.data.new-data.get-started.embedded.link-columns %}
+
+
diff --git a/get-started/index.md b/get-started/index.md
new file mode 100644
index 000000000..cf1aeea15
--- /dev/null
+++ b/get-started/index.md
@@ -0,0 +1,3 @@
+---
+redirect_to: /get-started/machine-learning-and-ai/
+---
diff --git a/get-started/storybook/index.md b/get-started/storybook/index.md
new file mode 100644
index 000000000..3eb23e647
--- /dev/null
+++ b/get-started/storybook/index.md
@@ -0,0 +1,54 @@
+---
+layout: new-layouts/base
+title: Storybook
+---
+
+
+
+{% include new-includes/components/get-started-hero.html content = site.data.new-data.get-started.storybook.hero %}
+
+{% include new-includes/components/hero-card.html test="test" image = site.data.new-data.get-started.storybook.hero-card stand_alone = true %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.storybook.card-grid %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.storybook.card-grid-hero-card %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.storybook.primary-content %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.storybook.secondary-content %}
+
+{% include new-includes/components/card-grid.html content = site.data.new-data.get-started.storybook.tertiary-content %}
+
+{% include new-includes/components/full-width-text-image-column.html content = site.data.new-data.get-started.storybook.full-width-text-image-column %}
+
+{% include new-includes/components/full-width-text-code-column.html content = site.data.new-data.get-started.storybook.full-width-text-code-column %}
+
+{% include new-includes/components/full-width-text-code-column.html content = site.data.new-data.get-started.storybook.full-width-text-code-column background = true %}
+
+{% include new-includes/components/code-image-column.html
+ content=site.data.new-data.get-started.storybook.code-image-column
+%}
+
+{% include new-includes/components/code-text-row.html
+ content=site.data.new-data.get-started.storybook.code-text-row
+%}
+
+{% include new-includes/components/image-text-row.html content = site.data.new-data.get-started.storybook.image-text-row %}
+
+{% include new-includes/components/image-text-row.html content = site.data.new-data.get-started.storybook.image-text-row-bg background = true %}
+
+{% include new-includes/components/headline-section.html content = site.data.new-data.get-started.storybook.headline-section %}
+
+{% include new-includes/components/code-box.html content = site.data.new-data.get-started.storybook.code-box %}
+
+{% include new-includes/components/link-columns.html content = site.data.new-data.get-started.storybook.link-columns %}
+
+{% include new-includes/components/os-selection.html content = site.data.new-data.get-started.storybook.interactive-tabs %}
+
+{% include new-includes/components/code-box.html content = site.data.new-data.get-started.storybook.code-box-with-tabs with-tabs = true %}
+
+
+
+
diff --git a/getting-started/_use-cases.md b/getting-started/_use-cases.md
index fd1dfe79a..1dd948b29 100644
--- a/getting-started/_use-cases.md
+++ b/getting-started/_use-cases.md
@@ -55,17 +55,6 @@
开始教程
-
-
- 微控制器嵌入式应用
-
- 学习如何使用嵌入式 Swift 创建可在嵌入式设备或模拟器上运行的应用程序。
-
- 此指南需要 macOS 或 Linux 环境。
-
-
- 开始教程
-
---
diff --git a/getting-started/embedded-swift/index.md b/getting-started/embedded-swift/index.md
deleted file mode 100644
index 15272f475..000000000
--- a/getting-started/embedded-swift/index.md
+++ /dev/null
@@ -1,223 +0,0 @@
----
-layout: page
-title: 为微控制器构建嵌入式应用
----
-
-> 本指南的源代码可以在 [GitHub](https://github.com/apple/swift-embedded-examples/blob/main/pico-blink-sdk/README.md) 上找到
-
-在本教程中,我们将以 Raspberry Pi Pico 作为目标嵌入式设备来运行我们的 Swift 应用程序。如果你没有实体设备也不用担心!你仍然可以在在线模拟器中运行应用程序。
-
-## 安装 Swift
-
-如果您尚未安装 Swift,请[先安装它](https://www.swift.org/install)。由于嵌入式 Swift 仍处于实验阶段,且仅在预览工具链中可用,请确保安装"开发快照"工具链(main),而不是发布工具链(6.0)。如果您使用的是 macOS 设备,需要确保已安装并选择了 Xcode,可以通过运行 `xcode-select -p` 并验证它指向 Xcode 安装路径来确认。接下来,确保将已安装的开发快照选择为活动工具链,例如通过导出 `TOOLCHAINS` 环境变量:
-
-```shell
-$ export TOOLCHAINS=org.swift.59202405011a
-```
-
-要测试是否已安装 Swift,请在 shell 或终端应用程序中运行 `swift --version`。它应该显示"6.0-dev",表示你已安装了"开发快照"工具链。
-
-## 安装嵌入式开发依赖
-
-按照 [Pico 入门指南](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf) 安装 Raspberry Pi Pico SDK 和 Arm 嵌入式工具链。
-导出三个环境变量以匹配你的设置和硬件:
-
-```shell
-$ export PICO_BOARD=pico
-$ export PICO_SDK_PATH=... # Pico SDK 的位置
-$ export PICO_TOOLCHAIN_PATH=... # Arm 嵌入式工具链的位置
-```
-
-如果你使用的是支持 Wi-Fi 的 Pico W 板而不是普通的 Pico,请注意你需要稍微不同的设置,具体请参考 [Pico W 示例项目](https://github.com/apple/swift-embedded-examples/tree/main/pico-w-blink-sdk),仅指定 `PICO_BOARD=pico_w` 是不够的。
-
-安装 [CMake 3.29](https://cmake.org/) 或更新版本。
-
-要测试是否已安装所有必需的组件,可以在终端中运行以下命令:
-
-```shell
-$ swift --version
-Apple Swift version 6.0-dev (LLVM b66077aefd3be08, Swift 84d36181a762913)
-$ cmake --version
-cmake version 3.29.2
-$ echo $PICO_BOARD
-pico
-$ ls $PICO_SDK_PATH
-CMakeLists.txt README.md external/ pico_sdk_version.cmake tools/
-CONTRIBUTING.md cmake/ lib/ src/
-LICENSE.TXT docs/ pico_sdk_init.cmake test/
-$ ls $PICO_TOOLCHAIN_PATH
-13.2.Rel1-darwin-arm64-arm-none-eabi-manifest.txt include/ share/
-arm-none-eabi/ lib/
-bin/ libexec/
-```
-
-## 构建一个"闪烁 LED"嵌入式应用
-
-在嵌入式开发中,标准的"Hello, World"是一个重复闪烁 LED 的程序。让我们来构建一个。以下设置也可以在 [swift-embedded-examples](https://github.com/apple/swift-embedded-examples/blob/main/pico-blink-sdk/README.md) 中找到,但我们将在下面展示你只需要三个文件即可。
-让我们创建一个新的空目录,并为基于 CMake 的项目准备一个简单的结构,该项目可以在 Pico SDK 之上使用:
-
-```
-embedded-swift-tutorial
-├── BridgingHeader.h
-├── CMakeLists.txt
-└── Main.swift
-```
-
-Main.swift 和 BridgingHeader.h 文件最初可以包含以下基本内容:
-
-```swift
-// Main.swift
-let led = UInt32(PICO_DEFAULT_LED_PIN)
-gpio_init(led)
-gpio_set_dir(led, /*out*/true)
-while true {
- gpio_put(led, true)
- sleep_ms(250)
- gpio_put(led, false)
- sleep_ms(250)
-}
-```
-
-```c
-// BridgingHeader.h
-#include "pico/stdlib.h"
-```
-
-要在 Pico SDK 的 CMake 支持之上构建,我们需要在 CMakeLists.txt 文件中添加更多的 CMake 逻辑:
-
-```cmake
-# CMakeLists.txt
-cmake_minimum_required(VERSION 3.29)
-include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
-
-set(CMAKE_Swift_COMPILATION_MODE wholemodule)
-set(CMAKE_Swift_COMPILER_WORKS YES)
-
-project(blinky)
-pico_sdk_init()
-enable_language(Swift)
-
-add_executable(blinky Main.swift)
-set_target_properties(blinky PROPERTIES LINKER_LANGUAGE CXX)
-
-# 清除包含 Swift 编译器不接受的 C 特定编译器标志的默认 COMPILE_OPTIONS
-# 相反,将这些选项设置为仅在编译 C 代码时应用
-set_target_properties(pico_standard_link PROPERTIES INTERFACE_COMPILE_OPTIONS "")
-target_compile_options(pico_standard_link INTERFACE "$<$:SHELL: -ffunction-sections -fdata-sections>")
-
-set(SWIFT_INCLUDES)
-foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
- string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
- string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
-endforeach()
-
-target_compile_options(blinky PUBLIC "$<$:SHELL:
- -enable-experimental-feature Embedded
- -target armv6m-none-none-eabi -Xcc -mfloat-abi=soft -Xcc -fshort-enums -Xfrontend -function-sections
- -import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
- ${SWIFT_INCLUDES}
- >")
-
-target_link_libraries(blinky pico_stdlib hardware_uart hardware_gpio)
-pico_add_extra_outputs(blinky)
-```
-
-现在我们准备为 Pico 配置和构建这个固件。运行以下命令:
-
-```shell
-$ cmake -B build -G Ninja . # 配置步骤
-$ cmake --build build # 构建步骤
-```
-
-构建应该成功,并以多种格式生成固件(ELF、HEX、UF2),包括一些信息转储文件(DIS、ELF.MAP):
-
-```shell
-$ ls -al build/blinky*
--rwxr-xr-x 1 kuba staff 8.0K Jan 1 12:00 build/blinky.bin*
--rw-r--r-- 1 kuba staff 145K Jan 1 12:00 build/blinky.dis
--rwxr-xr-x 1 kuba staff 30K Jan 1 12:00 build/blinky.elf*
--rw-r--r-- 1 kuba staff 222K Jan 1 12:00 build/blinky.elf.map
--rw-r--r-- 1 kuba staff 23K Jan 1 12:00 build/blinky.hex
--rw-r--r-- 1 kuba staff 16K Jan 1 12:00 build/blinky.uf2
-```
-
-## 在设备上运行固件
-
-如果你有一个 Raspberry Pi Pico,我们现在要上传构建好的固件并运行它。如果你没有,可以跳到下一节,在**模拟器中运行相同的固件文件**。
-
-通过 USB 线将 Raspberry Pi Pico 板连接到你的 Mac,并确保它处于 USB 大容量存储固件上传模式。如果你从未上传过任何固件,通常就是这种情况 - 如果 Pico 的内存中没有任何有效的固件,它会启动到固件上传模式。一旦上传了有效的固件,设备在插入后就会运行该固件。要返回固件上传模式,*在插入板子时按住 BOOTSEL 按钮*。
-
-然后 Pico 应该会作为一个挂载的卷显示在 /Volumes 中(在这种情况下显示为 RPI-RP2):
-
-```shell
-$ ls -al /Volumes
-lrwxr-xr-x 1 root wheel 1B Jan 1 12:00 Macintosh HD@ -> /
-drwx------ 1 kuba staff 16K Dec 31 1969 RPI-RP2/
-```
-
-将 UF2 文件复制到这个卷:
-
-```shell
-$ cp build/blinky.uf2 /Volumes/RPI-RP2
-```
-
-这将使 Pico 自动安装固件,重新启动,并运行固件。
-
-绿色 LED 现在应该重复闪烁。太好了!我们的第一个嵌入式 Swift 程序正在嵌入式设备上运行!
-
-## 在模拟器中运行固件
-
-如果你没有实体 Pico,或者想要快速迭代,[Wokwi](https://wokwi.com/) 是一个免费的在线模拟器,可以模拟各种嵌入式微控制器,包括 Raspberry Pi Pico。它执行的是你通常会上传到实体设备的相同固件二进制文件,并逐条指令模拟。
-
-在 Wokwi 中打开一个[新的 Pico 项目](https://wokwi.com/projects/new/pi-pico)。不要使用代码编辑器编写 C 代码,而是按 F1 并选择"上传固件并开始模拟"。然后选择我们的构建过程生成的 UF2 文件。
-
-一旦你将 UF2 文件上传到 Wokwi,模拟就会开始,LED 应该开始重复闪烁。太好了!我们的第一个嵌入式 Swift 程序正在模拟器中运行!
-
-## 附加内容:使用嵌入式 Swift 为你的主机操作系统构建简单程序
-
-虽然像 macOS 和 Linux 这样的桌面操作系统不是嵌入式 Swift 的典型目标,但你**完全可以**使用嵌入式 Swift 模式为它们构建代码。这对于实验、尝试嵌入式 Swift,或者快速迭代一些不需要实体设备就能工作的代码想法很有用。
-
-嵌入式 Swift 中最简单的程序可以就是一个普通的"Hello, World":
-
-```swift
-// HelloEmbedded.swift
-print("Hello, Embedded Swift 😊")
-```
-
-构建成可执行文件可以直接调用 `swiftc` 编译器,但我们需要添加标志来启用嵌入式 Swift,以及整体模块优化。
-
-```shell
-$ swiftc HelloEmbedded.swift -o HelloEmbedded -enable-experimental-feature Embedded -wmo
-```
-
-这将生成一个普通的可执行二进制文件,但请注意它的大小非常小,而且它*实际上不依赖操作系统中的 Swift 运行时*(所有嵌入式 Swift 二进制文件都在内部携带其运行时+stdlib 依赖):
-
-```shell
-$ ls -al
--rwxr-xr-x 1 kuba staff 18K May 16 17:19 HelloEmbedded*
--rw-r--r-- 1 kuba staff 59B May 16 17:16 HelloEmbedded.swift
-$ otool -L HelloEmbedded
-HelloEmbedded:
- /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1000.0.0)
-```
-
-让我们运行它:
-
-```shell
-$ ./HelloEmbedded
-Hello, Embedded Swift 😊
-```
-
-太好了!我们的第一个*主机端*嵌入式 Swift 程序正在工作!
-
-## 下一步去哪里
-
-- [嵌入式 Swift 愿景文档](https://github.com/swiftlang/swift-evolution/blob/main/visions/embedded-swift.md) 将为你概述嵌入式 Swift 的方法和目标,以及嵌入式 Swift 语言子集中具体包含什么。
-- GitHub 上的 [嵌入式 Swift 示例项目集合](https://github.com/apple/swift-embedded-examples) 展示了 Swift 今天可以在哪些嵌入式设备上工作,这些示例也可以用作你自己项目的模板。
-- [嵌入式 Swift 用户手册](https://github.com/swiftlang/swift/blob/main/docs/EmbeddedSwift/UserManual.md) 描述了如何使用嵌入式 Swift 编译模式以及如何与编译器交互。
-- [工具页面](https://swift.swiftgg.team/tools/#editors) 有关于在你的编辑器中设置 Swift 集成的指南,以启用索引、自动完成、跳转到定义等功能。
-- [Swift 论坛](https://forums.swift.org/) 是提问、反馈或分享你的酷项目的最佳场所。
-
----
-
-> 本指南的源代码可以在 [GitHub](https://github.com/apple/swift-embedded-examples/blob/main/pico-blink-sdk/README.md) 上找到
diff --git a/gsoc2025/index.md b/gsoc2025/index.md
index b75931672..3063f057e 100644
--- a/gsoc2025/index.md
+++ b/gsoc2025/index.md
@@ -196,7 +196,7 @@ Qualified name lookup is the process by which a compiler resolves a reference `
### DocC Language Features in SourceKit-LSP
-**Project size**: 90 hours (medium)
+**Project size**: 175 hours (medium)
**Estimated difficulty**: Intermediate
diff --git a/index.md b/index.md
index 0fc00e500..c68694ae9 100644
--- a/index.md
+++ b/index.md
@@ -1,144 +1,101 @@
---
-layout: page-wide
-title: Swift 中文站点
-hideTitle: true
+layout: new-layouts/base
+title: Swift 中文网
atom: true
---
-
-
Swift 是一款通用 编程语言。 新手易学 ,专家称心 Swift 快速 、现代 、安全 , 写起代码乐无边 。
-
-{% for snippet in site.data.featured_snippets %}
-```swift
-{{ snippet -}}
-```
-{: class="featured-snippet {% if forloop.first %}visible{% endif %}" }
-{% endfor %}
-
-
-
-
通过官方迁移指南 为 Swift 6 语言模式做好准备
-
-
-
-
-## 使用场景
-
-
-
- Apple 平台
-
- Swift 是一门强大而直观的编程语言,在 iOS、macOS 和其他 Apple 平台上运行时性能表现优异。
-
- Apple 提供了丰富的框架和 API,使在这些平台上开发的应用程序独特而有趣。
-
- 了解更多
-
-
- 跨平台命令行
-
- 编写 Swift 代码既互动又有趣,语法简洁而富有表现力。
- Swift 代码设计上保证安全性,并能产生运行速度极快的软件。
-
- SwiftArgumentParser 和 Swift 不断发展的软件包生态系统使开发跨平台命令行工具变得轻而易举。
-
-
- 了解更多
-
-
- 服务器与网络
-
- Swift 占用内存小、启动快速,具有可预测的性能表现,这些特点使其成为服务器和其他网络应用程序的绝佳选择。
-
- SwiftNIO 和 Swift 富有活力的服务器生态系统让开发网络应用程序变得充满乐趣。
-
-
- 了解更多
-
-
-
-## 参与其中
-
-我们欢迎每个人为 Swift 做出贡献。贡献不仅仅意味着编写代码或提交拉取请求 — 您可以通过多种方式参与其中,包括在论坛上回答问题、报告或分类 bug,以及参与 Swift 演进过程。
-
-无论您想如何参与,我们都建议您首先通过阅读[社区概览](/community/)了解项目参与者的期望。如果您要贡献代码,还应该了解如何从代码库构建和运行 Swift,具体说明请参见[源代码](/documentation/source-code/)。
-
-
-
- 设计
-
- 通过参与 Swift 演进过程 帮助塑造 Swift 的未来。
-
- 了解更多
-
-
- 编码
-
- 为 Swift 编译器、标准库和其他核心组件做出贡献。
-
- 了解更多
-
-
- 故障排查
-
- 通过报告和分类 bug 来帮助提高 Swift 的质量。
-
- 了解更多
-
-
-
-## 最新动态
-
-及时了解 Swift 社区的最新动态。
-
-
- - [访问 Swift.org 博客](/blog/)
- - [访问 Swift 论坛(英文)](https://forums.swift.org)
- - [在 Github 上关注 SwiftGG](https://github.com/swiftggteam){:target="_blank" class="link-external"}
- - [在 X 上关注 Swift(以前的推特)](https://x.com/swiftlang){:target="_blank" class="link-external"}
+
+
+
+
+
+
+
-
-
+
+
+
Swift 是一款强大的跨平台通用编程语言。 新手易学,专家称心。
+
快速、现代、安全,写起代码乐无边。
+
安装
+
适用于 Linux、macOS 和 Windows 的工具
+
使用 Swift 创造
+
+
+
+
+ {% for item in site.data.new-data.landing.get-started-secondary %}
+
+
+ {{ item.title }}
+
+
+ {% endfor %}
+
+
+
+
+{% assign pillar1_callouts = site.data.new-data.landing.callouts | slice: 0, 3 %}
+{% assign pillar2_callouts = site.data.new-data.landing.callouts | slice: 3, 2 %}
+{% assign pillar3_callouts = site.data.new-data.landing.callouts | slice: 5, 1 %}
+
+
+
+
+ Swift 是唯一一种可以从嵌入式设备和内核扩展到应用程序和云基础设施的语言。它简单、富有表现力,具有令人难以置信的性能和安全性。并且它与 C 和 C++ 具有无与伦比的互操作性。
+
+
+
+ 正是易用性、速度、安全性以及 Swift 的所有优势的结合,使其如此独特。
+
+
+ {% for callout in pillar1_callouts %}
+{% include new-includes/components/callout.html
+ title=callout.title
+ subtitle=callout.subtitle
+ text=callout.text
+ code=callout.code
+ index=forloop.index
+%}
+ {% endfor %}
+
+
+
+
+
+
+ {% for callout in pillar2_callouts %}
+{% include new-includes/components/callout.html
+ title=callout.title
+ subtitle=callout.subtitle
+ text=callout.text
+ code=callout.code
+ index=forloop.index
+%}
+ {% endfor %}
+
+
+
+
+ {% for callout in pillar3_callouts %}
+{% include new-includes/components/callout.html
+ title=callout.title
+ subtitle=callout.subtitle
+ text=callout.text
+ code=callout.code
+ index=forloop.index
+ links=callout.links
+%}
+ {% endfor %}
+
diff --git a/install/index.md b/install/index.md
index ab0c9e410..28cd60df4 100644
--- a/install/index.md
+++ b/install/index.md
@@ -1,10 +1,8 @@
---
redirect_from:
- "/download/"
-layout: page-wide
+layout: new-layouts/install
title: 安装 Swift
---
-{% include install/_os_tabs.md %}
-
-
+
diff --git a/install/linux/amazonlinux/2/index.md b/install/linux/amazonlinux/2/index.md
index a9d1c880b..4fd64d0fc 100644
--- a/install/linux/amazonlinux/2/index.md
+++ b/install/linux/amazonlinux/2/index.md
@@ -1,29 +1,32 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
+{% include /new-includes/assigns/linux-platform-builds.html
+ platform="Amazon Linux 2"
+ aarch64="true"
+ branch_dir="development"
+ development="main"
+ docker_tag="nightly-amazonlinux2"
+ development_builds=site.data.builds.development.amazonlinux2
+ aarch64_development_builds=site.data.builds.development.amazonlinux2-aarch64
+ development_2="release/6.2"
+ docker_tag_2="nightly-6.2-amazonlinux2"
+ development_builds_2=site.data.builds.swift-6_2-branch.amazonlinux2
+ aarch64_development_builds_2=site.data.builds.swift-6_2-branch.amazonlinux2-aarch64
+ branch_dir_2="swift-6.2-branch"
+%}
-{% include install/_linux_platforms_tabs.md amazonlinux="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.amazonlinux name="Amazon Linux" pressed="Amazon Linux 2" %}
-
-{% include install/_build_release.md platform="Amazon Linux 2" docker_tag="amazonlinux2" rpm="true"%}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Amazon Linux 2" %}
-
-
-{% include install/_build_snapshot.md platform="Amazon Linux 2"
-aarch64="true"
-branch_dir="development"
-development="main"
-docker_tag="nightly-amazonlinux2"
-development_builds=site.data.builds.development.amazonlinux2
-aarch64_development_builds=site.data.builds.development.amazonlinux2-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-amazonlinux2"
-development_builds_2=site.data.builds.swift-6_1-branch.amazonlinux2 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.amazonlinux2-aarch64
-branch_dir_2="swift-6.1-branch"%}
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ rpm=true
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
diff --git a/install/linux/amazonlinux/index.md b/install/linux/amazonlinux/index.md
index c77a2730b..e056bdc7e 100644
--- a/install/linux/amazonlinux/index.md
+++ b/install/linux/amazonlinux/index.md
@@ -1,10 +1,4 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md amazonlinux="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.amazonlinux name="Amazon Linux" %}
diff --git a/install/linux/debian/12/index.md b/install/linux/debian/12/index.md
index 8098a210b..80b163b39 100644
--- a/install/linux/debian/12/index.md
+++ b/install/linux/debian/12/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
+{% include /new-includes/assigns/linux-platform-builds.html
+ platform="Debian 12"
+ aarch64="true"
+ branch_dir="development"
+ development="main"
+ docker_tag="nightly-debian-12"
+ development_builds=site.data.builds.development.debian12
+ aarch64_development_builds=site.data.builds.development.debian12-aarch64
+ development_2="release/6.2"
+ docker_tag_2="nightly-6.2-debian12"
+ development_builds_2=site.data.builds.swift-6_2-branch.debian12
+ aarch64_development_builds_2=site.data.builds.swift-6_2-branch.debian12-aarch64
+ branch_dir_2="swift-6.2-branch"
+%}
-{% include install/_linux_platforms_tabs.md debian="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.debian name="Debian" pressed="Debian 12" %}
-
-{% include install/_build_release.md platform="Debian 12" docker_tag="debian12" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Debian 12" %}
-
-
-{% include install/_build_snapshot.md platform="Debian 12"
-aarch64="true"
-branch_dir="development"
-development="main"
-docker_tag="nightly-debian-12"
-development_builds=site.data.builds.development.debian12
-aarch64_development_builds=site.data.builds.development.debian12-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-debian12"
-development_builds_2=site.data.builds.swift-6_1-branch.debian12 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.debian12-aarch64
-branch_dir_2="swift-6.1-branch"%}
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
diff --git a/install/linux/debian/index.md b/install/linux/debian/index.md
index 53fa538bb..e056bdc7e 100644
--- a/install/linux/debian/index.md
+++ b/install/linux/debian/index.md
@@ -1,10 +1,4 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md debian="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.debian name="Debian" %}
diff --git a/install/linux/fedora/39/index.md b/install/linux/fedora/39/index.md
index 4853a93f5..8248a06be 100644
--- a/install/linux/fedora/39/index.md
+++ b/install/linux/fedora/39/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
+{% include /new-includes/assigns/linux-platform-builds.html
+ platform="Fedora 39"
+ aarch64="true"
+ branch_dir="development"
+ development="main"
+ docker_tag="nightly-fedora-39"
+ development_builds=site.data.builds.development.fedora39
+ aarch64_development_builds=site.data.builds.development.fedora39-aarch64
+ development_2="release/6.2"
+ docker_tag_2="nightly-6.2-fedora39"
+ development_builds_2=site.data.builds.swift-6_2-branch.fedora39
+ aarch64_development_builds_2=site.data.builds.swift-6_2-branch.fedora39-aarch64
+ branch_dir_2="swift-6.2-branch"
+%}
-{% include install/_linux_platforms_tabs.md fedora="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.fedora name="Fedora" pressed="Fedora 39" %}
-
-{% include install/_build_release.md platform="Fedora 39" docker_tag="fedora39" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Fedora 39" %}
-
-
-{% include install/_build_snapshot.md platform="Fedora 39"
-aarch64="true"
-branch_dir="development"
-development="main"
-docker_tag="nightly-fedora-39"
-development_builds=site.data.builds.development.fedora39
-aarch64_development_builds=site.data.builds.development.fedora39-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-fedora39"
-development_builds_2=site.data.builds.swift-6_1-branch.fedora39 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.fedora39-aarch64
-branch_dir_2="swift-6.1-branch"%}
\ No newline at end of file
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
\ No newline at end of file
diff --git a/install/linux/fedora/index.md b/install/linux/fedora/index.md
index 7a447c158..e056bdc7e 100644
--- a/install/linux/fedora/index.md
+++ b/install/linux/fedora/index.md
@@ -1,10 +1,4 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md fedora="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.fedora name="Fedora" %}
diff --git a/install/linux/index.md b/install/linux/index.md
index b5a4b9ccc..4a4100c60 100644
--- a/install/linux/index.md
+++ b/install/linux/index.md
@@ -1,7 +1,31 @@
---
-layout: page-wide
-title: 安装 Swift
+redirect_from:
+ - '/download/'
+layout: new-layouts/install
+title: 安装 Swift - Linux
---
-{% include install/_os_tabs.md linux="true" %}
-{% include install/_linux_platforms_tabs.md %}
+
+
+
+ {% include new-includes/components/code-box.html with-tabs = true content = site.data.new-data.install.linux.releases.latest-release.swiftly %}
+
+
+
+
+ {% include new-includes/components/code-box.html content = site.data.new-data.install.linux.releases.latest-release.container %}
+
+
+
+
+ {% include new-includes/components/static-linux-sdk.html %}
+
+
+
+
diff --git a/install/linux/ubi/9/index.md b/install/linux/ubi/9/index.md
index 1d3dd8a96..f8feaea28 100644
--- a/install/linux/ubi/9/index.md
+++ b/install/linux/ubi/9/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
+{% include /new-includes/assigns/linux-platform-builds.html
+ platform="ubi 9"
+ aarch64="true"
+ branch_dir="development"
+ development="main"
+ docker_tag="nightly-rhel-ubi9"
+ development_builds=site.data.builds.development.ubi9
+ aarch64_development_builds=site.data.builds.development.ubi9-aarch64
+ development_2="release/6.2"
+ docker_tag_2="nightly-6.2-rhel-ubi9"
+ development_builds_2=site.data.builds.swift-6_2-branch.ubi9
+ aarch64_development_builds_2=site.data.builds.swift-6_2-branch.ubi9-aarch64
+ branch_dir_2="swift-6.2-branch"
+%}
-{% include install/_linux_platforms_tabs.md ubi="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubi name="Red Hat 通用基础镜像" pressed="Red Hat 通用基础镜像 9" %}
-
-{% include install/_build_release.md platform="UBI 9" docker_tag="rhel-ubi9" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Red Hat 通用基础镜像 9" %}
-
-
-{% include install/_build_snapshot.md platform="ubi 9"
-aarch64="true"
-branch_dir="development"
-development="main"
-docker_tag="nightly-rhel-ubi9"
-development_builds=site.data.builds.development.ubi9
-aarch64_development_builds=site.data.builds.development.ubi9-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-rhel-ubi9"
-development_builds_2=site.data.builds.swift-6_1-branch.ubi9 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.ubi9-aarch64
-branch_dir_2="swift-6.1-branch"%}
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
\ No newline at end of file
diff --git a/install/linux/ubi/index.md b/install/linux/ubi/index.md
index 449ce3a0a..e056bdc7e 100644
--- a/install/linux/ubi/index.md
+++ b/install/linux/ubi/index.md
@@ -1,10 +1,4 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md ubi="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubi name="Red Hat 通用基础镜像" %}
diff --git a/install/linux/ubuntu/20_04/index.md b/install/linux/ubuntu/20_04/index.md
index d1308361d..0ecbbeaa2 100644
--- a/install/linux/ubuntu/20_04/index.md
+++ b/install/linux/ubuntu/20_04/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md ubuntu="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubuntu name="Ubuntu" pressed="Ubuntu 20.04" %}
-
-{% include install/_build_release.md platform="Ubuntu 20.04" docker_tag="focal" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Ubuntu 20.04" %}
-
-
-{% include install/_build_snapshot.md platform="Ubuntu 20.04"
+{% include /new-includes/assigns/linux-platform-builds.html
+platform="Ubuntu 20.04"
aarch64="true"
branch_dir="development"
development="main"
docker_tag="nightly-focal"
development_builds=site.data.builds.development.ubuntu2004
aarch64_development_builds=site.data.builds.development.ubuntu2004-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-focal"
-development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2004 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2004-aarch64
-branch_dir_2="swift-6.1-branch"%}
+development_2="release/6.2"
+docker_tag_2="nightly-6.2-focal"
+development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2004
+aarch64_development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2004-aarch64
+branch_dir_2="swift-6.2-branch"
+%}
+
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
\ No newline at end of file
diff --git a/install/linux/ubuntu/22_04/index.md b/install/linux/ubuntu/22_04/index.md
index 0e9c7fbc6..9d9c79a5a 100644
--- a/install/linux/ubuntu/22_04/index.md
+++ b/install/linux/ubuntu/22_04/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md ubuntu="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubuntu name="Ubuntu" pressed="Ubuntu 22.04" %}
-
-{% include install/_build_release.md platform="Ubuntu 22.04" docker_tag="jammy" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Ubuntu 22.04" %}
-
-
-{% include install/_build_snapshot.md platform="Ubuntu 22.04"
+{% include /new-includes/assigns/linux-platform-builds.html
+platform="Ubuntu 22.04"
aarch64="true"
branch_dir="development"
development="main"
docker_tag="nightly-jammy"
development_builds=site.data.builds.development.ubuntu2204
aarch64_development_builds=site.data.builds.development.ubuntu2204-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-jammy"
-development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2204 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2204-aarch64
-branch_dir_2="swift-6.1-branch"%}
+development_2="release/6.2"
+docker_tag_2="nightly-6.2-jammy"
+development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2204
+aarch64_development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2204-aarch64
+branch_dir_2="swift-6.2-branch"
+%}
+
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
\ No newline at end of file
diff --git a/install/linux/ubuntu/24_04/index.md b/install/linux/ubuntu/24_04/index.md
index 32c4aa9eb..7150b8899 100644
--- a/install/linux/ubuntu/24_04/index.md
+++ b/install/linux/ubuntu/24_04/index.md
@@ -1,29 +1,31 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md ubuntu="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubuntu name="Ubuntu" pressed="Ubuntu 24.04" %}
-
-{% include install/_build_release.md platform="Ubuntu 24.04" docker_tag="noble" %}
-
-
- 历史版本
- {% include install/_older-releases.md platform="Ubuntu 24.04" %}
-
-
-{% include install/_build_snapshot.md platform="Ubuntu 24.04"
+{% include /new-includes/assigns/linux-platform-builds.html
+platform="Ubuntu 24.04"
aarch64="true"
branch_dir="development"
development="main"
docker_tag="nightly-noble"
development_builds=site.data.builds.development.ubuntu2404
aarch64_development_builds=site.data.builds.development.ubuntu2404-aarch64
-development_2="release/6.1"
-docker_tag_2="nightly-6.1-noble"
-development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2404 aarch64_development_builds_2=site.data.builds.swift-6_1-branch.ubuntu2404-aarch64
-branch_dir_2="swift-6.1-branch"%}
+development_2="release/6.2"
+docker_tag_2="nightly-6.2-noble"
+development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2404
+aarch64_development_builds_2=site.data.builds.swift-6_2-branch.ubuntu2404-aarch64
+branch_dir_2="swift-6.2-branch"
+%}
+
+{% include /new-includes/components/linux-releases.html
+ docker_tag=docker_tag
+ development_builds=development_builds
+ development_builds_2=development_builds_2
+ platform=platform
+ development=development
+ development_2=development_2
+ platform_name_url=platform_name_url
+ branch_dir=branch_dir
+ branch_dir_2=branch_dir_2
+%}
\ No newline at end of file
diff --git a/install/linux/ubuntu/index.md b/install/linux/ubuntu/index.md
index b7c45d2b4..e056bdc7e 100644
--- a/install/linux/ubuntu/index.md
+++ b/install/linux/ubuntu/index.md
@@ -1,10 +1,4 @@
---
-layout: page-wide
+layout: new-layouts/install-linux-version
title: 安装 Swift
---
-
-{% include install/_os_tabs.md linux="true" %}
-
-{% include install/_linux_platforms_tabs.md ubuntu="true" %}
-
-{% include install/_os_versions_tabs.md os_versions=site.data.install.ubuntu name="Ubuntu" %}
diff --git a/install/macos/_old-release.html b/install/macos/_old-release.html
index 16282971e..891c1d58e 100644
--- a/install/macos/_old-release.html
+++ b/install/macos/_old-release.html
@@ -20,12 +20,7 @@
{% assign static_sdk = release_info.platforms | where: 'name', 'Static SDK'| first %}
{% if static_sdk %}
{% assign tag_downcase = include.release.tag | downcase %}
-
复制安装命令
-
+
复制安装命令
{% else %}
暂不可用
{% endif %}
diff --git a/install/macos/_older-6_1-snapshots.md b/install/macos/_older-6_1-snapshots.md
index 6372bc4a2..4297b70ba 100644
--- a/install/macos/_older-6_1-snapshots.md
+++ b/install/macos/_older-6_1-snapshots.md
@@ -1,4 +1,4 @@
-
+
下载
@@ -9,4 +9,4 @@
{% include_relative _old-snapshot.html build=build name="Xcode" platform_dir="xcode" branch_dir="swift-6.1-branch" %}
{% endfor %}
-
\ No newline at end of file
+
diff --git a/install/macos/_older-6_2-snapshots.md b/install/macos/_older-6_2-snapshots.md
new file mode 100644
index 000000000..42c233d36
--- /dev/null
+++ b/install/macos/_older-6_2-snapshots.md
@@ -0,0 +1,12 @@
+
+
+
+ Download
+
+
+
+ {% for build in xcode_6_2_builds | offset:1 | limit:10 %}
+ {% include_relative _old-snapshot.html build=build name="Xcode" platform_dir="xcode" branch_dir="swift-6.2-branch" %}
+ {% endfor %}
+
+
diff --git a/install/macos/_older-development-snapshots.md b/install/macos/_older-development-snapshots.md
index 0d234c516..cd4f71246 100644
--- a/install/macos/_older-development-snapshots.md
+++ b/install/macos/_older-development-snapshots.md
@@ -1,4 +1,4 @@
-
+
下载
diff --git a/install/macos/_older-releases.md b/install/macos/_older-releases.md
index 96a4f3ee3..34e36320f 100644
--- a/install/macos/_older-releases.md
+++ b/install/macos/_older-releases.md
@@ -1,4 +1,4 @@
-
+
版本
@@ -16,5 +16,6 @@
{% endunless %}
{% endfor %}
-
-
\ No newline at end of file
+
+
+
diff --git a/install/macos/index.md b/install/macos/index.md
index 8e8cd31a1..ffef77169 100644
--- a/install/macos/index.md
+++ b/install/macos/index.md
@@ -1,106 +1,123 @@
---
-layout: page-wide
-title: 安装 Swift
+redirect_from:
+ - '/download/'
+layout: new-layouts/install
+title: 安装 Swift - macOS
---
-{% include install/_os_tabs.md macos="true" %}
-
-## 最新版本
-
-
-
-
-## 其他安装选项
-
-
-
- 历史版本
- {% include_relative _older-releases.md %}
-
-
-
-
-## 开发快照版本
-
-Swift 快照是从分支自动创建的预构建二进制文件。这些快照不是官方发布版本。它们已经通过了自动化单元测试,但没有经过官方发布版本所需的完整测试。
-
-安装开发快照最简单的方法是使用 Swiftly 工具。更多信息请查看[说明页面](/install/macos/swiftly)。
-
{% assign xcode_dev_builds = site.data.builds.development.xcode | sort: 'date' | reverse %}
-{% assign xcode_6_1_builds = site.data.builds.swift-6_1-branch.xcode | sort: 'date' | reverse %}
+{% assign xcode_6_2_builds = site.data.builds.swift-6_2-branch.xcode | sort: 'date' | reverse %}
-工具链
-