/*
 * Coding Ireland proprietary interactive activity
 * Copyright (c) 2017-2026 Coding Ireland. All rights reserved.
 *
 * Part of the Coding Ireland online learning platform. Licensed for use only
 * as delivered on the platform. Copying, redistributing, or adapting this
 * file, in whole or in part, for use in any other product or service is not
 * permitted. Ref: CI-maths-circuit-builder
 */
.cb-stage { font-family: 'Nunito', system-ui, sans-serif; }

.cb-prompt {
    font-weight: 700; font-size: 16px; color: #163a5f;
    background: #eef6ff; border: 1px solid #c7dcf2; border-radius: 10px;
    padding: 10px 14px; margin: 4px 0 14px;
}

/* ---- Breadboard grid ---------------------------------------------------- */
.cb-grid {
    width: min(460px, 100%);
    margin: 4px auto 14px;
    display: grid;
    background: #f3f6fb;
    border: 2px solid #d7e0ea;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: inset 0 1px 4px rgba(15, 42, 80, .08);
}
.cb-cell {
    position: relative;
    aspect-ratio: 1 / 1;
    touch-action: none;
    background:
        radial-gradient(circle at 50% 50%, #c3cdda 2px, transparent 2.6px);
    transition: background-color .12s ease, box-shadow .12s ease;
}
.cb-cell.cb-cell-over { box-shadow: inset 0 0 0 3px rgba(21, 101, 192, .45); background-color: rgba(21, 101, 192, .08); }

.cb-tile { position: absolute; inset: 0; }
.cb-tilesvg { width: 100%; height: 100%; display: block; overflow: visible; }

/* wires */
.cb-wire { stroke: #4b5563; stroke-width: 6; stroke-linecap: round; fill: none; }
.cb-tile.cb-energized .cb-wire {
    stroke: #f59e0b; stroke-dasharray: 7 5;
    filter: drop-shadow(0 0 2px rgba(252, 211, 77, .95));
    animation: cb-flow .7s linear infinite;
}
@keyframes cb-flow { to { stroke-dashoffset: -12; } }

/* battery */
.cb-batt { fill: #2bb673; stroke: #1d8a56; stroke-width: 2; }
.cb-batt-nub { fill: #1d8a56; }
.cb-pol { font: 800 13px 'Nunito', sans-serif; fill: #1f2a37; }

/* bulb */
.cb-bulb-glass { fill: #e2e8f0; stroke: #b8c2cf; stroke-width: 2; transition: fill .15s ease; }
.cb-filament { stroke: #b8c2cf; stroke-width: 2; }
.cb-bulb-base { fill: #9aa3ad; }
.cb-tile.cb-on .cb-bulb-glass { fill: #ffe27a; stroke: #f5c945; filter: drop-shadow(0 0 7px rgba(250, 204, 21, .9)); animation: cb-flicker 2.4s ease-in-out infinite; }
.cb-tile.cb-on .cb-filament { stroke: #d97706; }
@keyframes cb-flicker { 0%, 100% { opacity: 1; } 50% { opacity: .88; } }

/* fan */
.cb-fan-housing { fill: #dbe2ea; stroke: #94a3b8; stroke-width: 2; }
.cb-blade { fill: #93a0b0; }
.cb-fan-hub { fill: #5b6675; }
.cb-blades { transform-box: fill-box; transform-origin: center; }
.cb-tile.cb-on .cb-blades { animation: cb-spin .5s linear infinite; }
.cb-tile.cb-on .cb-blade { fill: #5b9bd5; }
@keyframes cb-spin { to { transform: rotate(360deg); } }

/* motor */
.cb-motor-body { fill: #c3ccd8; stroke: #8b97a6; stroke-width: 2; }
.cb-motor-shaft { stroke: #5b6675; stroke-width: 3; stroke-linecap: round; }
.cb-motor-m { font: 800 9px 'Nunito', sans-serif; fill: #475569; text-anchor: middle; }

/* LED */
.cb-led-dome { fill: #e2e8f0; stroke: #b8c2cf; stroke-width: 2; transition: fill .15s ease; }
.cb-led-base { fill: #9aa3ad; }
.cb-led-rays { stroke: #ef4444; stroke-width: 2.5; stroke-linecap: round; opacity: 0; }
.cb-tile.cb-on .cb-led-dome { fill: #ef4444; stroke: #b91c1c; filter: drop-shadow(0 0 7px rgba(239, 68, 68, .85)); }
.cb-tile.cb-on .cb-led-rays { opacity: 1; animation: cb-flicker 1.8s ease-in-out infinite; }

/* ammeter, voltmeter, resistor (the Junior Cycle fill-the-gap parts) */
.cb-meter-body { fill: #f8fafc; stroke-width: 2.4; }
.cb-meter-a { stroke: #b42318; }
.cb-meter-v { stroke: #1d4ed8; }
.cb-meter-scale { fill: none; stroke: #94a3b8; stroke-width: 1.6; stroke-dasharray: 1.4 1.6; }
.cb-meter-needle { stroke: #1f2937; stroke-width: 1.8; stroke-linecap: round; transform-box: view-box; transform-origin: 30px 31px; transition: transform .5s cubic-bezier(.3, 1.4, .5, 1); }
.cb-meter-pin { fill: #1f2937; }
.cb-meter-letter { font: 900 9.5px 'Nunito', sans-serif; text-anchor: middle; }
.cb-meter-a ~ .cb-meter-letter { fill: #b42318; }
.cb-meter-v ~ .cb-meter-letter { fill: #1d4ed8; }
.cb-tile.cb-on .cb-meter-needle { transform: rotate(68deg); }
.cb-res-body { fill: #e8d3a8; stroke: #a8875a; stroke-width: 1.6; }

/* bell */
.cb-bell-body { fill: #f4c430; stroke: #c79612; stroke-width: 2; }
.cb-bell-base { fill: #c79612; }
.cb-bell-clap { fill: #8a6a12; }

/* push button */
.cb-btn-base { fill: #94a3b8; stroke: #64748b; stroke-width: 1.5; }
.cb-btn-cap { fill: #ef4444; stroke: #b91c1c; stroke-width: 1.5; transition: none; }
.cb-tile.cb-energized .cb-btn-cap { fill: #f87171; }

/* buzzer */
.cb-buzz-body { fill: #334155; stroke: #1f2937; stroke-width: 2; }
.cb-buzz-dot { fill: #94a3b8; }
.cb-sound { stroke: #f59e0b; stroke-width: 2.5; fill: none; opacity: 0; }
.cb-tile.cb-on .cb-sound { opacity: 1; animation: cb-sound 1s ease-in-out infinite; }
@keyframes cb-sound { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* switch */
.cb-lever { stroke: #1f2a37; stroke-width: 6; stroke-linecap: round; transition: all .15s ease; }
.cb-term { fill: #4b5563; }
.cb-tile.cb-energized .cb-lever { stroke: #b45309; }

/* test material */
.cb-test { fill: #fef3c7; stroke: #d97706; stroke-width: 2; }

/* remove button — subtle by default, only reddens when you hover it directly */
.cb-remove {
    position: absolute; top: 2px; right: 2px; z-index: 4;
    width: 15px; height: 15px; padding: 0; line-height: 1;
    border: none; border-radius: 50%;
    background: rgba(100, 116, 139, .16); color: #94a3b8; font-size: 8px;
    cursor: pointer; opacity: .4;
    transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.cb-cell:hover .cb-remove { opacity: .8; }
.cb-remove:hover { background: rgba(220, 38, 38, .92); color: #fff; opacity: 1; }

/* ---- Result ------------------------------------------------------------- */
.cb-result { text-align: center; font-weight: 800; min-height: 24px; margin: 6px 0 12px; }
.cb-result.cb-on { color: #15803d; }
.cb-result.cb-off { color: #64748b; }

/* ---- Palette ------------------------------------------------------------ */
.cb-palette-wrap { margin-bottom: 8px; }
.cb-tray-label {
    font-weight: 800; font-size: 12px; color: #64748b; margin: 4px 0 8px;
    text-transform: uppercase; letter-spacing: .08em;
}
.cb-palette {
    display: flex; flex-wrap: wrap; gap: 10px; padding: 12px;
    background: linear-gradient(180deg, #f1f5f9, #e7eef6);
    border: 1px dashed #cbd5e1; border-radius: 14px;
}
.cb-pal-item {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    width: 74px; padding: 8px 6px;
    background: #ffffff; border: 1.5px solid #cbd5e1; border-radius: 12px;
    cursor: grab; user-select: none; touch-action: none;
    box-shadow: 0 2px 6px rgba(15, 42, 80, .12);
    transition: transform .12s ease, box-shadow .12s ease;
}
.cb-pal-item:hover { transform: translateY(-2px); box-shadow: 0 8px 16px -6px rgba(15, 42, 80, .35); }
.cb-pal-item:active { cursor: grabbing; }
.cb-pal-item.cb-dragging { opacity: .35; }
.cb-pal-item .cb-tile { position: static; width: 48px; height: 48px; }
.cb-pal-label { font-weight: 800; font-size: 11px; color: #475569; text-align: center; }

.cb-hint { font-size: 12px; color: #64748b; text-align: center; margin: 2px 0 8px; }

/* ---- Check -------------------------------------------------------------- */
.cb-target-panel { display: flex; align-items: center; gap: 14px; justify-content: center; }

/* ---- Display mode ------------------------------------------------------- */
.activity-container.display-mode .cb-cell { background: none; }

/* ---- Fill-the-gap mode (a challenge with gapFill: true) -----------------
   One loop of six places whose gaps the class fills from a tray. Everything here hangs off
   .cb-gf* or .cb-gf-mode, which only a gapFill challenge switches on, so the grid, its palette
   and every lesson preset look exactly as before. Sizes are px on purpose: in competition mode
   the shared fit zooms the whole activity to the frame, so the loop and the tray grow together. */
.cb-stage.cb-gf-mode .cb-grid,
.cb-stage.cb-gf-mode .cb-palette-wrap,
.cb-stage.cb-gf-mode .cb-hint { display: none; }

.cb-gf {
    display: flex; align-items: center; gap: 28px;
    width: max-content; margin: 2px auto 0;
}
/* On a lesson page nothing fits it to the frame, so a narrow one puts the tray under the loop. */
html:not(.mcr-compete) .cb-gf { width: auto; flex-wrap: wrap; justify-content: center; }
.cb-gf-fig {
    position: relative; flex: none; box-sizing: content-box;
    width: 660px; height: 412px;
    background: #fff; border: 2px solid #d7e0ea; border-radius: 18px;
    box-shadow: 0 2px 8px rgba(15, 42, 80, .06);
}
.cb-gf-loop { position: absolute; inset: 0; pointer-events: none; }
.cb-gf-loop svg { display: block; width: 100%; height: 100%; }
.cb-gf-wire { fill: none; stroke: #4b5563; stroke-width: 13; }
.cb-gf.is-on .cb-gf-wire {
    stroke: #f59e0b; stroke-dasharray: 14 10;
    filter: drop-shadow(0 0 3px rgba(252, 211, 77, .95));
    animation: cb-gf-flow .7s linear infinite;
}
@keyframes cb-gf-flow { to { stroke-dashoffset: -24; } }

/* A place on the loop. White, so the wire stops at its edges and the part's own leads join it. */
.cb-gf-slot {
    position: absolute; box-sizing: border-box;
    width: 150px; height: 150px; margin: -75px 0 0 -75px;
    background: #fff; border-radius: 18px;
}
.cb-gf-gap {
    border: 4px dashed #94a3b8; background: #f8fafc;
    cursor: pointer; touch-action: none;
    transition: border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}
.cb-gf-gap.is-filled { border-style: solid; border-color: #1565c0; background: #fff; }
/* Leads as thick as the loop's wire, cut at the edge of the place so the two meet end to end;
   when the loop works they flow with it (clockwise, so leftwards along the bottom). */
.cb-gf .cb-tilesvg { overflow: hidden; }
.cb-gf .cb-tile .cb-wire { stroke-width: 3.8; }
.cb-gf-fig .cb-tile.cb-energized .cb-wire { stroke-dasharray: 4.2 3; animation-name: cb-gf-flow-lead; }
.cb-gf-slot.is-bottom .cb-tile.cb-energized .cb-wire { animation-direction: reverse; }
@keyframes cb-gf-flow-lead { to { stroke-dashoffset: -7.2; } }
.cb-gf-placed { position: absolute; inset: 0; cursor: grab; touch-action: none; user-select: none; }
.cb-gf-placed.cb-gf-dragging { opacity: .3; }
.cb-gf-name {
    position: absolute; transform: translateX(-50%); white-space: nowrap; pointer-events: none;
    font: 800 22px/28px 'Nunito', system-ui, sans-serif; color: #1f2a37;
}

/* The tray */
.cb-gf-tray {
    flex: none; box-sizing: border-box; padding: 10px 14px 14px;
    background: linear-gradient(180deg, #f1f5f9, #e7eef6);
    border: 2px dashed #cbd5e1; border-radius: 18px;
}
.cb-gf-tray-label {
    font: 800 15px/1 'Nunito', system-ui, sans-serif; color: #64748b;
    text-transform: uppercase; letter-spacing: .1em; margin: 2px 2px 10px;
}
.cb-gf-tray-in { display: grid; grid-template-columns: repeat(var(--cb-gf-cols, 2), 140px); gap: 12px; }
.cb-gf-tile {
    position: relative; box-sizing: border-box; height: 170px; padding: 8px 6px 10px;
    display: flex; flex-direction: column; align-items: center; justify-content: space-between;
    background: #fff; border: 2px solid #cbd5e1; border-radius: 16px;
    box-shadow: 0 3px 8px rgba(15, 42, 80, .12);
    cursor: grab; user-select: none; touch-action: none;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.cb-gf-tile:hover { border-color: #93a8c2; }
.cb-gf-art { position: relative; flex: none; width: 116px; height: 116px; }
.cb-gf-tname { font: 800 20px/1.1 'Nunito', system-ui, sans-serif; color: #1f2a37; text-align: center; }
.cb-gf-tile.cb-gf-dragging { opacity: .35; }
.cb-gf-tile.pd-selected { transform: translateY(-3px); border-color: #f5b301; }
.cb-gf-tile.is-used { background: transparent; border-style: dashed; box-shadow: none; pointer-events: none; }
.cb-gf-tile.is-used > * { visibility: hidden; }
/* the copy that follows a finger lives outside the activity */
body > .cb-gf-tile { height: auto; }
body > .cb-gf-placed { inset: auto; aspect-ratio: 1 / 1; }

/* A part picked up: the gaps it can go in light up. Dragging over one rings it. */
html.pd-picking .cb-gf-gap.pd-can-drop { outline: none; border-color: #f5b301; background: #fff8e1; }
.cb-gf-gap.cb-gf-over { box-shadow: 0 0 0 6px rgba(21, 101, 192, .3); }
.cb-gf-gap.is-nudge { border-color: #f59e0b; background: #fff8e1; animation: cb-gf-nudge .45s ease-in-out 2; }
@keyframes cb-gf-nudge { 50% { transform: scale(1.07); } }

/* After Test it */
.cb-gf.is-locked .cb-gf-tile,
.cb-gf.is-locked .cb-gf-placed { cursor: default; }
.cb-gf.is-locked .cb-gf-tile:not(.is-used) { opacity: .5; }
.cb-gf-gap.is-right { border: 4px solid #16a34a; background: #f0fdf4; }
.cb-gf-gap.is-wrong { border: 4px solid #dc2626; background: #fef2f2; }
.cb-gf-slot.is-fixed.is-wrong { box-shadow: 0 0 0 4px #dc2626; background: #fef2f2; }
/* On the corner that faces into the loop, clear of the part's name. */
.cb-gf-mark {
    position: absolute; top: -22px; right: -22px; z-index: 3;
    width: 36px; height: 36px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 19px; box-shadow: 0 2px 6px rgba(15, 42, 80, .25);
}
.cb-gf-slot.is-top > .cb-gf-mark { top: auto; bottom: -22px; }
.is-right > .cb-gf-mark { background: #16a34a; }
.is-wrong > .cb-gf-mark { background: #dc2626; }

.cb-stage.cb-gf-mode .cb-result { font-size: 18px; line-height: 1.35; min-height: 1.35em; margin: 10px 0 8px; }
.cb-result.cb-gf-say-ok { color: #15803d; }
.cb-result.cb-gf-say-bad { color: #b91c1c; }
.cb-result.cb-gf-say-warn { color: #92400e; }

/* ---- Competition layout (board), compete mode only ----------------------
   The round's question is #challengePrompt, which the shared runner sizes for the board; here it
   only loses the lesson strip around it. Check is pinned to the action bar by the runner, so
   the panel that held it folds away. */
html.mcr-compete .cb-prompt {
    background: none; border: 0; padding: 0; text-align: center;
    margin: 0 0 calc(var(--bu) * .5 / var(--mcr-fit, 1));
}
html.mcr-compete .cb-stage .cb-target-panel {
    padding: 0; margin: 0; border: 0; background: none; min-height: 0;
}
html.mcr-compete .cb-stage.cb-gf-mode .cb-result {
    font-size: calc(var(--bu) * 1.6 / var(--mcr-fit, 1));
    margin: calc(var(--bu) * .5 / var(--mcr-fit, 1)) 0 0;
}
/* A squarer board has the height for a taller tray and not the width for a wider one. */
@media (max-aspect-ratio: 3 / 2) {
    html.mcr-compete .cb-gf-tray-in.is-3col { grid-template-columns: repeat(2, 140px); }
    html.mcr-compete .cb-gf-tray-in.is-3col .cb-gf-tile { height: 150px; }
    html.mcr-compete .cb-gf-tray-in.is-3col .cb-gf-art { width: 100px; height: 100px; }
}
