@import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;500;700;800&family=DM+Sans:wght@400;500&display=swap');
/* Developed by Muhammad Shaaban for a Summer REU in 2026 for Makin */
body {
    background-color: rgb(26, 26, 31);
    /* Two faint corner glows (warm top-left, cool top-right) over the flat base
       give the page depth without touching any layout. Fixed so they don't
       scroll with content. */
    background-image:
        radial-gradient(1200px 620px at 10% -10%, rgba(255, 198, 42, 0.06), transparent 60%),
        radial-gradient(1000px 720px at 100% 0%, rgba(96, 116, 190, 0.07), transparent 55%);
    background-attachment: fixed;
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

:root {
    --border:      rgba(255, 255, 255, 0.1);
    --text-1:      #ffffff;
    --panel:       rgb(36, 39, 46);
    --gold:        rgb(255, 198, 42);
    --gold-soft:   rgba(255, 198, 42, 0.16);
    --ease:        cubic-bezier(0.4, 0, 0.2, 1);
    --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
    --shadow-1:    0 4px 18px rgba(0, 0, 0, 0.28);
    --shadow-2:    0 14px 44px rgba(0, 0, 0, 0.46);
    --shadow-gold: 0 6px 26px rgba(255, 198, 42, 0.30);
}

/* Slim scrollbars */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); }

/* ── Motion primitives ──────────────────────────────────────────────────────
   panelIn (fade + rise) is the reveal for the content panels themselves. It is
   only ever applied to the position:absolute panels — never to an ancestor of
   them, because a `transform` on an ancestor becomes the containing block for
   those absolutely-positioned panels and collapses their 90%/42% widths onto a
   single nav column. The nav tabs, which ARE such ancestors, use fadeIn. */
@keyframes panelIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* Opacity-only entrance for the nav — safe on containing-block ancestors. */
@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Respect users who ask for less motion: kill entrances and transform-based
   hovers, keep colour/opacity feedback. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

.buttons {
    height: 80vh;
    display: flex;
    position: relative;
    align-items: flex-start;
}

label .infoTag,
label > div:not(.buttonText) {
    display: none;
}

.inputRad{
    display: none;
}


