/* Computational-sciences visualization — vertical flow.
   One HPC server (top) enumerates the compute types and feeds four scientific
   domains (bottom): genomics, Bioinformatics, machine learning & AI, CFD & CAE.
   Themed to the main site (warm ivory paper, clay accent, editorial mono).
   Embedded transparently as a hero backdrop. */

:root {
    --paper:        #F0EEE6;
    --card:         #FBFAF6;
    --ink:          #1A1A18;
    --ink-soft:     #3D3C37;
    --muted:        #6B6A62;
    --line:         #E2DED2;
    --line-strong:  #D6D1C4;

    /* Earthy accents (anchored on the site's clay) */
    --accent:   #CC785C;   /* clay        */
    --accent-2: #B5613F;   /* clay-deep   */
    --accent-3: #3F4A52;   /* slate       */
    --accent-4: #7C7A52;   /* olive       */
    --accent-5: #A8694A;   /* terracotta  */

    --text:  var(--ink-soft);
    --mono: "JetBrains Mono", "SF Mono", "Menlo", "Consolas", monospace;
    --sans: "Inter", "Helvetica Neue", system-ui, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
    height: 100%;
    background: transparent;
    color: var(--text);
    font-family: var(--sans);
    overflow: hidden;
}

.viz {
    min-height: 100%;
    width: 100%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px 16px;
}

.stack {
    width: 100%;
    max-width: 330px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* =========================================================== Server (top) */
.server {
    position: relative;
    width: clamp(200px, 62%, 230px);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 13px 16px 16px;
    box-shadow: 0 1px 2px rgba(40, 30, 20, 0.04),
                0 18px 40px -28px rgba(40, 30, 20, 0.35);
    z-index: 2;
}

.server__bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding-bottom: 11px;
    margin-bottom: 12px;
    border-bottom: 1px dashed var(--line-strong);
}

.server__name {
    font-family: var(--mono);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.26em;
    color: var(--accent-2);
}

.led {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--accent-4);
    animation: ledBlink 1.6s ease-in-out infinite;
}
.led.alt { background: var(--accent); animation-delay: 0.5s; }

@keyframes ledBlink {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.3; }
}

.server__chips {
    display: flex;
    justify-content: center;
    gap: 8px;
}

.chip {
    font-family: var(--mono);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    padding: 6px 0;
    flex: 1;
    text-align: center;
    border-radius: 6px;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    color: var(--accent);
    animation: chipPulse 3.2s ease-in-out infinite;
}
.chip[data-k="gpu"]  { color: var(--accent-5); animation-delay: 0.4s; }
.chip[data-k="tpu"]  { color: var(--accent-3); animation-delay: 0.8s; }
.chip[data-k="fpga"] { color: var(--accent-4); animation-delay: 1.2s; }

@keyframes chipPulse {
    0%, 100% { border-color: var(--line-strong); }
    50%      { border-color: color-mix(in srgb, currentColor 55%, var(--line-strong)); }
}

/* Momentary "under load" flash, toggled from script.js */
.chip.busy {
    background: color-mix(in srgb, currentColor 12%, var(--paper));
    border-color: color-mix(in srgb, currentColor 60%, var(--line-strong));
}

.server__mark {
    margin-top: 12px;
    text-align: center;
    font-family: var(--mono);
    font-size: 0.52rem;
    letter-spacing: 0.16em;
    color: var(--muted);
}

/* ===================================== Sciences (zigzag + per-wire links) */
/* Fixed-size flow field: the four domains are placed at known pixel positions
   so the SVG wires (same 330×440 coordinate space) land exactly on box tops.
   Each science is fed by its own wire from its own source on the HPC box. */
.sciences {
    --art-h: 70px;
    --box-w: 140px;        /* narrower science boxes */
    position: relative;
    width: 330px;
    height: 410px;
    margin: -4px auto 0;   /* nudge up so the wire sources sit at the server edge */
}

/* Each science box, absolutely placed in the zigzag */
.sci {
    position: absolute;
    width: var(--box-w);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    min-width: 0;
    z-index: 1;
}
.sci[data-sci="genomics"] { top: 40px;  right: 8px; }   /* right, top    */
.sci[data-sci="md"]       { top: 126px; left: 8px;  }   /* left,  lower  */
.sci[data-sci="ml"]       { top: 212px; right: 8px; }   /* right, lower  */
.sci[data-sci="cfd"]      { top: 298px; left: 8px;  }   /* left,  bottom */

