/* =============================================================================
   Real-spectra practice — styles for the three experimental-NMR pages
   (proton-nmr-assignment, carbon-nmr-assignment, nmr-integration).

   Loaded AFTER nmr-practice.css, which already provides the shared bits reused
   here: .nmr-subnav*, #prompt-text, #compound-name, #feedback-message,
   #explanation-area, #reveal-link, #global-stats, #skip-next-btn, #check-btn,
   .legend-*, .next-ready/.disabled. This file adds only the spectrum, zoom,
   signal-chip, and structure-overlay pieces ported from the prototype.
   ============================================================================= */

/* --- Compact one-row game layout (desktop >= 1100px):
       [ spectrum panel (with the zoom as an INSET overlaid on its upper region,
         journal-figure style) + chips underneath ]  |  [ structure, centered ].
       The integration page has no structure column, so the spectrum spans the
       full width. Narrow screens stack (see the media queries at the bottom).
       The zoom inset is PERMANENTLY reserved (empty-state hint shown when
       nothing is selected) so selecting a signal never shifts the layout. --- */
#game-area {
    margin: 0.75em auto;
    max-width: 1120px;
    /* .container is a centered flex column: without an explicit width,
       children shrink-to-fit and BREATHE as their content changes (the
       chip-zone width oscillation Dennis observed). Pin to the column. */
    width: 100%;
    box-sizing: border-box;
}

/* Below the full-width spectrum + chips: expansion (left half) and structure
   (right half) side by side; the grid stretch equalizes their heights. */
#detail-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 20px;
    align-items: stretch;
    margin-top: 10px;
}

/* Integration page: no structure column — the expansion spans full width. */
#detail-row:not(:has(#structure-col)) {
    grid-template-columns: minmax(0, 1fr);
}

.spec-panel {
    min-width: 0;               /* let the SVG shrink instead of overflowing */
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 10px 12px;
}

.spec-panel h2 {
    font-size: 0.8rem;
    margin: 0 0 4px;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 700;
}

/* Positioning context for the overlaid zoom inset. */
.spec-stage {
    position: relative;
    width: 100%;
}

#spec-svg {
    width: 100%;
    height: 160px;
    display: block;
}

/* --- Zoom expansion panel: left half of the detail row. Reserved permanently
       so selection never shifts; the SVG stretches so the panel's height
       matches the structure panel beside it. --- */
.zoom-inset {
    width: 100%;
    min-width: 0;
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 8px 12px 6px;
    display: flex;
    flex-direction: column;
}

.zoom-inset #zoom-svg,
.zoom-inset #zoom-empty {
    flex: 1;
    min-height: 150px;
}

.zoom-inset-title {
    font-size: 0.72rem;
    margin: 0 0 2px;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 700;
}

#zoom-svg {
    width: 100%;
    height: 150px;
    display: block;
}

/* Reserve the inset's body height even when empty (no layout shift on select). */
#zoom-empty {
    height: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #999;
    font-size: 0.82rem;
    text-align: center;
    padding: 0 1em;
    pointer-events: none;
}

/* --- Signal chips (one per marked signal) --- */
#sig-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
    margin: 0.75em auto;
    max-width: 720px;
}

/* Assign modes: chips live in two labeled zones and move between them. */
#sig-chips:has(.chip-zone) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 12px;
    max-width: 1120px;
    width: 100%;             /* fixed column width — zones never breathe */
    box-sizing: border-box;
    align-items: stretch;
}

.chip-zone {
    border: 1px dashed #c8cdd6;
    border-radius: 10px;
    padding: 6px 10px 10px;
    background: #fafbfc;
}

.chip-zone-done {
    border-style: solid;
    border-color: #bfdcc9;
    background: #f4faf6;
}

.chip-zone-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #888;
    margin-bottom: 6px;
}

.chip-zone-done .chip-zone-title {
    color: #2a7d52;
}

.chip-zone-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
    min-height: 40px;
    align-items: center;
}

.chip-zone-chips:empty::after {
    content: attr(data-empty);
    color: #aab;
    font-size: 0.8rem;
    font-style: italic;
}

@media (max-width: 679px) {
    #sig-chips:has(.chip-zone) {
        grid-template-columns: minmax(0, 1fr);
    }
}

.sig-chip {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    border: 2px solid #ccc;
    border-radius: 16px;
    padding: 4px 12px;
    background: #fff;
    transition: background 0.12s;
}

.sig-chip-label {
    border: none;
    background: none;
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
    padding: 0;
    color: inherit;
}

.sig-chip.active .sig-chip-label {
    color: #fff !important;
}

/* The checkmark's width is RESERVED on every chip (invisible until
   assigned): a chip that widens on assignment wraps earlier in the
   Assigned zone than it did in To-assign, growing the zone past its
   frozen height — the residual jump Dennis caught. Constant geometry;
   the check just appears. */