label {
    display: flex;
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    /* No transform here: labels are the containing block for the absolute
       content panels, so a transform would collapse the panel layout. Elevate
       with colour + shadow instead. */
    transition: background 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

label:hover {
    background-color: rgba(255, 255, 255, 0.05);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

.topPanel {
    justify-content: center;
    margin: 2px;
    flex: 1;
    border-radius: 10px;
    transition: background 0.2s;
    background-color: rgb(36, 39, 46);
    border-right: 1px solid rgba(255,255,255,0.06);
    /* Staggered entrance so the nav assembles itself on load. Opacity-only:
       .topPanel is an ancestor of the absolute content panels, so a transform
       here would reparent their containing block (see @keyframes note). */
    animation: fadeIn 0.5s var(--ease-out) both;
}
.topPanel:nth-child(1) { animation-delay: 0.02s; }
.topPanel:nth-child(2) { animation-delay: 0.07s; }
.topPanel:nth-child(3) { animation-delay: 0.12s; }
.topPanel:nth-child(4) { animation-delay: 0.17s; }
.topPanel:nth-child(5) { animation-delay: 0.22s; }

.buttonText{
    font-family: 'Syne';
    align-items: center;
    text-align: center;
    margin: 10px;
    padding: 5px;
    border-radius: 10px;
    height: 52px;
    justify-content: center;
    box-sizing: border-box;
    cursor: pointer;

    background: none;
    color: white;
    font-weight: 600;
    font-size: 1.0rem;
    letter-spacing: -0.02em;
    transition: 0.25s;
}

abbr {
    cursor: help;
}

input:checked + label {
    z-index: 9999;
    background: linear-gradient(160deg, rgb(255, 212, 70), rgb(242, 180, 10));
    border-left: 3px solid rgb(255, 198, 42);
    /* Elevation via shadow only — see the label rule for why not transform. */
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.25), var(--shadow-gold);
}

input:checked + label .infoTag,
input:checked + label > div:not(.buttonText):not(.nncont){
    display: block;
    position: absolute;
    top: 52px;
    left: 5%;
    width: 90%;
    margin-top: 5rem;
    margin: 0auto;
    box-sizing: border-box;
    /* Reveal each panel as its tab becomes active. */
    animation: panelIn 0.42s var(--ease-out) both;
}

input:checked + label .nncont{
    display: flex;
    position: absolute;
    top: 52px;
    left: 5%;
    width: 90%;
    margin-top: 5rem;
    margin: 0auto;
    box-sizing: border-box;
    animation: panelIn 0.42s var(--ease-out) both;
}


input:checked + label .buttonText{
    z-index: 9999;
    background: none;
    color:black;
    font-size: 1.1rem;
    font-weight: 700;
}




.infoTag {
    text-align: center;
    background-color: rgb(63, 69, 80);
    font-size: 1rem;
    position: relative;
    width: 80%;
    height: fit-content;
    color: white;
    padding: 1rem;
    border-radius: 16px;
    flex-direction: column;
    justify-content: space-around;
    flex-wrap: wrap;
    border: 1px solid var(--border);
    box-shadow: var(--shadow-1);
}

.archContainer {
    text-align: center;
    background-color: rgb(63, 69, 80);
    font-size: 1rem;
    height: 100%;
    color: white;
    padding: 1rem;
    border-radius: 16px;
    border: 1px solid var(--border);
    box-shadow: var(--shadow-1);
}

input:checked + label > div.archContainer:not(.buttonText):not(.nncont) {
    top: 15.5rem;      /* clears the multi-line infoTag; verified not to overlap */
    left: 5%;
    width: 66%;        /* wide window for the horizontal pipeline */
    /* Height is viewport-relative rather than bottom:1.5rem, so the box extends
       past the .buttons 80vh region into the empty space below it and shows more
       of the diagram. No ancestor clips overflow, so this is safe. */
    height: calc(100vh - 17rem);
    bottom: auto;
    margin-top: 0;     /* beat the shared rule's margin-top:5rem */
    overflow: auto;    /* scroll if the diagram is still larger than the window */
    text-align: left;
}

/* ── Architecture diagram grid ──────────────────────────────────────────────
   Four columns mirror the figure: input | encoder | attention | decoder.
   Rows are shared across the stacks so Encoder 3 (row 2) lines up with the
   Decoder 1 / attention row. Row-gap leaves room for the flow arrows. */
.archGrid {
    display: grid;
    grid-template-columns:
        minmax(130px, 1fr) minmax(140px, 1.1fr) auto minmax(150px, 1.2fr);
    gap: 1.4rem 1rem;
    align-items: center;
    justify-items: stretch;
    padding-top: 0.4rem;
    min-width: min-content;   /* let it exceed the window and scroll rather than crush */
    position: relative;       /* positioning context for the .archLines overlay */
}

/* SVG connector overlay — sits behind the boxes, paths drawn by archTabs.js. */
.archLines {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
    z-index: 0;
}
.archLine {
    fill: none;
    stroke: var(--gold);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0.5;
}

/* Attention (and any) inter-column connector — a label on the arrow, not a box. */
.archConnector {
    align-self: center;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--gold);
    white-space: nowrap;
    padding: 0 0.25rem;
}

/* ── Architecture skeleton placeholders ─────────────────────────────────────
   Rough stand-ins, not the real diagram. These become .archNode cards (see
   architect_demo.html) once the container moves out of the <label>. */
.archSkelTitle {
    font-family: 'Syne';
    font-weight: 700;
    font-size: 1.05rem;
    margin-bottom: 0.9rem;
}

.archSkelBox {
    position: relative;   /* anchor for the .archUp / .archDown flow arrows */
    background-color: rgb(36, 39, 46);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 0.65rem 0.9rem;
    cursor: pointer;
    transition: border-color 0.2s var(--ease), background 0.2s var(--ease),
                transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

/* Flow arrows drawn in the row-gap above a box. No transform (the preview pane
   doesn't render transforms), so centre with left:0/right:0 + text-align. */
.archUp::before,
.archDown::before {
    position: absolute;
    top: -1.35rem;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 0.95rem;
    line-height: 1;
    color: rgba(255, 255, 255, 0.32);
    pointer-events: none;
}
.archUp::before   { content: '\2191'; }   /* ↑ */
.archDown::before { content: '\2193'; }   /* ↓ */

.archSkelBox:hover {
    border-color: rgba(255, 198, 42, 0.5);
    transform: translateY(-2px);
    box-shadow: var(--shadow-1);
}

.archSkelBox:active {
    transform: translateY(0);
}

/* Selected node — mirrors the accent the main tabs use when active. */
.archSkelBox.is-active {
    border-color: rgb(255, 198, 42);
    background-color: rgb(46, 44, 38);
    box-shadow: var(--shadow-gold);
}

.archSkelStage {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.38);
}

.archSkelLabel {
    font-family: 'Syne';
    font-weight: 600;
    font-size: 1rem;
}

.archSkelMeta {
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.6);
}

/* Placeholder for the encoder→decoder edge; becomes an SVG connector later. */
.archSkelLink {
    text-align: center;
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.38);
    padding: 0.5rem 0;
}

