diff --git a/.gitignore b/.gitignore
index a307529d7..2f1c7a73a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,5 @@ venv
site_libs
.DS_Store
index_files
-digest.txt
\ No newline at end of file
+digest.txt
+**/*.quarto_ipynb
diff --git a/assets/images/workflow/fff.png b/assets/images/workflow/fff.png
new file mode 100644
index 000000000..539ea4d85
Binary files /dev/null and b/assets/images/workflow/fff.png differ
diff --git a/index.qmd b/index.qmd
index 9f825d860..cf8500db1 100644
--- a/index.qmd
+++ b/index.qmd
@@ -100,15 +100,20 @@ Turing is written entirely in Julia, and is interoperable with its powerful ecos
:::
-::: {.code-window-title}
+::: {.code-window-tabs}
```{=html}
-linear_regression.jl
+Model
+Condition
+Prior
+Inference
+Analysis
```
:::
:::
+::: {#tab-model .code-content .active}
```{.julia .code-overflow-scroll}
using Turing
@@ -122,11 +127,41 @@ using Turing
μ = α .+ β .* x
y ~ MvNormal(μ, σ² * I)
end
+```
+:::
+
+::: {#tab-condition .code-content}
+```julia
+# Data
+x_data = rand(10)
+y_data = rand(10)
+
+# Condition model on data
+model = linear_regression(x_data) | (; y = y_data)
+```
+:::
+
+::: {#tab-prior .code-content}
+```julia
+# Sample from the prior
+prior = sample(model, Prior(), 100)
+```
+:::
+
+::: {#tab-inference .code-content}
+```julia
+# Run inference using NUTS
+chain = sample(model, NUTS(), 1000)
+```
+:::
-x, y = rand(10), rand(10)
-posterior = linear_regression(x) | (; y = y)
-chain = sample(posterior, NUTS(), 1000)
+::: {#tab-analysis .code-content}
+```julia
+# Analyze the posterior
+describe(chain)
+plot(chain)
```
+:::
:::
:::
@@ -134,7 +169,374 @@ chain = sample(posterior, NUTS(), 1000)
:::
+
+::: {.flowchart-section-custom}
+
+::: {.flowchart-header}
+### The Bayesian Workflow
+From model definition to posterior analysis, Turing.jl provides a seamless experience.
+:::
+
+::: {.flowchart-container}
+
+```{=html}
+
+```
+
+::: {#node-math .flow-node}
+::: {.node-header}
+Mathematical Specification
+:::
+::: {.node-body}
+$$
+\begin{align*}
+ \sigma^2 &\sim \text{InverseGamma}(3, 4/10) \\
+ \gamma &\sim \mathcal{N}(0, \sqrt{10}) \\
+ \beta &\sim \mathcal{N}(0, I) \\
+ y_i &\sim \log \mathcal{N}(\beta \cdot x_i + \gamma, \sigma)
+\end{align*}
+$$
+:::
+:::
+
+::: {#node-model .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+linear_regression.jl
+:::
+::: {.node-body}
+```julia
+@model function linear_regression(x)
+ d = size(x, 1)
+
+ # Priors
+ σ² ~ InverseGamma(3, 4 / 10)
+ γ ~ Normal(0, √10)
+ β ~ MvNormal(zeros(d), I)
+
+ # Likelihood
+ y ~ MvLogNormal(x' * β .+ γ, σ² * I)
+end
+
+model = linear_regression(x_data)
+```
+:::
+:::
+
+::: {#node-prior .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Prior Checks
+:::
+::: {.node-body}
+```julia
+model_gen = fix(model, params_gen)
+(; y) = rand(model_gen)
+chain_gen = sample(model | (y = y,), NUTS(), 1000)
+```
+:::
+:::
+
+::: {#node-condition .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Condition
+:::
+::: {.node-body}
+```julia
+model_conditioned = model | (y = y_data,)
+```
+:::
+:::
+
+::: {#node-determinability .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Determinability
+:::
+::: {.node-body}
+::: {.node-plot}
+{fig-alt="Determinability Plot"}
+:::
+:::
+:::
+
+::: {#node-inference .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Inference
+:::
+::: {.node-body}
+```julia
+chain = sample(model_conditioned, NUTS(), 1000)
+```
+:::
+:::
+
+::: {#node-analysis .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Posterior Analysis
+:::
+::: {.node-body}
+```
+Summary Statistics
+parameters mean std mcse
+σ² 0.0543 0.0032 0.0000
+γ 7.7252 0.3688 0.0066
+β[1] -0.2270 0.1247 0.0022
+β[2] 0.0133 0.1229 0.0022
+```
+::: {.node-plot}
+{fig-alt="Posterior Density"}
+:::
+:::
+:::
+
+::: {#node-predictions .flow-node}
+::: {.node-header}
+::: {.node-dots}
+[]{.dot .red} []{.dot .yellow} []{.dot .green}
+:::
+Posterior Predictions
+:::
+::: {.node-body}
+::: {.node-plot}
+{fig-alt="Posterior Prediction"}
+:::
+:::
+:::
+
+:::
+
+:::
+```{=html}
+
+```
+
+
:::: {.section-header .section-start-space}
diff --git a/theming/rules/_flowchart.scss b/theming/rules/_flowchart.scss
new file mode 100644
index 000000000..cc5191c73
--- /dev/null
+++ b/theming/rules/_flowchart.scss
@@ -0,0 +1,186 @@
+.flowchart-section-custom {
+ padding: 4rem 0;
+ background-color: $body-bg;
+ transition: background-color 0.3s ease;
+ position: relative;
+}
+
+.flowchart-header {
+ text-align: center;
+ margin-bottom: 3rem;
+
+ h3 {
+ color: $text-color;
+ margin-bottom: 1rem;
+ }
+
+ p {
+ color: $text-muted;
+ max-width: 700px;
+ margin: 0 auto;
+ }
+}
+
+.flowchart-container {
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ column-gap: 8rem;
+ row-gap: 3rem;
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 2rem;
+ z-index: 1;
+}
+
+/* SVG Overlay Layer */
+.flow-svg-layer {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none; /* Let clicks pass through */
+ z-index: 0;
+ overflow: visible;
+}
+
+.flow-arrow-path {
+ fill: none;
+ stroke: $text-muted; // Using text-muted as a proxy for the line color
+ stroke-width: 2px;
+ transition: stroke 0.3s ease;
+ opacity: 0.5;
+}
+
+.flow-arrow-head {
+ fill: $text-muted;
+ transition: fill 0.3s ease;
+ opacity: 0.5;
+}
+
+.flow-node {
+ background: $panel-bg;
+ border-radius: 12px;
+ box-shadow: 0 4px 12px $box-shadow-color;
+ border: 1px solid $btn-border-color;
+ display: flex;
+ flex-direction: column;
+ transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
+ z-index: 2;
+ position: relative;
+
+ &:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 12px 24px rgba(0,0,0,0.1); // Keep this generic or use a darker shadow var if available
+ border-color: $teal;
+ }
+}
+
+// Dark mode specific hover shadow adjustment
+body.quarto-dark .flow-node:hover {
+ box-shadow: 0 12px 24px rgba(0,0,0,0.5);
+}
+
+.node-header {
+ padding: 0.75rem 1rem;
+ background: rgba(0,0,0,0.03);
+ border-bottom: 1px solid $btn-border-color;
+ font-family: "SF Mono", "Fira Code", monospace;
+ font-size: 0.85rem;
+ color: $text-muted;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border-radius: 12px 12px 0 0;
+}
+
+.node-dots {
+ display: flex;
+ gap: 6px;
+}
+
+.node-body {
+ padding: 1rem;
+ font-size: 0.9rem;
+ color: $text-color;
+
+ pre {
+ margin: 0 !important;
+ padding: 0 !important;
+ background: $code-block-bg !important;
+ border: none !important;
+ white-space: pre-wrap;
+ color: $text-color;
+ }
+}
+
+/* Syntax Highlighting Adjustments for Dark Mode */
+body.quarto-dark .sourceCode {
+ .kw { color: #c792ea; }
+ .fu { color: #82aaff; }
+ .fl { color: #f78c6c; }
+ .st { color: #c3e88d; }
+ .op { color: #89ddff; }
+ .pp { color: #c792ea; }
+}
+
+.node-plot {
+ margin-top: 1rem;
+ border: 1px solid $btn-border-color;
+ border-radius: 6px;
+ overflow: hidden;
+ background: white; // Plots are usually on white background
+
+ img {
+ display: block;
+ width: 100%;
+ height: auto;
+ }
+}
+
+/* Grid Positioning */
+#node-math { grid-column: 1; grid-row: 1; }
+#node-model { grid-column: 2; grid-row: 1; }
+
+#node-prior { grid-column: 1; grid-row: 2; margin-top: 2rem; }
+#node-condition { grid-column: 2; grid-row: 2; margin-top: 2rem; }
+
+#node-determinability { grid-column: 1; grid-row: 3; }
+#node-inference { grid-column: 2; grid-row: 3; }
+
+#node-analysis { grid-column: 2; grid-row: 4; }
+#node-predictions { grid-column: 2; grid-row: 5; }
+
+#node-math .node-body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 1.1rem;
+}
+
+/* Responsive */
+@media (max-width: 992px) {
+ .flowchart-container {
+ grid-template-columns: 1fr;
+ gap: 3rem;
+ padding: 1rem;
+ }
+
+ #node-math, #node-model, #node-prior, #node-condition,
+ #node-determinability, #node-inference, #node-analysis, #node-predictions {
+ grid-column: 1;
+ grid-row: auto;
+ margin-top: 0;
+ }
+
+ /* Reorder for linear flow on mobile */
+ #node-math { order: 1; }
+ #node-model { order: 2; }
+ #node-prior { order: 3; }
+ #node-determinability { order: 4; }
+ #node-condition { order: 5; }
+ #node-inference { order: 6; }
+ #node-analysis { order: 7; }
+ #node-predictions { order: 8; }
+}
diff --git a/theming/rules/_layouts.scss b/theming/rules/_layouts.scss
index e7ebb441c..79a1f217c 100644
--- a/theming/rules/_layouts.scss
+++ b/theming/rules/_layouts.scss
@@ -184,6 +184,7 @@
align-items: center;
border-bottom: 1px solid lighten($btn-border-color, 5%);
position: relative;
+ justify-content: space-between; /* Changed to space-between to push tabs to right */
}
.code-window-dots {
@@ -200,14 +201,45 @@
font-size: 0.8rem;
}
- .dot {
- width: 13px;
- height: 13px;
- border-radius: 50%;
- display: inline-block;
- &.red { background-color: #ff5f56; }
- &.yellow { background-color: #ffbd2e; }
- &.green { background-color: #27c93f; }
+ .code-window-tabs {
+ display: flex;
+ gap: 1rem;
+ z-index: 10; /* Ensure tabs are clickable above title if they overlap */
+ }
+
+ .tab {
+ cursor: pointer;
+ color: $text-muted;
+ font-size: 0.85rem;
+ font-weight: 600;
+ padding: 0.2rem 0.6rem;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+ user-select: none;
+
+ &:hover {
+ color: $text-color;
+ background-color: rgba(0,0,0,0.05);
+ }
+
+ &.active {
+ color: $primary;
+ background-color: rgba($primary, 0.1);
+ }
+ }
+
+ .code-content {
+ display: none;
+
+ &.active {
+ display: block;
+ animation: fadeIn 0.3s ease;
+ }
+ }
+
+ @keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
}
.sourceCode {
@@ -229,6 +261,16 @@
}
}
+.dot {
+ width: 13px;
+ height: 13px;
+ border-radius: 50%;
+ display: inline-block;
+ &.red { background-color: #ff5f56; }
+ &.yellow { background-color: #ffbd2e; }
+ &.green { background-color: #27c93f; }
+}
+
/* Core Packages Section */
.core-packages-grid {
display: grid;
@@ -326,41 +368,219 @@
white-space: nowrap;
}
-.unified-card-footer {
- padding: 1rem 1.5rem;
- border-top: 1px solid lighten($panel-bg, 7%);
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 0.85rem;
- color: $text-muted;
- background-color: $background-body;
+/* Split View for Code and Plots */
+.split-view {
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ min-height: 350px; /* Ensure enough height for plot */
+ background-color: $code-block-bg;
}
-.unified-card-meta {
+.split-code {
+ flex: 1;
+ min-width: 0; /* Prevent overflow */
+ display: flex;
+ flex-direction: column;
+
+ /* Override quarto code block margins */
+ div.sourceCode {
+ margin: 0 !important;
+ height: 100%;
display: flex;
flex-direction: column;
- gap: 0.25rem;
- min-width: 0;
+ }
+
+ pre {
flex-grow: 1;
+ margin: 0 !important;
+ border-radius: 0 0 0 4px !important;
+ }
}
-.unified-card-author {
- font-weight: 600;
- color: $text-color;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+.split-plot {
+ flex: 1;
+ background-color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-left: 1px solid darken($code-block-bg, 5%);
+ padding: 1rem;
+
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ height: auto;
+ object-fit: contain;
+ filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
+ }
}
-.unified-card-date {
- font-size: 0.8rem;
+/* Responsive: Stack on small screens */
+@media (max-width: 992px) {
+ .split-view {
+ flex-direction: column;
+ }
+
+ .split-plot {
+ border-left: none;
+ border-top: 1px solid darken($code-block-bg, 5%);
+ min-height: 250px;
+ padding: 1.5rem;
+ }
+
+ .split-code pre {
+ border-radius: 0 !important;
+ }
+}
+
+/* Workflow Section Styles */
+.workflow-container {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ gap: 2rem;
+ align-items: start;
+}
+
+.workflow-nav {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ padding: 1rem 0;
+}
+
+.workflow-step {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1rem;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ border: 1px solid transparent;
+
+ &:hover {
+ background-color: rgba($primary, 0.05);
+ }
+
+ &.active {
+ background-color: white;
+ border-color: $btn-border-color;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.05);
+
+ .step-marker {
+ background-color: $primary;
+ color: white;
+ border-color: $primary;
+ }
+
+ .step-label {
+ color: $primary;
+ }
+ }
+}
+
+.step-marker {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ border: 2px solid $text-muted;
+ color: $text-muted;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 700;
+ font-size: 0.9rem;
+ flex-shrink: 0;
+ transition: all 0.2s ease;
+ background-color: white;
+ z-index: 2;
+}
+
+.step-info {
+ display: flex;
+ flex-direction: column;
+}
+
+.step-label {
+ font-weight: 700;
+ color: $text-color;
+ font-size: 1rem;
+ transition: color 0.2s ease;
+}
+
+.step-desc {
+ font-size: 0.85rem;
+ color: $text-muted;
+ line-height: 1.3;
+}
+
+.workflow-connector {
+ width: 2px;
+ height: 20px;
+ background-color: $border-color;
+ margin-left: 26px; /* Center with marker (16px + 1rem padding) */
+ margin-top: -5px;
+ margin-bottom: -5px;
+ z-index: 1;
+}
+
+.workflow-display {
+ min-height: 450px;
+ background-color: white;
+ overflow: hidden;
+}
+
+.workflow-content {
+ display: none;
+ animation: fadeIn 0.3s ease;
+
+ &.active {
+ display: block;
+ }
+}
+
+.content-header {
+ padding: 1.5rem;
+ border-bottom: 1px solid $border-color;
+
+ h5 {
+ margin-bottom: 0.5rem;
+ font-weight: 700;
+ }
+
+ p {
+ margin-bottom: 0;
color: $text-muted;
+ }
}
-.unified-card-reading-time {
- font-weight: 600;
- color: $teal;
- white-space: nowrap;
- font-size: 0.8rem;
+@media (max-width: 992px) {
+ .workflow-container {
+ grid-template-columns: 1fr;
+ }
+
+ .workflow-nav {
+ flex-direction: row;
+ overflow-x: auto;
+ padding-bottom: 1rem;
+ gap: 1rem;
+ }
+
+ .workflow-step {
+ min-width: 200px;
+ flex-direction: column;
+ text-align: center;
+ align-items: center;
+ padding: 1rem;
+ border: 1px solid $border-color;
+ }
+
+ .workflow-connector {
+ display: none;
+ }
+
+ .step-marker {
+ margin-bottom: 0.5rem;
+ }
}
diff --git a/theming/theme-dark.scss b/theming/theme-dark.scss
index f54f90524..e2088193c 100644
--- a/theming/theme-dark.scss
+++ b/theming/theme-dark.scss
@@ -16,6 +16,7 @@
@import "rules/quarto-tweaks";
@import "rules/responsive";
@import "rules/hoverables-dark";
+@import "rules/flowchart";
.hero-logo-light {
display: none;
diff --git a/theming/theme-light.scss b/theming/theme-light.scss
index 3242b3f3a..076b6fac8 100644
--- a/theming/theme-light.scss
+++ b/theming/theme-light.scss
@@ -16,6 +16,7 @@
@import "rules/responsive";
@import "rules/quarto-tweaks";
@import "rules/hoverables-light";
+@import "rules/flowchart";
.hero-logo-light {
display: block;
diff --git a/workflow.md b/workflow.md
new file mode 100644
index 000000000..cca78583d
--- /dev/null
+++ b/workflow.md
@@ -0,0 +1,72 @@
+```
+\begin{align*}
+ \sigma^2 &\sim \text{InverseGamma}(3, 4/10) \\
+ \gamma &\sim \mathcal{N}(0, \sqrt{10}) \\
+ \beta &\sim \mathcal{N}(0, I) \\
+ y_i &\sim \log \mathcal{N}(\beta \cdot x_i + \gamma, \sigma) \quad \text{for } i = 1, \dots, N
+\end{align*}
+```
+
+to Turing.jl:
+
+Let's give id 1 to this block
+```julia
+@model function linear_regression(x)
+ d = size(x, 1)
+
+ # Priors
+ σ² ~ InverseGamma(3, 4 / 10)
+ γ ~ Normal(0, √10)
+ β ~ MvNormal(zeros(d), I)
+
+ # Likelihood
+ y ~ MvLogNormal(x' * β .+ γ, σ² * I)
+end
+
+model = linear_regression(x_data)
+```
+
+From id 1 to Prior Checks:
+
+```julia
+model_gen = fix(model, params_gen)
+(; y) = rand(model_gen)
+chain_gen = sample(model | (y = y,), NUTS(), 1000)
+```
+
+From Prior Checks to Determinability (ID 2):
+
+PLOT Image
+
+From ID 1, also goes Condition:
+
+```julia
+model_conditioned = model | (y = y_data,)
+```
+
+Condtion to Perform Inference:
+
+```julia
+chain = sample(model_conditioned, NUTS(), 1000)
+```
+
+Perform Inference to Post-inference Analysis:
+
+```
+Summary Statistics
+parameters mean std mcse ...
+Symbol Float64 Float64 Float64 ...
+
+σ² 0.0543 0.0032 0.0000 ...
+γ 7.7252 0.3688 0.0066 ...
+β[1] -0.2270 0.1247 0.0022 ...
+β[2] 0.0133 0.1229 0.0022 ...
+```
+
+Plot Image
+
+Then to Posterior Predictions (ID 3):
+
+Plot image
+
+From ID 3 to ID 2 (Determinability) in a dashed line arrow with label "Iterate if necessary"
\ No newline at end of file