.sig-chip .sig-chip-label::after {
    content: " ✓";
    visibility: hidden;
}

.sig-chip.done .sig-chip-label::after {
    visibility: visible;
}

.sig-chip.sig-right {
    border-color: #2a9d8f;
    box-shadow: 0 0 0 1px #2a9d8f inset;
}

.sig-chip.sig-wrong {
    border-color: #d32f2f;
    box-shadow: 0 0 0 1px #d32f2f inset;
}

/* Friendly note when ?src=real is used on a match page (match problems are
   reconstructed-bank only, so the request is served from sim). */
.src-note {
    max-width: 700px;
    margin: 0.4em auto 0;
    font-size: 0.85rem;
    color: #777;
    text-align: center;
    font-style: italic;
}

/* --- Match mode: an integration ratio (the given) + three candidate structures.
       No spectrum is shown; the ratio IS the prompt. --- */
#match-area {
    margin: 0.75em auto 0;
    max-width: 1120px;
}

#match-ratio-wrap {
    text-align: center;
    margin: 0.5em auto 1em;
}

.match-ratio-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #888;
    margin-bottom: 6px;
}

#ratio-display {
    font-size: 2.6rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    color: #3b3486;
    line-height: 1.1;
}

/* --- HARD match (nmr-integration): the answer's spectrum + integrals is shown
       in #game-area above, and the three same-ratio candidates sit below. --- */
#candidate-section {
    margin: 0.75em auto 0;
    max-width: 1120px;
}

.candidate-section-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #888;
    text-align: center;
    margin-bottom: 8px;
}

#candidate-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    align-items: stretch;
}

.candidate-card {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    background: #fff;
    border: 2px solid #d5d9e0;
    border-radius: 12px;
    cursor: pointer;
    transition: border-color 0.12s, box-shadow 0.12s, background 0.12s;
    min-height: 200px;
}

@media (hover: hover) {
    .candidate-card:hover {
        border-color: #6153cc;
        box-shadow: 0 2px 10px rgba(97, 83, 204, 0.18);
    }
}

.candidate-struct {
    width: 100%;
}

.candidate-struct svg {
    display: block;
    width: 100%;
    height: auto;
}

.candidate-card.cand-correct {
    border-color: #2a9d8f;
    background: #f2fbf8;
    box-shadow: 0 0 0 2px #2a9d8f inset;
}

.candidate-card.cand-wrong {
    border-color: #d32f2f;
    background: #fdf4f3;
    box-shadow: 0 0 0 2px #d32f2f inset;
}

.candidate-card.cand-dim {
    opacity: 0.5;
}

@media (max-width: 679px) {
    #candidate-row { grid-template-columns: minmax(0, 1fr); }
    #ratio-display { font-size: 2rem; }
}

/* --- Structure panel: right half of the detail row (assign modes). --- */
#structure-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-width: 0;
}

#structure-wrap {
    position: relative;
    width: 340px;
    max-width: 100%;
    margin: auto;               /* centers in the space below the expansion */
}

/* Post-answer reveal toggle: correct answer vs the student's. */
.reveal-toggle {
    display: flex;
    gap: 0;
    border: 1px solid #ccc;
    border-radius: 16px;
    overflow: hidden;
}

.reveal-toggle button {
    border: none;
    background: #fff;
    padding: 5px 14px;
    font-size: 0.82rem;
    font-weight: 600;
    color: #666;
    cursor: pointer;
}

.reveal-toggle button.on {
    background: #6153cc;
    color: #fff;
}

/* Symmetry-aware selection toggle (default ON; OFF = per-atom hard mode). */
.symsel-control {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 0.85rem;
    color: #555;
    cursor: pointer;
    user-select: none;
    line-height: 1.3;
    max-width: 340px;
    text-align: left;
}

.symsel-control input {
    width: 16px;
    height: 16px;
    accent-color: #6153cc;
    cursor: pointer;
    flex: 0 0 auto;
}

#structure svg {
    display: block;
    width: 100%;
    height: auto;
}

#atom-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;   /* edge-atom reveal badges must not clip */
}

.atom-hit {
    fill: transparent;
    stroke: none;
    pointer-events: all;
    cursor: pointer;
}

/* hover-capable devices only: on touch, :hover sticks to the last-tapped atom
   and leaves a ghost shade after deselection (a past bug). */
@media (hover: hover) {
    .atom-hit:hover {
        fill: rgba(97, 83, 204, 0.15);
    }
}

.assign-ring {
    pointer-events: none;
}

/* Ripple/pulse on equivalent partner atoms auto-toggled by a symmetry click. */
.atom-ripple {
    pointer-events: none;
    stroke-width: 3;
    transform-box: fill-box;
    transform-origin: center;
    animation: atom-ripple 300ms ease-out forwards;
}

@keyframes atom-ripple {
    from { opacity: 0.85; transform: scale(0.6); }
    to   { opacity: 0;    transform: scale(1.7); }
}