/* ── Node detail tabs ───────────────────────────────────────────────────────
   One panel per .archSkelBox, filling the gap to the right of .archContainer.
   Geometry deliberately mirrors the .archContainer override above (same top,
   same height) so the two panels line up; left/width place it in the gap:
   .archContainer spans 5%→47%, .infoTag ends at 95%, so 50%→95% is the hole.
   Toggled by dynamic/archTabs.js via .is-open. */
.archTab {
    background-color: rgb(63, 69, 80);
    color: white;
    font-size: 1rem;
    padding: 1rem 1.25rem;
    border-radius: 16px;
    border: 1px solid var(--border);
    box-shadow: var(--shadow-2);
}

input:checked + label > div.archTab:not(.buttonText):not(.nncont) {
    display: none;         /* beat the shared rule's display:block until opened */
    top: 15.5rem;          /* aligned with the diagram window */
    left: 73%;            /* docked in the strip right of the 5%–71% diagram */
    width: 22%;
    height: calc(100vh - 17rem);   /* match the taller diagram window */
    bottom: auto;
    margin-top: 0;
    overflow-y: auto;
    text-align: left;
}

/* Higher specificity than the rule above, so .is-open wins the display fight. */
input:checked + label > div.archTab.is-open:not(.buttonText):not(.nncont) {
    display: block;
}

.archTabClose {
    float: right;
    cursor: pointer;
    font-size: 1.4rem;
    line-height: 1;
    color: rgba(255, 255, 255, 0.38);
    padding: 0 0.25rem;
    transition: color 0.2s;
}

.archTabClose:hover {
    color: white;
}

.archTabTag {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgb(255, 198, 42);
}

.archTabTitle {
    font-family: 'Syne';
    font-weight: 700;
    font-size: 1.25rem;
    margin: 0.2rem 0 0.8rem;
}

/* Per-stage activation figure (light-themed PNG) shown in the detail panel. */
.archTabFig {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: #fff;
    margin: 0 0 0.9rem;
}
.archTabFig[hidden] { display: none; }

.archTabBody {
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.6);
    margin: 0 0 0.9rem;
}

/* ── Home tab layout ────────────────────────────────────────────────────────
   The whole Home tab is a single normal-flow column (.homeContent) so the
   page scrolls naturally. Only this wrapper is the absolutely-positioned tab
   panel; everything inside it (title card, intro, the two info cards, and the
   architecture diagram) stacks in document flow. This replaces the old scheme
   of several hard-positioned panels that overlapped once the intro grew. */
input:checked + label > div.homeContent:not(.buttonText):not(.nncont) {
    top: 76px;             /* small breathing room below the nav tabs */
    left: 5%;
    width: 90%;
    height: auto;          /* content-driven height → the body scrolls */
    margin: 0;
    bottom: auto;
    padding: 0 0 4rem;
    text-align: left;
    overflow: visible;
}

/* Intro paragraph: keep the .infoTag surface but drop the absolute positioning
   it inherits from the shared active-tab rule so it flows inside .homeContent. */
input:checked + label .homeContent .infoTag {
    position: static;
    width: auto;
    margin: 0 0 1.6rem;
    padding: 1.5rem 1.9rem;
    text-align: left;
    font-size: 1.1rem;
    line-height: 1.8;
    animation: none;
}

/* Title header — a plain header block set off by a hairline rule rather than a
   filled gradient card, so it reads as the page's title, not a widget. */
.homeTitleCard {
    padding: 0.5rem 0 1.4rem;
    margin-bottom: 1.6rem;
    border-bottom: 1px solid var(--border);
}
.homeTitleKicker {
    font-family: 'DM Sans', sans-serif;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    font-size: 0.8rem;
    color: rgba(255, 198, 42, 0.85);
    margin-bottom: 1rem;
}
.homeTitle {
    font-family: 'Syne';
    font-weight: 700;
    font-size: 3.4rem;
    line-height: 1.14;
    letter-spacing: 0.01em;   /* positive → open, not squashed */
    color: var(--text-1);
    margin: 0;
}
.homeTitleSub {
    font-family: 'DM Sans', sans-serif;
    font-size: 1.25rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.62);
    margin-top: 1rem;
}

/* Two side-by-side info cards (placeholder copy for now). Same surface, radius
   and shadow as the intro paragraph so the page feels like one system. */