/* Connector wires (SVG overlay sharing the 330×440 coordinate space) */
.links {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    z-index: 0;
    pointer-events: none;
}
.links__base path {
    fill: none;
    stroke: var(--line-strong);
    stroke-width: 1.4;
    vector-effect: non-scaling-stroke;
}
/* Animated data running down each wire */
.wf {
    fill: none;
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
    stroke-linecap: round;
    stroke-dasharray: 12 150;
    animation: wireFlow 2.6s linear infinite;
}
.wf.w-md  { animation-delay: 0.5s; }
.wf.w-ml  { animation-delay: 1.0s; }
.wf.w-cfd { animation-delay: 1.4s; }
@keyframes wireFlow {
    from { stroke-dashoffset: 162; }
    to   { stroke-dashoffset: 0; }
}
/* Per-science colour for wires + source dots */
.w-gen { stroke: var(--accent);   }
.w-md  { stroke: var(--accent-5); }
.w-ml  { stroke: var(--accent-3); }
.w-cfd { stroke: var(--accent-4); }
.src { animation: srcPulse 2.2s ease-in-out infinite; }
.src.w-gen { fill: var(--accent);   }
.src.w-md  { fill: var(--accent-5); animation-delay: 0.5s; }
.src.w-ml  { fill: var(--accent-3); animation-delay: 1.0s; }
.src.w-cfd { fill: var(--accent-4); animation-delay: 1.4s; }
@keyframes srcPulse {
    0%, 100% { opacity: 0.85; }
    50%      { opacity: 0.4; }
}

/* Landing dot where the wire meets the top of each box */
.sci__port {
    position: absolute;
    top: 0; left: 50%;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--accent);
    transform: translate(-50%, -50%);
    z-index: 2;
}
.sci[data-sci="md"]  .sci__port { background: var(--accent-5); }
.sci[data-sci="ml"]  .sci__port { background: var(--accent-3); }
.sci[data-sci="cfd"] .sci__port { background: var(--accent-4); }

.sci__art {
    position: relative;
    width: 100%;
    height: var(--art-h);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(40, 30, 20, 0.04),
                0 18px 40px -30px rgba(40, 30, 20, 0.35);
}

.sci figcaption {
    font-family: var(--mono);
    font-size: 0.6rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
    text-align: center;
    line-height: 1.3;
}

/* === Genomics: DNA tape === */
.dna-tape {
    width: 100%;
    white-space: nowrap;
    text-align: center;
    overflow: hidden;
    font-family: var(--mono);
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: 0.08em;
    -webkit-mask-image: linear-gradient(90deg, transparent, black 14%, black 86%, transparent);
            mask-image: linear-gradient(90deg, transparent, black 14%, black 86%, transparent);
}
.dna-tape .base { display: inline-block; animation: baseFlash 1.6s ease-in-out infinite; }
.dna-tape .base.a { color: var(--accent); }
.dna-tape .base.t { color: var(--accent-2); }
.dna-tape .base.g { color: var(--accent-4); }
.dna-tape .base.c { color: var(--accent-3); }
.dna-tape .base:nth-child(2n)  { animation-delay: 0.2s; }
.dna-tape .base:nth-child(3n)  { animation-delay: 0.4s; }
.dna-tape .base:nth-child(5n)  { animation-delay: 0.6s; }
.dna-tape .base:nth-child(7n)  { animation-delay: 0.8s; }

@keyframes baseFlash {
    0%, 100% { opacity: 0.35; transform: translateY(0); }
    50%      { opacity: 1;    transform: translateY(-2px); }
}

/* === Bioinformatics: 3D ball-and-stick molecule (pure CSS 3D) ===
   Tetrahedral geometry: a central atom bonded to four atoms. The whole
   assembly spins on a turntable (tilted) so atoms in front genuinely
   occlude the ones behind. Each atom sphere is billboarded (counter-spun)
   so its shaded face always points at the viewer. */
.mol3d {
    position: absolute;
    inset: 0;
    perspective: 360px;
}
.mol3d__spin {
    position: absolute;
    top: 50%; left: 50%;
    width: 0; height: 0;
    transform-style: preserve-3d;
    animation: molSpin 15s linear infinite;
}
@keyframes molSpin {
    from { transform: rotateX(-18deg) rotateY(0deg); }
    to   { transform: rotateX(-18deg) rotateY(360deg); }
}

/* atom position anchors (tetrahedral, ~20px bond length) */
.apos { position: absolute; top: 0; left: 0; transform-style: preserve-3d; }
.apos.a1 { transform: translate3d( 11.5px,  11.5px,  11.5px); }
.apos.a2 { transform: translate3d( 11.5px, -11.5px, -11.5px); }
.apos.a3 { transform: translate3d(-11.5px,  11.5px, -11.5px); }
.apos.a4 { transform: translate3d(-11.5px, -11.5px,  11.5px); }
.apos.ac { transform: translate3d(0, 0, 0); }

