/* ═══════════════════════════════════════════════════════════════════════
   projects/circuit.css — justwhitee · Matteo Fontolan
   PCB visual language for the /projects/ circuit. Tokens (--accent,
   --accent-bright, --bg-color, --radius) come from shared.css.
   ═══════════════════════════════════════════════════════════════════════ */

.circuit-stage {
    position: relative;
    width: 100%;
}

.circuit-stage.is-hidden {
    display: none;
}

.circuit-view-toggle {
    display: block;
    margin: 0 auto 6px;
    padding: 7px 18px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    color: var(--accent-bright);
    background: rgba(var(--accent-rgb), 0.08);
    border: 1px solid rgba(var(--accent-bright-rgb), 0.35);
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.circuit-view-toggle:hover {
    background: rgba(var(--accent-bright-rgb), 0.15);
    border-color: var(--accent-bright);
}

.circuit-svg {
    display: block;
    width: 100%;
    height: auto;
    color: rgba(var(--accent-rgb), 0.35);
}

.circuit-path {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.circuit-path-untraveled {
    stroke: rgba(var(--accent-rgb), 0.18);
    stroke-width: 3.5;
}

/* Chip-solder-pad cap: a short, thicker overlay on the final stretch of
   lanes that end together in a parallel bundle, standing in for the
   soldered contact row at the edge of a chip. */
.circuit-path-untraveled-cap {
    stroke: rgba(var(--accent-rgb), 0.32);
    stroke-width: 8;
}

.circuit-path-traveled {
    stroke: rgba(var(--accent-rgb), 0.18);
    transition: stroke 0.4s ease;
}

/* Stroke-width hierarchy (spec Routing rules): main path thickest,
   dead-ends thinner — still heavier than the untraveled network above,
   so "what's conducting" reads at a glance. */
.circuit-path-main    { stroke-width: 7; }
.circuit-path-deadend { stroke-width: 5; }

.circuit-segment.is-lit .circuit-path-traveled {
    stroke: var(--accent-bright);
    filter: drop-shadow(0 0 5px rgba(var(--accent-bright-rgb), 0.65));
}

/* The base line above stays solid once lit — a steady, thick "live wire."
   This overlay is the separate bright streak that travels along it,
   reading as energy moving through the wire rather than the wire itself
   blinking. Same geometry (identical `d`), drawn on top. */
.circuit-flow-overlay {
    fill: none;
    stroke: #fff;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 3.5;
    opacity: 0;
}

.circuit-segment.is-lit .circuit-flow-overlay {
    opacity: 0.7;
}

/* A mix of the original smooth pulse and the jagged-lightning attempt:
   a single medium-length dash per 180px cycle (half as many as the
   two-dash version, so the gap between sparks is effectively doubled —
   still 180 total, so FLOW_SPEED_PX_PER_S/FLOW_PERIOD_MS in circuit.js
   stay in sync), blurred enough to glow softly like the original, with
   #circuit-lightning-jitter (circuit.js) still kinking its geometry
   underneath that blur for the "electric" texture. */
.circuit-segment.is-flowing .circuit-flow-overlay {
    stroke-dasharray: 22 158;
    filter: url(#circuit-lightning-jitter) blur(1px) drop-shadow(0 0 4px rgba(255, 255, 255, 0.85)) drop-shadow(0 0 11px rgba(var(--accent-bright-rgb), 0.8));
    animation: circuit-flow 1.2s linear infinite;
}

@keyframes circuit-flow {
    to { stroke-dashoffset: -180; }
}

.circuit-via {
    color: rgba(var(--accent-rgb), 0.4);
}

.circuit-decor {
    color: rgba(var(--accent-rgb), 0.3);
}

.circuit-node-pad {
    fill: none;
    stroke: rgba(var(--accent-rgb), 0.4);
    stroke-width: 1.5;
}

.circuit-node-fill {
    fill: #0b2b2d;
    stroke: rgba(var(--accent-bright-rgb), 0.5);
    stroke-width: 1.5;
    transition: stroke 0.4s ease, filter 0.4s ease;
}

.circuit-node.is-lit .circuit-node-fill {
    stroke: var(--accent-bright);
    filter: drop-shadow(0 0 6px rgba(var(--accent-bright-rgb), 0.55));
}

.circuit-node.is-excited .circuit-node-fill {
    filter: drop-shadow(0 0 10px rgba(var(--accent-bright-rgb), 0.9));
}

.circuit-node-overlay {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    pointer-events: none;
}

.circuit-node-btn {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 76px;
    height: 76px;
    border-radius: 50%;
    border: none;
    background: transparent;
    cursor: pointer;
    pointer-events: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.circuit-node-btn:focus-visible {
    outline: 2px solid var(--accent-bright);
    outline-offset: 3px;
    border-radius: 50%;
}

.circuit-node-icon {
    width: 36px;
    height: 36px;
    object-fit: contain;
    pointer-events: none;
    filter: brightness(0.9);
}

/* Its random-jump excite reads best with real room to move in — give it a
   bigger stage than the uniform node-icon size. */
.circuit-node-btn[data-slug="edgecv4safety"] .circuit-node-icon {
    width: 40px;
    height: 40px;
}

.circuit-node-icon.is-vibrating {
    animation: crackerVibrate 0.1s linear infinite;
}

.circuit-node-crumb {
    position: absolute;
    border: 1px solid #1a0f00;
    border-radius: 40%;
    pointer-events: none;
}

.circuit-node-icon #sliceceipt-back-board,
.circuit-node-icon #sliceceipt-front-board {
    transform-box: fill-box;
    transform-origin: center;
    transition: transform 0.45s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.circuit-node-icon.is-flapping #sliceceipt-back-board  { transform: translate(-12px, -9px) rotate(-7deg); }
.circuit-node-icon.is-flapping #sliceceipt-front-board { transform: translate(12px, 9px) rotate(7deg); }

/* scrollbar-gutter:stable always reserves the track's width, but with no
   custom styling that reserved strip shows the browser's default (usually
   light) scrollbar track against this dark panel — reading as a stray
   border down the right edge even before anything scrolls. */
.circuit-popup,
.circuit-window {
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--accent-bright-rgb), 0.35) transparent;
}
.circuit-popup::-webkit-scrollbar,
.circuit-window::-webkit-scrollbar {
    width: 8px;
}
.circuit-popup::-webkit-scrollbar-track,
.circuit-window::-webkit-scrollbar-track {
    background: transparent;
}
.circuit-popup::-webkit-scrollbar-thumb,
.circuit-window::-webkit-scrollbar-thumb {
    background: rgba(var(--accent-bright-rgb), 0.35);
    border-radius: 4px;
}
.circuit-popup::-webkit-scrollbar-thumb:hover,
.circuit-window::-webkit-scrollbar-thumb:hover {
    background: rgba(var(--accent-bright-rgb), 0.55);
}

.circuit-popup {
    position: absolute;
    z-index: 50;
    width: min(400px, 90vw);
    max-height: 82vh;
    overflow-y: auto;
    scrollbar-gutter: stable;
    border-radius: var(--radius);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5), 0 0 24px rgba(var(--accent-bright-rgb), 0.25);
}

.circuit-popup .project-card {
    width: 100%;
}

/* The featured card's 2-column layout needs real width (~1000px, its
   natural grid size) to look right — a hover popup never has that much
   room, so it always gets the same single-column layout the site already
   uses below 900px viewport width, rather than squeezing 2 columns into
   400px. */
.circuit-popup .project-card.featured {
    grid-column: span 1;
    display: flex;
    flex-direction: column;
}
/* Targets project-img-wrap directly (not .project-img) — EdgeCV4Safety's
   image is injected SVG (svg-inject mode), which never carries the
   .project-img class the plain <img> cards use, so a rule scoped to that
   class silently never matched here and the image rendered at its full
   intrinsic size instead of the intended compact height. */
.circuit-popup .project-card.featured .project-img-wrap {
    height: 200px;
    padding: 16px;
    box-sizing: border-box;
}
.circuit-popup .project-card.featured .project-img { height: 100%; min-height: unset; padding: 0; }

.circuit-window-backdrop {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(3, 8, 8, 0.75);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.circuit-window {
    position: relative;
    width: min(92vw, 560px);
    max-height: 90vh;
    overflow-y: auto;
    scrollbar-gutter: stable;
    border-radius: var(--radius);
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6), 0 0 32px rgba(var(--accent-bright-rgb), 0.3);
}

/* Featured cards (currently just EdgeCV4Safety) keep their original 2-column
   grid treatment, which needs real width to look right. */
.circuit-window:has(.project-card.featured) {
    width: min(92vw, 960px);
}

.circuit-window .project-card {
    width: 100%;
}

.circuit-window-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 1;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(var(--accent-bright-rgb), 0.4);
    background: rgba(8, 15, 15, 0.85);
    color: var(--accent-bright);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.circuit-window-close:hover {
    background: rgba(var(--accent-bright-rgb), 0.15);
}