.homeCards {
    display: flex;
    gap: 1.5rem;
    align-items: stretch;
    margin-top: 1.6rem;      /* match the gaps above; don't butt against the diagram */
    margin-bottom: 2.25rem;
}
.homeCard {
    flex: 1 1 0;
    min-width: 0;
    background-color: rgb(63, 69, 80);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 1.9rem 2rem;
    box-shadow: var(--shadow-1);
}
.homeCardTag {
    font-family: 'DM Sans', sans-serif;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-size: 0.78rem;
    color: rgba(255, 198, 42, 0.8);
    margin-bottom: 0.7rem;
}
.homeCardTitle {
    font-family: 'Syne';
    font-weight: 600;
    font-size: 1.7rem;
    line-height: 1.2;
    letter-spacing: 0.01em;
    margin: 0 0 1.1rem;
    color: var(--text-1);
}
.homeCardBody {
    font-size: 1.05rem;
    line-height: 1.8;
    color: rgba(255, 255, 255, 0.68);
    margin: 0 0 1rem;
}
.homeCardBody:last-child { margin-bottom: 0; }

/* Easter egg: clicking the "(BMI)" acronym pops the hidden BMI calculator
   (Body Mass Index — same initials as Brain Machine Interfaces). Kept subtle
   so it reads as a normal part of the title until hovered. */
.bmiEgg {
    cursor: pointer;
    transition: color 0.2s var(--ease);
}
.bmiEgg:hover { color: var(--gold); }

@media (max-width: 720px) {
    .homeCards { flex-direction: column; }
}

/* Diagram + node-detail panel row. The diagram (.archContainer) flows normally
   and sets the row height; the detail panel is absolutely positioned and
   stretched to that same height (top:0/bottom:0). Because the panel is out of
   flow, its per-node content — long text, a figure, or none — can never change
   the row height, so BOTH boxes stay a constant size as autoplay cycles through
   the layers. Overflow inside the panel scrolls instead of resizing it. */
.archSection {
    position: relative;
    padding-right: calc(300px + 1.25rem);   /* reserve the detail-panel column */
}
.homeContent .archContainer {
    height: auto;          /* natural height → the fixed reference for the row */
    text-align: left;
    overflow-x: auto;      /* wide pipeline scrolls sideways if the row is tight */
}
.homeContent .archTab {
    display: none;         /* shown by .is-open below */
    position: absolute;
    top: 0;
    bottom: 0;             /* height locked to the diagram, regardless of content */
    right: 0;
    width: 300px;
    box-sizing: border-box;
    overflow-y: auto;
}
.homeContent .archTab.is-open {
    display: block;
}

/* On narrow screens the reserved column would crush the diagram; stack instead
   and let the panel size to its content there. */
@media (max-width: 760px) {
    .archSection { padding-right: 0; }
    .homeContent .archTab {
        position: static;
        width: auto;
        margin-top: 1.25rem;
    }
}

/* ── Tooltip tag ────────────────────────────────────────────────────────────
   Drop into any text:  <span class="tip" data-tip="explanation">word</span>  */
.tip { position: relative; cursor: help; border-bottom: 1px dashed var(--gold); }
.tip::after {
    content: attr(data-tip);
    position: absolute; left: 50%; bottom: calc(100% + 9px);
    transform: translateX(-50%);
    width: max-content; max-width: 220px;
    padding: 0.5rem 0.7rem;
    background: var(--panel); color: var(--text-1);
    border: 1px solid var(--gold-soft); border-radius: 10px; box-shadow: var(--shadow-2);
    font: 500 0.8rem/1.45 'DM Sans', sans-serif; letter-spacing: normal; text-align: center;
    white-space: normal;   /* don't inherit nowrap from .archConnector etc. */
    opacity: 0; visibility: hidden; pointer-events: none; z-index: 10000;
    transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
}
.tip::before {   /* little arrow under the bubble */
    content: ''; position: absolute; left: 50%; bottom: calc(100% + 4px);
    transform: translateX(-50%);
    border: 5px solid transparent; border-top-color: var(--panel);
    opacity: 0; pointer-events: none; z-index: 10000; transition: opacity 0.18s var(--ease);
}
.tip:hover::after  { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(-2px); }
.tip:hover::before { opacity: 1; }

/* Downward variant: bubble drops below the word instead of above. Used by the
   electrode key, which sits near the top where an upward bubble is clipped by
   the nav tab boxes. */
.tip-below::after {
    top: calc(100% + 9px);
    bottom: auto;
}
.tip-below::before {
    top: calc(100% + 4px);
    bottom: auto;
    border-top-color: transparent;
    border-bottom-color: var(--panel);
}
.tip-below:hover::after { transform: translateX(-50%) translateY(2px); }


/* ── Component Analysis Panel ──────────────────────────────────────────── */
/* Row layout: dropdowns stacked on the left, square plot filling the height
   on the right. */
.componentAnalysis {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;   /* center the square in the full panel */
    width: 100%;
    position: relative;
}