/* atom spheres — billboarded to always face the viewer */
.atom {
    position: absolute;
    top: 0; left: 0;
    border-radius: 50%;
    box-shadow: 0 2px 5px rgba(40, 30, 20, 0.28);
    animation: molSpinInv 15s linear infinite;
}
@keyframes molSpinInv {
    from { transform: rotateY(0deg)    rotateX(18deg); }
    to   { transform: rotateY(-360deg) rotateX(18deg); }
}
.atom-c { width: 22px; height: 22px; margin: -11px; background: radial-gradient(circle at 32% 27%, #8b887d, #46443d 72%); }
.atom-o { width: 16px; height: 16px; margin: -8px;  background: radial-gradient(circle at 32% 27%, #ecaa8e, #b5613f 72%); }
.atom-n { width: 16px; height: 16px; margin: -8px;  background: radial-gradient(circle at 32% 27%, #7b8893, #34404a 72%); }
.atom-h { width: 12px; height: 12px; margin: -6px;  background: radial-gradient(circle at 32% 27%, #ffffff, #c9c4b6 72%); }

/* bonds — thin bars from the central atom to each outer atom */
.bond {
    position: absolute;
    top: 0; left: 0;
    width: 20px; height: 3px;
    margin-top: -1.5px;
    border-radius: 2px;
    transform-origin: left center;
    background: linear-gradient(to bottom, #d6d1c4, #afaa9b);
}
.bond.b1 { transform: rotate3d(0, -1,  1, 54.7356deg);  }
.bond.b2 { transform: rotate3d(0,  1, -1, 54.7356deg);  }
.bond.b3 { transform: rotate3d(0,  1,  1, 125.264deg);  }
.bond.b4 { transform: rotate3d(0, -1, -1, 125.264deg);  }

/* === Machine Learning & AI: neural net === */
.net { width: 104px; height: 62px; }
.net .edges line {
    stroke: rgba(26, 26, 24, 0.18);
    stroke-width: 1;
    stroke-dasharray: 3 4;
    animation: edgePulse 2s linear infinite;
}
.net .edges line:nth-child(2n) { animation-delay: 0.3s; }
.net .edges line:nth-child(3n) { animation-delay: 0.6s; }
.net .edges line:nth-child(5n) { animation-delay: 0.9s; }

@keyframes edgePulse {
    0%   { stroke-dashoffset: 0;   opacity: 0.35; }
    50%  { opacity: 1; }
    100% { stroke-dashoffset: -14; opacity: 0.35; }
}

.net .nodes circle {
    fill: var(--accent-3);
    transform-box: fill-box;
    transform-origin: center;
    animation: nodeBlink 2.4s ease-in-out infinite;
}
.net .nodes circle:nth-child(odd) { animation-delay: 0.4s; }
.net .nodes circle:nth-child(3n)  { animation-delay: 0.8s; }

@keyframes nodeBlink {
    0%, 100% { transform: scale(1);   opacity: 0.55; }
    50%      { transform: scale(1.3); opacity: 1; }
}

/* === CFD & CAE: flame === */
.art-cfd { padding: 0; }
.flame-wrap {
    position: absolute;
    inset: 0;
    border-radius: 11px;
    overflow: hidden;
    background:
        radial-gradient(ellipse at 50% 118%, rgba(204, 120, 92, 0.22), transparent 62%),
        var(--paper);
}
.flame {
    position: absolute;
    bottom: -10%;
    left: 50%;
    width: 38%; height: 92%;
    border-radius: 50% 50% 30% 30% / 60% 60% 40% 40%;
    transform: translateX(-50%);
    filter: blur(6px);
    mix-blend-mode: multiply;
    animation: flicker 1.6s ease-in-out infinite;
}
.flame.f1 { background: radial-gradient(ellipse at 50% 100%, #E0A36F 0%, #CC785C 45%, transparent 70%); }
.flame.f2 { background: radial-gradient(ellipse at 50% 100%, #CC785C 0%, #B5613F 45%, transparent 70%); width: 26%; height: 72%; animation-delay: 0.3s; }
.flame.f3 { background: radial-gradient(ellipse at 50% 100%, #7C7A52 0%, transparent 60%); width: 18%; height: 52%; animation-delay: 0.6s; }

@keyframes flicker {
    0%, 100% { transform: translateX(-50%) scaleY(1)    scaleX(1);    opacity: 0.85; }
    25%      { transform: translateX(-52%) scaleY(1.1)  scaleX(0.95); opacity: 1; }
    50%      { transform: translateX(-48%) scaleY(0.95) scaleX(1.05); opacity: 0.9; }
    75%      { transform: translateX(-51%) scaleY(1.05) scaleX(0.98); opacity: 1; }
}

/* ============================================================== Responsive */
/* The diagram is a fixed 330px design so the wires meet the box tops exactly.
   On very narrow embeds, scale the whole thing down uniformly to keep that
   alignment intact rather than reflowing individual pieces. */
@media (max-width: 360px) {
    .stack { transform: scale(0.84); transform-origin: top center; }
}
