Exsolvent Field — Rational Function Visualizer.html
Exsolvent Field — Rational Function Visualizer.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Exsolvent Field — Rational Function Visualizer</title>
<!-- Plotly CDN for interactive 3D and 2D plots -->
<script src="[Link]
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #0b0e14;
color: #e0e4ea;
margin: 0;
padding: 20px;
}
.app-container {
max-width: 1400px;
margin: 0 auto;
}
h1 {
text-align: center;
font-weight: 300;
letter-spacing: 2px;
border-bottom: 1px solid #2a3a4a;
padding-bottom: 15px;
color: #b8d0e0;
}
h1 span {
color: #6a9bbf;
font-weight: 500;
}
.subtitle {
text-align: center;
color: #8899aa;
font-style: italic;
margin-top: -12px;
margin-bottom: 30px;
font-size: 0.95rem;
}
.controls {
display: flex;
flex-wrap: wrap;
gap: 30px 50px;
background: #141a22;
padding: 20px 30px;
border-radius: 12px;
margin-bottom: 30px;
border: 1px solid #2a3a4a;
justify-content: center;
}
.control-group {
display: flex;
flex-direction: column;
min-width: 160px;
}
.control-group label {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 1px;
color: #7a8fa0;
margin-bottom: 4px;
}
.control-group .value {
font-size: 1rem;
font-weight: 600;
color: #b0d0e8;
}
input[type="range"] {
width: 100%;
min-width: 120px;
background: #1e2a34;
height: 4px;
border-radius: 4px;
-webkit-appearance: none;
appearance: none;
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
border-radius: 50%;
background: #6a9bbf;
cursor: pointer;
border: none;
transition: 0.1s;
}
input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.15);
background: #8ab8df;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 25px;
}
.plot-card {
background: #141a22;
border-radius: 12px;
padding: 15px;
border: 1px solid #1e2e3e;
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
}
.plot-card h3 {
margin: 0 0 10px 0;
font-weight: 400;
font-size: 1rem;
color: #9ab0c8;
letter-spacing: 0.5px;
}
.plot-card .sub {
font-size: 0.75rem;
color: #6a7f90;
margin-top: -6px;
margin-bottom: 12px;
}
.plot-card .plot-container {
width: 100%;
height: 400px;
}
.full-width {
grid-column: 1 / -1;
}
.footer-note {
text-align: center;
font-size: 0.8rem;
color: #4a5f70;
margin-top: 30px;
border-top: 1px solid #1a2a3a;
padding-top: 20px;
}
.footer-note a {
color: #6a9bbf;
text-decoration: none;
}
@media (max-width: 900px) {
.grid-container {
grid-template-columns: 1fr;
}
.controls {
gap: 15px;
padding: 15px;
}
}
</style>
</head>
<body>
<div class="app-container">
<h1> <span>Exsolvent</span> Field Visualizer</h1>
<div class="subtitle">Rational Function Field for Multi-Scale Porous Media —
Weighted Polynomial Upscaling</div>
<div class="footer-note">
⚡ The Watcher inhabits the gap between the abstract field (top) and the
physical ground (bottom).<br/>
Drag sliders to explore the structural tension. <span
style="color:#4a6a7a;">— Exsolvent Geometry v1.0</span>
</div>
</div>
<script>
(function() {
"use strict";
[Link] = [Link](2);
[Link] = [Link](2);
[Link] = [Link](2);
[Link] = [Link](2);
[Link] = res;
const n = res;
const data = computeField(n, phiC, alpha, k);
const layout3d = {
margin: { l: 30, r: 30, b: 40, t: 20 },
scene: {
xaxis: { title: 'Porosity φ', color: '#8899aa' },
yaxis: { title: 'Permeability k', color: '#8899aa' },
zaxis: { title: 'K<sub>eff</sub>', color: '#8899aa' },
bgcolor: '#0b0e14',
camera: { eye: { x: 1.8, y: 1.8, z: 1.2 } }
},
paper_bgcolor: '#141a22',
plot_bgcolor: '#0b0e14',
font: { color: '#c0d0e0' }
};
const traceContour = {
type: 'contour',
x: [Link],
y: [Link],
z: pMatrix,
colorscale: 'Viridis',
showscale: true,
colorbar: { title: 'P(φ,k)', len: 0.6 },
contours: { coloring: 'heatmap' },
hovertemplate: 'φ: %{x:.2f}<br>k: %{y:.2f}<br>P:
%{z:.2f}<extra></extra>'
};
const layoutContour = {
margin: { l: 40, r: 30, b: 40, t: 20 },
xaxis: { title: 'Porosity φ', color: '#8899aa', gridcolor:
'#1a2a3a' },
yaxis: { title: 'Matrix Permeability k', color: '#8899aa',
gridcolor: '#1a2a3a' },
paper_bgcolor: '#141a22',
plot_bgcolor: '#0b0e14',
font: { color: '#c0d0e0' }
};
const traceLattice = {
type: 'heatmap',
z: zLattice,
colorscale: [[0, '#0a0f18'], [1, '#d0e4f0']],
showscale: false,
hovertemplate: 'x: %{x}<br>y: %{y}<br>Pore: %{z}<extra></extra>'
};
const layoutLattice = {
margin: { l: 10, r: 10, b: 10, t: 20 },
xaxis: { showgrid: false, showticklabels: false, range: [-1,
size] },
yaxis: { showgrid: false, showticklabels: false, range: [-1, size],
scaleanchor: 'x' },
paper_bgcolor: '#141a22',
plot_bgcolor: '#0b0e14',
font: { color: '#c0d0e0' },
annotations: [{
x: 0.5,
y: 1.05,
xref: 'paper',
yref: 'paper',
text: `φ = ${[Link](2)} | p(pore) = $
{[Link](2)} | Largest cluster: ${[Link]} cells`,
showarrow: false,
font: { size: 11, color: '#8aaabc' }
}]
};
})();
</script>
</body>
</html>