/* The active-tab rule forces panel roots to display:block and pushes them down
   with margin-top; override (higher specificity) to restore the flex row and
   sit the panel just under the tabs so the square fills the area without
   needing to scroll. */
input:checked + label > div.componentAnalysis:not(.buttonText):not(.nncont) {
    display: flex;
    top: 64px;
    margin-top: 24px;
    height: calc(100vh - 112px);
}

/* Left column: the controls stack. Compact gaps so the whole stack (6 selects,
   two toggles, a slider and the buttons) fits without scrolling to reach Compute. */
.caControls {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0.5rem;
    padding-top: 0.25rem;
    width: 220px;
    position: absolute;      /* float as a left sidebar so it doesn't shift the centered square */
    left: 0;
    top: 0;
}

/* One label-over-dropdown stack. */
.caField {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.1rem;
    text-align: left;
}

/* Compact viewport-dynamic labels. clamp() scales with the window within bounds. */
.caLabel {
    font-family: 'Syne', sans-serif;
    font-size: clamp(0.82rem, 1vw, 1.12rem);
    line-height: 1.15;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text-1);
    white-space: nowrap;
}

/* Dropdowns themselves, matching the dark theme used elsewhere. */
.caSelect {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    color: #fff;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.8rem, 0.9vw, 1rem);
    font-weight: 500;
    padding: 0.32rem 0.7rem;
    width: 100%;
    min-width: 0;
    outline: none;
    cursor: pointer;
    transition: background 0.13s ease, border-color 0.13s ease, box-shadow 0.13s ease;
}
.caSelect:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.4);
}
.caSelect:focus {
    border-color: rgba(255, 198, 42, 0.7);
    box-shadow: 0 0 0 2px rgba(255, 198, 42, 0.2);
}
.caSelect option { background: rgb(36, 39, 46); color: #fff; }

/* Experimental toggles (circular stats / variance spheres). */
.caToggle {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    cursor: pointer;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.8rem, 0.9vw, 1rem);
    font-weight: 500;
    color: var(--text-1);
    padding: 0.12rem 0.25rem;
    margin: 0 -0.25rem;          /* keep text aligned while giving hover room */
    border-radius: 6px;
    transition: background 0.13s ease, color 0.13s ease;
}
.caToggle:hover { background: rgba(255, 255, 255, 0.06); color: #fff; }
.caToggleInput {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    accent-color: #ffc62a;
    cursor: pointer;
    transition: transform 0.1s ease;
}
.caToggleInput:hover { transform: scale(1.12); }
.caToggleText { user-select: none; }

/* Variance-sphere size slider. */
.caSlider {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.caSliderLabel {
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.75rem, 0.85vw, 0.92rem);
    color: rgba(255, 255, 255, 0.7);
}
.caSliderInput {
    width: 100%;
    accent-color: #ffc62a;
    cursor: pointer;
}

/* Compute / Clear button row at the bottom of the controls. */
.caButtons {
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
    margin-top: 0.15rem;
}
.caButton {
    flex: 1 1 0;
    padding: 0.42rem 0.6rem;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.05);
    color: #fff;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.85rem, 1vw, 1.05rem);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.13s ease, border-color 0.13s ease,
                transform 0.09s ease, box-shadow 0.13s ease;
}
.caButton:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.5);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
}
.caButton:active {
    transform: translateY(1px) scale(0.985);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.caButtonPrimary {
    background: #ffc62a;
    border-color: #ffc62a;
    color: #1a1a1f;
}
.caButtonPrimary:hover {
    background: #ffd45a;
    border-color: #ffd45a;
    box-shadow: 0 4px 16px rgba(255, 198, 42, 0.45);
}

/* Plot region — future scrollable / zoomable / 3D-rotatable display.
   overflow:hidden + position:relative ready it to host a canvas/renderer. */
.caPlot {
    /* Largest square that fits the panel height while leaving room for the
       floating 240px controls on both notional sides (≈500px), so the square
       stays centered without overlapping the sidebar or forcing a scroll. */
    height: min(calc(100vh - 112px), calc(90vw - 460px));
    aspect-ratio: 1 / 1;     /* square: width = that height */
    flex: 0 0 auto;
    position: relative;
    overflow: hidden;
    background: #0e0e12;
    background-color: white;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Dark-mode modifier: flips the white plot background (and dark axis labels)
   to the dark theme used elsewhere. Toggled by #caThemeToggle. */
.caPlot.caPlotDark {
    background-color: #0e0e12;
}
.caPlot.caPlotDark .caAxisLabel {
    color: #ffffff;
}
.caPlot.caPlotDark .caPlotPlaceholder {
    color: rgba(255, 255, 255, 0.3);
}

/* Small pill button, top-right of the plot, to flip the background. */
.caThemeToggle {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 3;
    padding: 0.3rem 0.65rem;
    border-radius: 999px;
    border: 1px solid rgba(0, 0, 0, 0.18);
    background: rgba(255, 255, 255, 0.85);
    color: #1a1a1f;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.72rem, 0.85vw, 0.9rem);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.13s ease, border-color 0.13s ease, color 0.13s ease;
}
.caThemeToggle:hover {
    background: #ffffff;
    border-color: rgba(0, 0, 0, 0.35);
}
.caPlot.caPlotDark .caThemeToggle {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.25);
    color: #fff;
}
.caPlot.caPlotDark .caThemeToggle:hover {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(255, 255, 255, 0.5);
}

.caPlotPlaceholder {
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.8rem, 1vw, 1.05rem);
    color: rgba(255, 255, 255, 0.3);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    pointer-events: none;
}