@media (prefers-reduced-motion: reduce) {
    .atom-ripple { animation-duration: 1ms; }
}

/* --- DEPT toggle button --- */
#dept-toggle {
    background-color: #fff;
    color: #6153cc;
    border: 2px solid #6153cc;
    min-width: 110px;
}

#dept-toggle.active {
    background-color: #6153cc;
    color: #fff;
}

/* --- Attribution line (small, under the controls) --- */
.data-attribution {
    font-size: 0.78rem;
    color: #888;
    text-align: center;
    max-width: 640px;
    margin: 1em auto 0;
    line-height: 1.5;
}

.data-attribution a {
    color: #6153cc;
}

/* --- Responsive ---
   Wide      : full-width spectrum, chips, then expansion | structure halves.
   < 900     : the detail row stacks (expansion above structure). --- */
@media (max-width: 899px) {
    #detail-row {
        grid-template-columns: minmax(0, 1fr);
    }
    #structure-wrap { margin-top: 4px; }
}

@media (max-width: 679px) {
    #spec-svg { height: 150px; }
    .zoom-inset #zoom-svg,
    .zoom-inset #zoom-empty { min-height: 140px; }
}

/* --- DEPT practice: three stacked synthesized panels + a 4-way classifier.
       Panels share one X mapping so lines align vertically; chips carry a
       segmented CH3/CH2/CH/C control per signal. --- */
#dept-panels {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.dept-panel h2 {
    font-size: 0.85rem;
    color: #555;
    margin: 0 0 2px;
    text-align: left;
}

.dept-panel svg {
    width: 100%;
    height: 150px;
    display: block;
    background: #fff;
    border: 1px solid #e2e2e2;
    border-radius: 6px;
}

#dept-chips {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 10px;
    margin: 14px 0 6px;
}

.dept-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    border: 2px solid #ccc;
    border-radius: 14px;
    padding: 8px 10px;
    background: #fff;
}

.dept-chip-label {
    font-weight: 700;
    font-size: 0.9rem;
}

.dept-seg {
    display: inline-flex;
    border: 1px solid #bbb;
    border-radius: 8px;
    overflow: hidden;
}

.dept-seg-btn {
    border: none;
    background: #f6f6f6;
    padding: 5px 10px;
    font-size: 0.85rem;
    font-weight: 600;
    color: #444;
    cursor: pointer;
    border-right: 1px solid #ddd;
}

.dept-seg-btn:last-child { border-right: none; }

.dept-seg-btn:hover { background: #ececff; }

.dept-seg-btn.on {
    background: #6153cc;
    color: #fff;
}

/* Post-check: the true class button gets a teal underline even when the
   student's (wrong) pick stays highlighted, so both are visible at once. */
.dept-seg-btn.truth {
    box-shadow: 0 -3px 0 #2a9d8f inset;
}

.dept-chip-truth {
    min-height: 1.1em;
    font-size: 0.78rem;
    color: #555;
    text-align: center;
}

.dept-chip.dept-right { border-color: #2a9d8f; box-shadow: 0 0 0 1px #2a9d8f inset; }
.dept-chip.dept-wrong { border-color: #d32f2f; box-shadow: 0 0 0 1px #d32f2f inset; }

@media (max-width: 679px) {
    .dept-panel svg { height: 110px; }
}

/* --- No-frameshift batch (Dennis, 2026-07-28) --- */

/* Integration page: spectrum + expansion share ONE row; candidates below. */
#data-row {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 14px;
    align-items: stretch;
}
@media (max-width: 899px) {
    #data-row { grid-template-columns: minmax(0, 1fr); }
}

/* Check/skip/reveal on one row: none of these pages has a text input, so
   the controls need no stacking. reveal-link joins the row. */
#guess-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin: 0.9em 0 0.4em;
}
#guess-controls #primary-controls,
#guess-controls #secondary-controls { margin-top: 0; }

/* Verdict button states live in nmr-practice.css (shared by all pages). */

/* DEPT page: spectra stack left, classification chips right (single column)
   so the page fits in one screen height. */
#dept-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 1.2fr);
    gap: 14px;
    align-items: start;
}
#dept-layout #dept-chips {
    grid-template-columns: minmax(0, 1fr);
    margin: 0;
    max-height: 560px;
    overflow-y: auto;
}
@media (max-width: 899px) {
    #dept-layout { grid-template-columns: minmax(0, 1fr); }
    #dept-layout #dept-chips { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); max-height: none; }
}

/* Phase 1 reserved zones (no-frameshift): the verdict line nests inside
   the zone (see nmr-practice.css); the zone has a fixed budget with
   internal scroll. */
#explanation-area {
    min-height: 6.5em;
    max-height: 6.5em;
    overflow-y: auto;
}
@media (max-width: 679px) {
    #explanation-area { min-height: 0; max-height: none; overflow: visible; }
}