/* Matplotlib-style axis labels fixed to the plot frame (dark text on the white
   plot). pointer-events:none so they never block the orbit/zoom controls. */
.caAxisLabel {
    position: absolute;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.75rem, 1vw, 1rem);
    color: #1a1a1f;
    letter-spacing: 0.02em;
    white-space: nowrap;
    pointer-events: none;
    z-index: 2;
}
.caAxisX {
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
}
.caAxisY {
    left: 6px;
    top: 50%;
    transform: translateY(-50%) rotate(180deg);
    writing-mode: vertical-rl;   /* vertical text reading bottom-to-top */
}

/* Right-hand key: mirrors the floating .caControls sidebar on the left.
   Sits off to the side of the centered plot and color-codes the points. */
.caLegend {
    width: 220px;
    position: absolute;
    right: 0;
    top: 0;
    max-height: calc(100vh - 112px);
    overflow-y: auto;
    padding-top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    text-align: left;
}
.caLegend[hidden] { display: none; }

.caLegendTitle {
    font-family: 'Syne', sans-serif;
    font-size: clamp(1.05rem, 1.5vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text-1);
    margin-bottom: 0.2rem;
}

/* Global-variance header line above the phoneme / word rows. */
.caLegendHeader {
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.82rem, 1vw, 1.05rem);
    font-weight: 600;
    color: var(--text-1);
    font-variant-numeric: tabular-nums;
    padding-bottom: 0.35rem;
    margin-bottom: 0.15rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

/* One swatch + name row (phonemes / words). */
.caLegendRow {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.85rem, 1vw, 1.1rem);
    font-weight: 500;
    color: var(--text-1);
}
.caLegendSwatch {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, 0.25);
}
/* Per-phoneme variance, pushed to the right edge of the row. */
.caLegendVar {
    margin-left: auto;
    padding-left: 0.5rem;
    font-size: clamp(0.72rem, 0.85vw, 0.92rem);
    color: rgba(255, 255, 255, 0.6);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Continuous gradient bar (time). */
.caLegendGradient {
    width: 100%;
    height: 16px;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, 0.2);
}
.caLegendScale {
    display: flex;
    justify-content: space-between;
    font-family: 'DM Sans', sans-serif;
    font-size: clamp(0.75rem, 0.9vw, 0.95rem);
    color: rgba(255, 255, 255, 0.75);
}

/* ── 3D Display Panel ──────────────────────────────────────────────────── */
.display3D {
    display: flex;
    flex-direction: column;
    width: 100%;
    position: relative;
}

/* Raise the panel and size it to the viewport so the Load Saliencies button
   sits above the fold (no scroll to reach it). fadeIn (opacity only) instead of
   the shared panelIn keeps this panel transform-free, so the full-bleed
   position:fixed brain canvas below resolves against the viewport. */
input:checked + label > div.display3D:not(.buttonText):not(.nncont) {
    top: 64px;
    margin-top: 24px;
    height: calc(100vh - 108px);
    animation: fadeIn 0.42s var(--ease-out) both;
}

/* Positioning box for the floating controls (pickers, electrode toggle). The
   brain canvas no longer lives inside it — it's a full-viewport background —
   but the controls still anchor to this inset box so they keep their spot. */
.display3DTop {
    height: calc(100% - 94px);
    position: relative;
}

/* Full-bleed brain: a fixed background layer spanning the whole viewport below
   the nav tabs. z-index 0 keeps it under the floating controls (z-index 10).
   Only visible on this tab, since its ancestor panel is display:none elsewhere. */
#container3D {
    position: fixed;
    top: 88px;              /* clear the nav tab row */
    left: 0;
    width: 100vw;
    height: calc(100vh - 88px);
    z-index: 0;
}

#container3D canvas {
    width: 100% !important;
    height: 100% !important;
    border-radius: 0;
}

/* Keep the Load Saliencies bar above the full-bleed brain. */
.display3D .modelParamsRow {
    position: relative;
    z-index: 20;
}

/* Left-side explainer panel, floating over the full-bleed brain, below the
   picker bar. Same glass treatment as the floating controls. */
.regionInfo {
    position: absolute;
    top: 68px;
    left: 16px;
    z-index: 10;
    width: min(240px, 32vw);
    background: rgba(22, 22, 27, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 12px;
    padding: 16px 18px;
}
.regionInfoTitle {
    font-family: 'Syne', sans-serif;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    color: #fff;
    margin-bottom: 0.6rem;
}
.regionInfoBody {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.9rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.72);
    margin: 0 0 0.7rem;
}
.regionInfoBody:last-child { margin-bottom: 0; }
.regionInfoBody b { color: rgba(255, 255, 255, 0.9); font-weight: 600; }

/* On narrow screens keep it readable but out of the way. */
@media (max-width: 700px) {
    .regionInfo { width: min(300px, calc(100vw - 90px)); }
}

/* Colour key for the electrode dots, tucked under the Electrodes toggle. */
.elecKey {
    position: absolute;
    top: 52px;
    right: 16px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    gap: 5px;
    background: rgba(22, 22, 27, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    padding: 8px 11px;
}
.elecKeyRow {
    display: flex;
    align-items: center;
    gap: 7px;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.72rem;
    color: rgba(255, 255, 255, 0.75);
    white-space: nowrap;
}
.elecKeyDot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 5px currentColor;   /* soft glow, matching the 3D dot */
}
.elecKeyDot.actual  { background: #00ffcc; color: #00ffcc; }  /* elecMat 0x00ffcc */
.elecKeyDot.bipolar { background: #ff0011; color: #ff0011; }  /* bpMat   0xff0011 */

.toggleElecBtn {
    position: absolute;
    top: 14px;
    right: 16px;
    z-index: 10;
    background: rgba(22, 22, 27, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    color: rgba(255, 255, 255, 0.75);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 6px 12px;
    cursor: pointer;
    transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.toggleElecBtn:hover {
    background: rgba(40, 40, 48, 0.75);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.22);
}
.toggleElecBtn.hidden {
    color: rgba(255, 255, 255, 0.3);
    border-color: rgba(255, 255, 255, 0.06);
}

/* ── Saliency method picker (overlay, top-left of the 3D canvas) ──────────── */
/* Holds the Saliency + Color Scheme pickers side by side in the top-left. */
.pickerBar {
    position: absolute;
    top: 14px;
    left: 16px;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 10px;
}
/* Inside the bar, pickers flow with flex instead of each absolutely stacking. */
.pickerBar .saliencyPicker {
    position: static;
    top: auto;
    left: auto;
}

.saliencyPicker {
    position: absolute;
    top: 14px;
    left: 16px;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 8px;
    background: rgba(22, 22, 27, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    padding: 5px 10px;
}
.saliencyLabel {
    color: rgba(255, 255, 255, 0.55);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.saliencySelect {
    background: rgba(40, 40, 48, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 6px;
    color: rgba(255, 255, 255, 0.9);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    padding: 4px 8px;
    cursor: pointer;
    outline: none;
    transition: border-color 0.2s;
}
.saliencySelect:hover  { border-color: rgba(255, 255, 255, 0.28); }
.saliencySelect:focus  { border-color: rgba(255, 198, 42, 0.55); }

/* ── buildModel parameter row ───────────────────────────────────────────── */
.modelParamsRow {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 0 12px;
    height: 94px;
    flex-shrink: 0;
    background: rgba(22, 22, 27, 0.97);
    border-top: 1px solid rgba(255, 255, 255, 0.07);
    overflow-x: auto;
    gap: 0;
}

/* Single "Load Saliencies" button occupies the bar (retrain params removed).
   Transparent so the full-bleed brain shows through — only the button floats. */
.saliencyBar {
    justify-content: center;
    background: transparent;
    border-top: none;
}


/* Load Saliencies button */
.runBtn {
    padding: 0.6rem 1.4rem;
    background: rgb(255, 198, 42);
    color: black;
    border: none;
    border-radius: 8px;
    font-family: 'Syne', sans-serif;
    font-size: 0.9rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.2s var(--ease), transform 0.12s var(--ease),
                box-shadow 0.2s var(--ease);
    white-space: nowrap;
}
.runBtn:hover  { background: #ffd060; transform: translateY(-1px); box-shadow: var(--shadow-gold); }
.runBtn:active { transform: scale(0.98); box-shadow: none; }


/* ── Neural Network Training Demo (Train an NN tab, moved from SubDemo) ───── */
/* Scoped under .nnDemo so the demo's original global rules (body/button/input/
   canvas) don't leak into the rest of the page. */
.nnDemo {
    color: #eee;
    font-family: sans-serif;
}
.nnDemo .container {
    max-width: 500px;
    margin: 0 auto;             /* center the card (parent is display:block here) */
    padding: 2rem;
    background: #1e1e24;
    border-radius: 12px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
}
.nnDemo h1 {
    font-size: 1.6rem;
    margin: 0 0 1rem;
}
.nnDemo .controls {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.nnDemo .controls label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}
.nnDemo input,
.nnDemo select {
    padding: 0.3rem;
    background: #2a2a32;
    color: #eee;
    border: 1px solid #555;
    border-radius: 4px;
}
.nnDemo button {
    padding: 0.5rem 1rem;
    background: #4f349e;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
}
.nnDemo button:hover    { background: #6543c4; }
.nnDemo button:disabled { background: #555; cursor: not-allowed; }
.nnDemo #status {
    margin-bottom: 1rem;
    font-style: italic;
    min-height: 1.5em;
}
.nnDemo canvas {
    border: 1px solid #555;
    background: white;
    display: block;
}

/* ── Hidden BMI gag (overlay, shown via BMI.js) ──────────────────────────── */
#bmiJoke {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
#bmiJoke[hidden] { display: none; }

#BMICalc {
    position: relative;
    text-align: center;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 2rem 2.5rem;
    color: var(--text-1);
    box-shadow: var(--shadow-2);
}
#BMICalc h1 {
    font-family: 'Syne', sans-serif;
    font-size: 1.6rem;
    font-weight: 700;
    margin: 0 0 1.25rem;
}
#BMICalc label {
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.8rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
/* Cancel the global nav-tab label:hover highlight for the calculator's field
   labels — only the Calculate button should light up on hover. */
#BMICalc label:hover {
    background: none;
    box-shadow: none;
}
#BMICalc input[type="number"] {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text-1);
    font-family: 'Syne', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    padding: 0.5rem 0.6rem;
    width: 5rem;
    outline: none;
    margin: 0.4rem 0.25rem;
    -moz-appearance: textfield;
    transition: border-color 0.2s var(--ease);
}
#BMICalc input[type="number"]::-webkit-outer-spin-button,
#BMICalc input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; }
#BMICalc input[type="number"]:focus { border-color: rgba(255, 198, 42, 0.5); }
#BMICalc button {
    display: block;
    margin: 1.5rem auto 0;
    background: var(--gold);
    color: #1a1a1f;
    border: none;
    border-radius: 8px;
    padding: 0.6rem 1.4rem;
    font-family: 'Syne', sans-serif;
    font-size: 0.95rem;
    font-weight: 800;
    cursor: pointer;
    transition: background 0.2s var(--ease), transform 0.12s var(--ease);
}
#BMICalc button:hover  { background: #ffd060; transform: translateY(-1px); }
#BMICalc button:active { transform: scale(0.98); }
#bmicalcd {
    font-family: 'Syne', sans-serif;
    font-weight: 700;
    font-size: 1.2rem;
    margin: 1.25rem 0 0;
    min-height: 1.4em;
}

/* Close × in the corner of the calculator card (scoped to beat #BMICalc button). */
#BMICalc .bmiClose {
    position: absolute;
    top: 10px;
    right: 12px;
    margin: 0;
    padding: 0;
    background: none;
    color: rgba(255, 255, 255, 0.5);
    font-size: 1.4rem;
    font-weight: 400;
    transition: color 0.2s var(--ease);
}
#BMICalc .bmiClose:hover { background: none; color: #fff; transform: none; }
/* ── Export toolbar ──────────────────────────────────────────────────────────
   Vertical stack of little format buttons, pinned bottom-right. Mirrors the
   panel/gold design tokens. Hidden when printing so it never lands in the PDF. */
.exportBar {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 50;
    /* Hidden by default; export.js reveals it only on the Dimensionality
       Reduction tab (sets display back to flex). */
    display: none;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 10px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow-2);
}
.exportBarLabel {
    font-family: 'Syne', sans-serif;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-align: center;
    color: rgba(255, 255, 255, 0.4);
    margin-right: 4px;
}
.exportBtn {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    font-family: 'Syne', sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text-1);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease),
                border-color 0.2s var(--ease), transform 0.2s var(--ease),
                box-shadow 0.2s var(--ease);
}
.exportBtn:hover {
    color: rgb(26, 26, 31);
    background: var(--gold);
    border-color: var(--gold);
    transform: translateY(-1px);
    box-shadow: var(--shadow-gold);
}
.exportBtn:active { transform: translateY(0); }

@media print {
    .exportBar { display: none !important; }
}
