:root {
  --bb-green: #adc276; --bb-green-dark: #8da45a; --bb-green-deep: #5d7139;   /* links and small print: 5.4:1 on white */
  --bb-dark: #111111; --bb-secondary: #5f6b57; --bb-sage: #bbd291; --bb-border: #c9d6aa;
  --bb-light-bg: #e2ecce; --bb-red: #d9534f; --bb-red-bg: #f7dcdb; --bb-amber: #e0a800;
  --bb-cream: #ffffff; --bb-green-light: #bbd291; --bb-yellow: #fdd14d;
  /* every surface goes through a name, so the dark theme is a list of colours and nothing else */
  --bb-surface: #ffffff;        /* cards, panels, popups, buttons */
  --bb-code-bg: #ffffff;        /* the editor and the console */
  --bb-view-bg: #faf8ef;        /* around the robot's mat */
  --bb-bar: var(--bb-green);    /* the top bar */
  --bb-soft: #f4f7ee;           /* the bars that belong to a cell: debug, share */
  --bb-note: #fff7d6;           /* a note from the teacher */
  --bb-note-border: #e8d48a;
  --bb-ink-dim: #3d4a30;        /* small print on a green ground */
  --bb-placeholder: #9aa7ad;
  --bb-red-ink: #7a1f1b;
  --bb-cam-bg: #c9d3c3;         /* behind the robot's camera view, which is drawn on a clear canvas */
  --bb-chip: rgba(255,255,255,.65);   /* a word of code sitting on a coloured ground */
  --bb-on-green: #111111;       /* the brand green is light in both themes: what sits on it never changes */
  --bb-on-green-dim: #3d4a30;
  /* one scale for the whole page: rem sizes everything, including the code */
  --text-scale: 1;
  --code-size: .84rem;
}
/* the student's text size: the page is laid out in rem, so this moves all of it at once */
html { font-size: calc(100% * var(--text-scale)); }

/* the dark theme: the same page, a different set of colours */
:root.bb-dark {
  --bb-dark: #e4e8ec; --bb-secondary: #9fb2bf; --bb-border: #2b323a;
  --bb-cream: #14171b; --bb-surface: #1b1f25; --bb-code-bg: #15181c; --bb-view-bg: #101317;
  --bb-light-bg: #222932; --bb-sage: #232a31; --bb-bar: #1b2026; --bb-soft: #1e242b;
  --bb-note: #2c2718; --bb-note-border: #5b4f29; --bb-ink-dim: #b6c4cf; --bb-placeholder: #66727d;
  --bb-green-deep: #a8e06a; --bb-red: #ff8a84; --bb-red-bg: #3a2322; --bb-red-ink: #ffb4ae;
  --bb-cam-bg: #232a28; --bb-chip: rgba(255,255,255,.12);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }
body { font-family: 'Nunito', system-ui, sans-serif; color: var(--bb-dark); background: var(--bb-cream); line-height: 1.55; }
a { color: var(--bb-green-deep); }

/* top bar: cream, the wordmark logo, the site's name beside it */
.bar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 1.5rem; padding: .45rem 1.25rem; background: var(--bb-bar); color: var(--bb-dark); }
.brand { font-family: 'Varela Round', sans-serif; font-size: 1.05rem; color: var(--bb-dark); text-decoration: none; display: flex; align-items: center; gap: .7rem; }
.brand .logo { height: 38px; width: auto; display: inline-block; }
.brand .site { padding: .15rem .65rem; border-radius: 999px; background: #000; color: #fff; font-size: .85rem; font-weight: 700; letter-spacing: .02em; }
.bar-links { display: flex; gap: 1.1rem; margin-left: auto; }
.bar-links a { color: var(--bb-dark); text-decoration: none; font-weight: 700; font-size: .9rem; }
.bar-links a:hover { color: #fff; }
.status { font-family: 'Roboto Mono', monospace; font-size: .75rem; color: var(--bb-ink-dim); }

/* the one WebGL canvas: fixed over the page, drawn only inside visible cells */
/* the shared WebGL canvas is a scratch surface: each view is copied into the cell's own canvas, which scrolls with the page */
.gl { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; visibility: hidden; z-index: -1; }

/* index */
.index { max-width: 1000px; margin: 0 auto; padding: 2.5rem 1.25rem 4rem; }
.index h1 { font-family: 'Varela Round', sans-serif; font-weight: 400; font-size: 2rem; margin: 0 0 .5rem; }
.index .lead { color: var(--bb-secondary); max-width: 62ch; margin-bottom: 2rem; }
.module { margin-bottom: 2.5rem; }
.module-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.module-head .num { font-family: 'Roboto Mono', monospace; font-size: .75rem; color: var(--bb-secondary); letter-spacing: .05em; }
.module-head h2 { font-family: 'Varela Round', sans-serif; font-weight: 400; margin: .2rem 0 .3rem; font-size: 1.5rem; }
.module-head p { margin: 0; color: var(--bb-secondary); max-width: 62ch; }
.side-module { margin-bottom: .35rem; }
.side-module-title { display: flex; align-items: center; gap: .4rem; width: 100%; text-align: left; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--bb-secondary); margin: .35rem 0 .1rem; padding: .3rem 0; border: 0; background: none; border-radius: 4px; font-weight: 700; }
.side-module-title:hover { background: var(--bb-light-bg); }
.side-module-title .t { flex: 1; }
.side-module-title .count { font-family: 'Roboto Mono', monospace; font-size: .7rem; text-transform: none; letter-spacing: 0; }
.side-module-title .chev { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--bb-secondary); transform: rotate(-90deg); transition: transform .15s; }
.side-module.open .side-module-title .chev { transform: rotate(0); }
.side-module-body { display: none; padding-left: .9rem; }
.side-module.open .side-module-body { display: block; }
.drawer-toggle { display: none; }
.drawer-backdrop { display: none; }
.crumb { font-size: .8rem; color: var(--bb-secondary); letter-spacing: .03em; margin-top: .5rem; }
.lesson-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.25rem; }
.lesson-card { display: block; text-decoration: none; color: inherit; border: 1px solid var(--bb-border); border-radius: 12px; padding: 1.25rem 1.25rem 1rem; background: var(--bb-surface); transition: box-shadow .15s; }
.lesson-card:hover { box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.08); }
.lesson-card .num { font-family: 'Roboto Mono', monospace; font-size: .75rem; color: var(--bb-secondary); letter-spacing: .05em; }
.lesson-card h3 { font-family: 'Varela Round', sans-serif; font-weight: 400; margin: .25rem 0 .4rem; font-size: 1.2rem; }
.lesson-card p { margin: 0 0 .75rem; color: var(--bb-secondary); font-size: .95rem; }
.lesson-card .meta { display: flex; justify-content: space-between; align-items: center; font-size: .8rem; color: var(--bb-secondary); }
.progress-pill { border-radius: 999px; padding: .15rem .6rem; font-weight: 700; font-size: .75rem; background: var(--bb-light-bg); border: 1px solid var(--bb-border); }
.progress-pill.done { background: var(--bb-green); border-color: var(--bb-green); color: var(--bb-on-green); }

/* lesson layout */
.lesson { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 2.5rem; max-width: 1180px; margin: 0 auto; padding: 1.5rem 1.25rem 0; }
/* anchors and scrolled cells stop below the sticky bar */
html { scroll-padding-top: 3.6rem; }
.cell { scroll-margin-top: 3.6rem; }
.side { position: sticky; top: 3.4rem; align-self: start; max-height: calc(100vh - 3.4rem); overflow: auto; padding-top: .75rem; font-size: .9rem; }
.side h4 { margin: 1rem 0 .4rem; font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--bb-secondary); }
.side a { display: block; text-decoration: none; color: var(--bb-dark); padding: .25rem 0; }
.side a.current { color: var(--bb-green-deep); font-weight: 700; }
.side .outline a { color: var(--bb-secondary); padding-left: .5rem; border-left: 2px solid var(--bb-border); }
.side .outline a.active { color: var(--bb-dark); border-left-color: var(--bb-green-dark); }
.main { min-width: 0; max-width: 760px; padding-bottom: 5rem; }
.main h1 { font-family: 'Varela Round', sans-serif; font-weight: 400; font-size: 2.1rem; margin: .5rem 0 1rem; text-wrap: balance; }
.main h2 { font-family: 'Varela Round', sans-serif; font-weight: 400; font-size: 1.45rem; margin: 2.4rem 0 .6rem; padding-top: .5rem; scroll-margin-top: 4.5rem; }
.main p, .main li { max-width: 68ch; }
.main code { font-family: 'Roboto Mono', monospace; font-size: .88em; background: var(--bb-light-bg); border: 1px solid var(--bb-border); border-radius: 3px; padding: 0 .25em; }
.main pre { background: var(--bb-light-bg); border: 1px solid var(--bb-border); border-radius: 8px; padding: .8rem 1rem; overflow-x: auto; font-family: 'Roboto Mono', monospace; font-size: .85rem; line-height: 1.5; }
.main pre code { background: none; border: 0; padding: 0; font-size: inherit; }
.main ol li, .main ul li { margin: .3rem 0; }
.main h2.quiz-title { margin-top: 2.5rem; }

/* a file of the student's own on a lesson page: an editor with no robot, which the page's cells can import */
.file-cell .cell-head { grid-template-columns: auto minmax(0, 1fr) auto; }
.file-cell .cell-head .note { font-size: .78rem; color: var(--bb-ink-dim); min-width: 0; }
.file-cell .file-reset { font: inherit; font-size: .78rem; padding: .2rem .6rem; }
.file-cell .CodeMirror { height: auto; font-size: var(--code-size); }
.file-cell.file-written .cell-head { animation: file-written 1.6s ease-out; }
@keyframes file-written { from { background: var(--bb-yellow); } to { background: var(--bb-sage); } }
@media (prefers-reduced-motion: reduce) { .file-cell.file-written .cell-head { animation: none; outline: 2px solid var(--bb-yellow); } }

/* the same files as tabs on a cell, so a file can be read without scrolling back up the page */
.cell .file-bar { display: flex; align-items: center; gap: .15rem; padding: 0 .55rem; background: var(--bb-code-bg); border-bottom: 1px solid var(--bb-border); overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.cell .file-tab { font: inherit; font-size: .78rem; padding: .35rem .5rem; border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--bb-secondary); cursor: pointer; white-space: nowrap; margin-bottom: -1px; }
.cell .file-tab:hover { color: var(--bb-dark); }
.cell .file-tab.on { color: var(--bb-dark); font-weight: 600; border-bottom-color: var(--bb-green-dark); }
.cell .file-actions { margin-left: auto; display: flex; align-items: center; gap: .4rem; padding-left: .5rem; }
.cell .file-bar .file-reset { font: inherit; font-size: .75rem; padding: .15rem .5rem; white-space: nowrap; }
.cell .file-add { font: inherit; font-size: .75rem; padding: .15rem .4rem; border: 0; background: transparent; color: var(--bb-secondary); cursor: pointer; white-space: nowrap; }
.cell .file-add:hover { color: var(--bb-dark); text-decoration: underline; }
.cell .file-tab.file-written { animation: file-written 1.6s ease-out; }
@media (prefers-reduced-motion: reduce) { .cell .file-tab.file-written { animation: none; outline: 2px solid var(--bb-yellow); } }

/* a flowchart drawn inline: its lines and words follow the text colour, so it works in both themes */
.main figure.flowchart { margin: 1.4rem 0; max-width: 68ch; color: var(--bb-dark); }
.main figure.flowchart svg { display: block; width: 100%; height: auto; max-height: 34rem; }
.main figure.flowchart figcaption { font-size: .8rem; color: var(--bb-secondary); margin-top: .35rem; }
/* on a phone a wide diagram would shrink its labels to about 8 px: keep it at least 500 px wide and let it scroll */
@media (max-width: 560px) {
  .main figure.flowchart { overflow-x: auto; }
  .main figure.flowchart svg[viewBox^="0 0 5"], .main figure.flowchart svg[viewBox^="0 0 6"],
  .main figure.flowchart svg[viewBox^="0 0 7"] { min-width: 500px; }
}

/* an exam box: what the exam boards expect on this topic, one tab per board */
.exam { margin: 1.6rem 0; max-width: 68ch; border: 1px solid var(--bb-border); border-radius: 10px; background: var(--bb-surface); overflow: hidden; }
.exam-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem .75rem; padding: .4rem .5rem .4rem .9rem; background: var(--bb-soft); border-bottom: 1px solid var(--bb-border); }
.exam-title { font-size: .75rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--bb-secondary); }
.exam-boards { display: flex; gap: .25rem; }
.exam-boards button { font: inherit; font-size: .8rem; line-height: 1.2; padding: .22rem .7rem; border-radius: 999px; border: 1px solid var(--bb-border); background: var(--bb-surface); color: var(--bb-dark); cursor: pointer; }
.exam-boards button:hover { border-color: var(--bb-green-dark); }
.exam-boards button[aria-selected="true"] { background: var(--bb-green); border-color: var(--bb-green); color: var(--bb-on-green); font-weight: 700; }
.exam-boards button:focus-visible { outline: 2px solid var(--bb-green-deep); outline-offset: 2px; }
.exam-body { padding: .1rem 1rem .5rem; }
.exam-body > :first-child, .exam-board > :first-child { margin-top: .6rem; }
.exam-spec { font-family: 'Roboto Mono', monospace; font-size: .72rem; letter-spacing: .02em; color: var(--bb-secondary); margin: .7rem 0 -.2rem; }
.exam-body pre { font-size: .8rem; }
.quiz-lead { color: var(--bb-secondary); }
.quiz-q { margin: 1rem 0; padding: .8rem 1rem; border: 1px solid var(--bb-border); border-radius: 10px; background: var(--bb-surface); }
.quiz-q.right { border-color: var(--bb-green-dark); box-shadow: inset 4px 0 var(--bb-green-dark); }
.quiz-q.wrong { border-color: var(--bb-red); box-shadow: inset 4px 0 var(--bb-red); }
.quiz-q fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.quiz-q legend { font-weight: 700; padding: 0; margin-bottom: .5rem; }
.quiz-q legend code, .quiz-options code, .quiz-explain code { font-family: 'Roboto Mono', monospace; font-size: .9em; background: var(--bb-light-bg); padding: 0 .3em; border-radius: 3px; font-weight: 500; }
.quiz-n { display: inline-flex; align-items: center; justify-content: center; min-width: 1.6rem; height: 1.6rem; margin-right: .3rem; border-radius: 50%; background: var(--bb-sage); color: var(--bb-on-green); font-size: .85rem; }
.quiz-code, .quiz-answer pre { font-family: 'Roboto Mono', monospace; font-size: .85rem; background: var(--bb-code-bg); border: 1px solid var(--bb-border); border-radius: 6px; padding: .5rem .7rem; margin: .3rem 0 .6rem; white-space: pre; overflow-x: auto; }
.quiz-options { display: flex; flex-direction: column; gap: .3rem; }
.quiz-options label { display: flex; gap: .5rem; align-items: baseline; padding: .3rem .4rem; border-radius: 6px; cursor: pointer; }
.quiz-options label:hover { background: var(--bb-light-bg); }
.quiz-in { font: inherit; padding: .35rem .5rem; border: 1px solid var(--bb-border); border-radius: 6px; background: var(--bb-surface); color: var(--bb-dark); width: min(100%, 22rem); }
.quiz-out { font-family: 'Roboto Mono', monospace; font-size: .85rem; width: min(100%, 30rem); display: block; }
.quiz-order { margin: .2rem 0; padding-left: 1.5rem; }
.quiz-order li { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .2rem .3rem; margin: .15rem 0; border: 1px solid var(--bb-border); border-radius: 6px; background: var(--bb-code-bg); }
.quiz-order code { font-family: 'Roboto Mono', monospace; font-size: .85rem; white-space: pre; }
.quiz-move button { padding: .1rem .45rem; margin-left: .2rem; }
.quiz-actions { display: flex; align-items: center; gap: .7rem; margin-top: .6rem; }
.quiz-q.right .quiz-result { color: var(--bb-green-deep); font-weight: 700; }
.quiz-q.wrong .quiz-result { color: var(--bb-red-ink); font-weight: 700; }
.quiz-explain { margin-top: .5rem; padding: .5rem .7rem; border-radius: 6px; background: var(--bb-light-bg); font-size: .92rem; }
.quiz-explain[hidden] { display: none; }
.quiz-answer { margin-bottom: .3rem; }
.quiz-summary { font-weight: 700; }
.lesson-nav { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--bb-border); }
.lesson-nav a { text-decoration: none; font-weight: 700; }

/* cells */
.cell { margin: 1.25rem 0 1.75rem; border: 1px solid var(--bb-border); border-radius: 12px; overflow: hidden; background: var(--bb-surface); box-shadow: 0 .35rem 1rem rgba(0,0,0,.05); }
.cell.task { border-color: var(--bb-green-dark); }
/* accessibility: a visible focus ring, a skip link, less motion when asked */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline: 3px solid #1a5fb4; outline-offset: 2px; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: -999px; top: .5rem; z-index: 100; padding: .5rem .9rem; background: #111; color: #fff; border-radius: 6px; font-weight: 700; }
.skip:focus { left: .5rem; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; scroll-behavior: auto !important; } }

/* the control that sets the text size and the theme for the page */
.view-wrap { position: relative; margin-left: auto; }
.bar .view-wrap + .bar-links { margin-left: 1.1rem; }
.view-btn { font-family: 'Roboto Mono', monospace; font-weight: 700; padding: .25rem .55rem; }
.view-panel { position: absolute; z-index: 40; right: 0; top: calc(100% + .4rem); width: 15rem; padding: .6rem .7rem; border: 1px solid var(--bb-border); border-radius: 10px; background: var(--bb-surface); box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.15); font-size: .85rem; }
.view-panel[hidden] { display: none; }
.view-row { display: flex; align-items: center; gap: .5rem; margin: .25rem 0; }
.view-row button { padding: .15rem .5rem; }
.view-row .view-size { font-family: 'Roboto Mono', monospace; font-size: .78rem; min-width: 4.2em; text-align: center; }

/* dark code: the editor, the console and the panels that belong to them. The page around them stays as it is. */
.bb-dark .CodeMirror-gutters { background: var(--bb-code-bg); border-right-color: var(--bb-border); }
.bb-dark .CodeMirror-linenumber { color: #6b7784; }
.bb-dark .CodeMirror-cursor { border-left-color: #e4e8ec; }
.bb-dark .CodeMirror-selected { background: #33405a; }
.bb-dark .CodeMirror-focused .CodeMirror-selected { background: #3c4c6b; }
.bb-dark .CodeMirror-activeline-background { background: #1b1f25; }
.bb-dark .cm-keyword { color: #d29ff0; }
.bb-dark .cm-string, .bb-dark .cm-string-2 { color: #a8e06a; }
.bb-dark .cm-number { color: #f5c777; }
.bb-dark .cm-comment { color: #7d8b99; }
.bb-dark .cm-def, .bb-dark .cm-builtin { color: #7cd3ff; }
.bb-dark .cm-variable, .bb-dark .cm-variable-2, .bb-dark .cm-variable-3, .bb-dark .cm-property, .bb-dark .cm-operator, .bb-dark .cm-punctuation { color: #dbe3ea; }
.bb-dark .cm-meta { color: #9fb2bf; }
.bb-dark .CodeMirror .running-line { background: rgba(122, 176, 63, .3); }
.bb-dark .console-in { caret-color: #a8e06a; }
.bb-dark .console-in:focus, .bb-dark .console-in:focus-visible { box-shadow: inset 0 -2px 0 #a8e06a; }
.bb-dark .cell-view .telemetry { text-shadow: 0 0 3px var(--bb-view-bg), 0 0 3px var(--bb-view-bg); }
.bb-dark .share-box .share-link { background: var(--bb-code-bg); color: var(--bb-dark); }
.bb-dark li.CodeMirror-hint-active { background: #33405a; color: #fff; }
.bb-dark li.CodeMirror-hint-active .h-doc, .bb-dark .CodeMirror-hint .h-doc { color: #9fb2bf; }
.bb-dark .CodeMirror-foldmarker, .bb-dark .CodeMirror-foldgutter-open, .bb-dark .CodeMirror-foldgutter-folded { color: #a8e06a; }

/* Share: the copied link, when the browser will not let the page reach the clipboard */
.share-box { display: flex; align-items: center; gap: .5rem; padding: .4rem .6rem; border-bottom: 1px solid var(--bb-border); background: var(--bb-soft); font-size: .82rem; }
.share-box label { font-weight: 700; }
.cell-view:has(.ref-panel), .cell-body:has(.ref-docked) { min-height: 24rem; }
.cell-body:has(.ref-docked) { position: relative; }
.ref-panel.ref-docked { left: auto; width: min(22rem, 100%); box-shadow: -6px 0 14px rgba(0, 0, 0, .12); }
.ref-panel { position: absolute; inset: 0; z-index: 30; display: flex; flex-direction: column; background: var(--bb-surface); color: var(--bb-dark); font-size: .82rem; border-left: 1px solid var(--bb-border); }
.ref-top { display: flex; gap: .4rem; padding: .45rem .5rem; border-bottom: 1px solid var(--bb-border); background: var(--bb-soft); }
.ref-search { flex: 1; min-width: 0; font: inherit; padding: .3rem .45rem; border: 1px solid var(--bb-border); border-radius: 5px; background: var(--bb-surface); color: var(--bb-dark); }
.ref-groups { flex: 1; overflow-y: auto; padding: .2rem .5rem .4rem; }
.ref-group { border-bottom: 1px solid var(--bb-border); }
.ref-group > summary { cursor: pointer; font-weight: 800; padding: .45rem 0; }
.ref-item { padding: .35rem 0 .5rem; border-top: 1px dashed var(--bb-border); }
.ref-item[hidden], .ref-group[hidden], .ref-none[hidden] { display: none; }
.ref-sig { font-family: 'Roboto Mono', monospace; font-weight: 500; font-size: .8rem; overflow-wrap: anywhere; }
.ref-doc { color: var(--bb-secondary); margin: .1rem 0 .3rem; }
.ref-ex { display: flex; align-items: flex-start; gap: .4rem; }
.ref-ex pre { flex: 1; min-width: 0; margin: 0; padding: .3rem .45rem; background: var(--bb-code-bg); border-radius: 5px; font-family: 'Roboto Mono', monospace; font-size: .76rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.ref-insert { flex: none; font-size: .76rem; padding: .25rem .5rem; }
.ref-none, .ref-more { margin: .4rem .5rem; color: var(--bb-secondary); }
.cell-view { position: relative; }
.cell-foot .handin[hidden] { display: none; }
.cell-foot .handed.returned { color: var(--bb-red-ink); font-weight: 700; }
.cell-head .icon[hidden] { display: none; }
.test-page .test-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem; }
.test-clock { font-family: 'Roboto Mono', monospace; font-size: 1.4rem; font-weight: 500; padding: .1rem .6rem; border-radius: 8px; background: var(--bb-light-bg); }
.test-clock.soon { background: var(--bb-red-bg); color: var(--bb-red-ink); }
.test-rules { color: var(--bb-secondary); margin: .2rem 0 1rem; }
.test-task { margin: 1.5rem 0; }
.test-task h2 { font-family: 'Varela Round', sans-serif; font-weight: 400; font-size: 1.25rem; margin: 0 0 .3rem; }
.class-test { margin: 0 0 1rem; padding: .7rem 1rem; border-radius: 10px; background: var(--bb-red-bg); color: var(--bb-red-ink); font-weight: 700; }
.class-test a { color: inherit; }
.cell-feedback { padding: .5rem .75rem .6rem; border-top: 1px solid var(--bb-border); background: var(--bb-note); font-size: .85rem; }
.cell-feedback[hidden] { display: none; }
.cell-feedback.returned { box-shadow: inset 4px 0 var(--bb-red-ink); }
.fb-head { display: flex; flex-wrap: wrap; gap: .2rem .5rem; align-items: baseline; }
.fb-when { color: var(--bb-secondary); font-size: .8rem; }
.fb-tag { font-size: .75rem; font-weight: 700; color: var(--bb-red-ink); }
.fb-note { margin: .3rem 0 0; white-space: pre-wrap; }
.fb-lines { list-style: none; margin: .4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.fb-lines li { display: flex; flex-wrap: wrap; gap: .2rem .45rem; align-items: baseline; }
.fb-go { font-family: 'Roboto Mono', monospace; font-size: .75rem; padding: .05rem .4rem; }
.fb-lines code { font-family: 'Roboto Mono', monospace; font-size: .76rem; background: var(--bb-chip); padding: 0 .3em; border-radius: 3px; }
.CodeMirror .feedback-line { background: rgba(253, 209, 77, .28); }
.feedback-widget { margin: .1rem 0 .3rem 1.2rem; padding: .25rem .5rem; border-left: 3px solid var(--bb-amber); background: var(--bb-note); color: var(--bb-dark); font-family: 'Nunito', system-ui, sans-serif; font-size: .8rem; white-space: pre-wrap; border-radius: 0 4px 4px 0; }
.cell-foot .handed { font-size: .8rem; color: var(--bb-secondary); }
.cell-foot .handed.late { color: var(--bb-red-ink); }
.saves-box { padding: .5rem .6rem; border-bottom: 1px solid var(--bb-border); background: var(--bb-soft); font-size: .82rem; }
.saves-row { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.saves-row label { font-weight: 700; }
.saves-row .spacer { flex: 1; }
.saves-box .save-name { flex: 1 1 10rem; min-width: 8rem; font: inherit; padding: .25rem .4rem; border: 1px solid var(--bb-border); border-radius: 5px; background: var(--bb-surface); color: var(--bb-dark); }
.saves-msg { margin: .3rem 0 0; min-height: 1em; color: var(--bb-secondary); }
.saves-msg:empty { display: none; }
.saves-list { list-style: none; margin: .4rem 0 0; padding: 0; max-height: 12rem; overflow-y: auto; }
.saves-list li { display: flex; align-items: center; gap: .5rem; padding: .25rem 0; border-top: 1px solid var(--bb-border); }
.saves-list .save-title { font-weight: 700; overflow-wrap: anywhere; }
.saves-list .save-when { flex: 1; color: var(--bb-secondary); font-size: .76rem; }
.saves-list li.same .save-title::before { content: "\2022  "; color: var(--bb-green-deep); }
.saves-empty, .saves-note { margin: .4rem 0 0; color: var(--bb-secondary); }
.share-box .share-link { flex: 1; min-width: 0; font-family: 'Roboto Mono', monospace; font-size: .75rem; padding: .25rem .4rem; border: 1px solid var(--bb-border); border-radius: 5px; background: var(--bb-surface); }

/* debug mode: the line that is running, the bar that steps through it, and values on hover */
.CodeMirror .running-line { background: rgba(122, 176, 63, .22); }
.debug-bar { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding: .4rem .6rem; border-top: 1px solid var(--bb-border); background: var(--bb-soft); font-size: .82rem; }
.debug-bar[hidden] { display: none; }      /* display: flex above would otherwise beat the browser's rule for hidden */
.debug-bar .dbg-at { font-weight: 700; }
.debug-bar .dbg-vars { font-family: 'Roboto Mono', monospace; font-size: .78rem; color: var(--bb-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.var-tip { position: fixed; z-index: 3000; max-width: 32rem; padding: .25rem .45rem; border-radius: 5px; background: #111; color: #fff; font-family: 'Roboto Mono', monospace; font-size: .78rem; pointer-events: none; white-space: pre; overflow: hidden; text-overflow: ellipsis; }

/* input(): the prompt and what is typed sit on the console line itself, as they would in any Python console */
.console-ask { display: inline; }
.console-in { font: inherit; color: inherit; background: transparent; border: 0; padding: 0; outline: none; width: 2ch; caret-color: var(--bb-green-deep); }
/* a box round it would not look like a console, so the focus shows as a line under what is being typed */
.console-in:focus, .console-in:focus-visible { outline: none; box-shadow: inset 0 -2px 0 var(--bb-green-deep); }

/* the legal footer under every page */
.site-foot { max-width: 1180px; margin: 0 auto; padding: 1.2rem 1.25rem 2rem; font-size: .78rem; color: var(--bb-secondary); border-top: 1px solid var(--bb-border); }
.site-foot a { color: inherit; }
body.embed .site-foot, body.expanded .site-foot { display: none; }

/* the teacher's own tasks */
.class-tasks .module-head { background: var(--bb-note); border-color: var(--bb-note-border); }
.class-task .crumb { color: var(--bb-secondary); font-size: .9rem; }
.class-task-cell { margin-top: 1rem; }

/* locked modules */
.module.locked .module-head { opacity: .55; }
.side-module.locked .side-module-title { opacity: .5; cursor: default; }

/* the class: the bar pill, the join dialog, the banner */
.classbar { display: flex; align-items: center; gap: .4rem; }
.classbar button { font: inherit; font-weight: 700; font-size: .8rem; padding: .25rem .7rem; border-radius: 999px; border: 1px solid var(--bb-dark); background: var(--bb-surface); color: var(--bb-dark); cursor: pointer; }
.classbar button.class-join { background: var(--bb-dark); color: var(--bb-cream); }
.classbar button:hover { background: var(--bb-sage); color: var(--bb-dark); }
.class-pill { font-size: .8rem; font-weight: 700; padding: .2rem .65rem; border-radius: 999px; background: var(--bb-surface); border: 1px solid var(--bb-border); }
.join-dialog { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.35); display: flex; align-items: center; justify-content: center; padding: 1rem; }
.join-privacy { margin: .4rem 0 0; font-size: .8rem; }
.join-school { display: grid; gap: .5rem; margin: .7rem 0 .2rem; }
.join-school button { width: 100%; font-weight: 700; }
.join-school[hidden], .join-go[hidden] { display: none; }
.join-label { display: block; font-size: .8rem; font-weight: 700; margin: .5rem 0 .15rem; }
.join-box { background: var(--bb-surface); border-radius: 12px; padding: 1.2rem 1.4rem; max-width: 380px; width: 100%; box-shadow: 0 .75rem 2rem rgba(0,0,0,.2); }
.join-box h3 { margin: 0 0 .4rem; font-family: 'Varela Round', sans-serif; font-weight: 400; }
.join-box p { margin: 0 0 .7rem; color: var(--bb-secondary); font-size: .9rem; }
.join-box input { display: block; width: 100%; font: inherit; padding: .45rem .6rem; border: 1px solid var(--bb-border); border-radius: 6px; margin: .35rem 0; }
.join-box .join-code { font-family: 'Roboto Mono', monospace; letter-spacing: .25em; text-transform: uppercase; font-weight: 700; }
.join-actions { display: flex; gap: .5rem; margin-top: .5rem; }
.join-actions button { font: inherit; font-weight: 700; padding: .4rem 1rem; border-radius: 6px; border: 1px solid var(--bb-green-dark); background: var(--bb-surface); cursor: pointer; }
.join-actions button.primary { background: var(--bb-green); border-color: var(--bb-green); color: var(--bb-on-green); }
.join-msg { min-height: 1.2em; color: var(--bb-red); font-size: .85rem; }
.class-banner { margin: .6rem 0 1rem; display: flex; flex-direction: column; gap: .4rem; }
.class-msg, .class-hint { border-radius: 10px; padding: .55rem .9rem; font-size: .95rem; border: 1px solid var(--bb-border); background: var(--bb-light-bg); }
.class-hint { background: var(--bb-note); border-color: var(--bb-note-border); }
.class-assign { border-radius: 10px; padding: .55rem .9rem; font-size: .95rem; border: 1px solid var(--bb-border); background: var(--bb-surface); }
.class-assign.done { background: var(--bb-light-bg); }
.class-assign.late { border-color: #e0b4b1; background: #fbeeed; }
.class-assign .assign-note { color: var(--bb-secondary); margin-top: .2rem; }
.class-assign .assign-links { display: flex; flex-wrap: wrap; gap: .3rem .8rem; margin-top: .35rem; font-size: .88rem; }
.progress-pill.assigned { background: var(--bb-note); border-color: var(--bb-note-border); margin-right: .4rem; }
.lesson-card.assigned { border-color: var(--bb-note-border); }
.class-banner .tag { font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--bb-secondary); margin-right: .5rem; }

/* notifications: bubbles in the corner that follow the student across pages until dismissed */
.toasts { position: fixed; top: 3.6rem; right: 1rem; z-index: 55; display: flex; flex-direction: column; gap: .5rem; width: min(360px, calc(100vw - 2rem)); pointer-events: none; }
.toast { pointer-events: auto; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem; align-items: start; background: var(--bb-surface); border: 1px solid var(--bb-border); border-left: 5px solid var(--bb-green-dark); border-radius: 10px; padding: .55rem .5rem .6rem .85rem; box-shadow: 0 .6rem 1.6rem rgba(0,0,0,.16); font-size: .93rem; animation: toast-in .2s ease-out; }
.toast.hint { border-left-color: var(--bb-amber); background: var(--bb-note); }
.toast.asg { border-left-color: #6f8544; }
.toast .tag { display: block; font-size: .7rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--bb-secondary); margin-bottom: .15rem; }
.toast-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.toast-link { display: inline-block; margin-top: .3rem; font-weight: 700; }
.toast-x { border: 0; background: transparent; font-size: 1rem; line-height: 1; padding: .2rem .45rem; color: var(--bb-secondary); cursor: pointer; }
.toast-x:hover { color: var(--bb-dark); background: var(--bb-light-bg); }
.toast.out { opacity: 0; transform: translateX(1rem); transition: opacity .18s, transform .18s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-.4rem); } to { opacity: 1; transform: none; } }
@media (max-width: 700px) { .toasts { top: auto; bottom: 4.6rem; right: .6rem; width: calc(100vw - 1.2rem); } }

/* the consent bar for analytics cookies */
.consent { position: fixed; left: 50%; bottom: 1rem; transform: translateX(-50%); z-index: 50; display: flex; align-items: center; gap: .6rem; max-width: calc(100% - 2rem); padding: .55rem .9rem; border-radius: 999px; background: #111; color: #fff; font-size: .85rem; box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.25); }
.consent button { font: inherit; font-weight: 700; font-size: .8rem; padding: .3rem .8rem; border-radius: 999px; border: 1px solid #fff; background: transparent; color: #fff; cursor: pointer; white-space: nowrap; }
.consent button.primary { background: var(--bb-green); border-color: var(--bb-green); color: var(--bb-on-green); }
@media (max-width: 600px) { .consent { flex-wrap: wrap; border-radius: 12px; left: .6rem; right: .6rem; transform: none; max-width: none; padding: .5rem .8rem; } .consent button { min-height: 40px; } }

/* the loading bar: a stripe that sweeps under the cell head while the simulator is working */
/* the track is always there, so nothing shifts when a run starts; it only sweeps while the page is waiting for
   Python to load and start. Once the robot is moving there is nothing left to wait for. */
.cell-progress { height: 4px; background: var(--bb-light-bg); position: relative; overflow: hidden; }
.cell-progress::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 0; border-radius: 2px; background: var(--bb-green-dark); }
.cell.loading .cell-progress::before { left: -40%; width: 40%; animation: cell-sweep 1.1s ease-in-out infinite; }
@keyframes cell-sweep { from { left: -40%; } to { left: 100%; } }
@media (prefers-reduced-motion: reduce) { .cell.loading .cell-progress::before { animation: none; left: 0; width: 100%; opacity: .6; } }
/* the head: the title with the buttons on its right, the task's description on its own line under it */
.cell-head { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) repeat(5, auto); align-items: center; column-gap: .35rem; row-gap: .15rem; padding: .45rem .75rem; background: var(--bb-sage); border-bottom: 1px solid var(--bb-border); font-size: .85rem; }
.cell-head .label { font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell-head .task-hint { color: var(--bb-ink-dim); grid-column: 1 / -1; grid-row: 2; min-width: 0; }
.cell-head .task-hint code { font-family: 'Roboto Mono', monospace; font-size: .92em; background: var(--bb-chip); padding: 0 .3em; border-radius: 3px; }
.cell-head .spacer { display: none; }
.cell-head .task-stdin { color: var(--bb-ink-dim); grid-column: 1 / -1; grid-row: 3; min-width: 0; }
.cell-head .task-stdin code { font-family: 'Roboto Mono', monospace; font-size: .92em; background: var(--bb-chip); padding: 0 .3em; border-radius: 3px; margin-right: .2em; }
.cell-head .task-stdin code.empty { font-style: italic; }
.cell-body { display: grid; grid-template-columns: minmax(0, 1fr) 6px 300px; }
.cell .CodeMirror { height: auto; min-height: 120px; font-family: 'Roboto Mono', monospace; font-size: var(--code-size); background: var(--bb-code-bg); color: var(--bb-dark); }
.cell .CodeMirror-scroll { min-height: 120px; max-height: 420px; }
.cell-view { position: relative; background: var(--bb-view-bg); border-left: 1px solid var(--bb-border); min-height: 220px; }
.cell-view canvas.view3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* the robot view is painted on the shared canvas, which sits above the page, so the readout lives in the
   top-left corner where the mat never reaches */
/* the sound switch floats on the 3D view, top right: one tap mutes the motors, bumps, chimes and the robot's own notes */
.cell-view .view-sound { position: absolute; z-index: 7; right: .5rem; top: .45rem; width: 2.1rem; height: 2.1rem; padding: 0; display: grid; place-items: center; border-radius: 50%;
  border: 1px solid rgba(0,0,0,.12); background: rgba(255,255,255,.78); backdrop-filter: blur(4px); box-shadow: 0 1px 4px rgba(0,0,0,.12); cursor: pointer; }
.cell-view .view-sound:hover { background: #fff; } .cell-view .view-sound:disabled { opacity: .5; cursor: not-allowed; }
.cell-view .view-sound[aria-pressed="false"] { background: rgba(255,255,255,.55); }
.bb-dark .cell-view .view-sound { background: rgba(27,31,37,.78); border-color: rgba(255,255,255,.16); color: var(--bb-dark); } .bb-dark .cell-view .view-sound:hover { background: #232a31; }
.cell-view .telemetry { position: absolute; z-index: 6; left: .5rem; top: .4rem; font-family: 'Roboto Mono', monospace; font-size: 11px; color: var(--bb-secondary); pointer-events: none; background: transparent; padding: 0; text-shadow: 0 0 3px #fff, 0 0 3px #fff; }
.cell-view .telemetry:empty { display: none; }
.cell-view .placeholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--bb-secondary); font-size: .85rem; }
.cell-head .icon, .cell-head .view-btn { display: inline-flex; align-items: center; justify-content: center; padding: .34rem; line-height: 0; }
.cell-head .view-btn { font-family: 'Roboto Mono', monospace; line-height: 1; min-width: 2rem; }
/* what just happened, said next to the icons: out of the grid, so it cannot push a button onto a second row */
.cell-head .share-said { position: absolute; z-index: 6; top: 100%; right: .6rem; margin-top: 3px; padding: .15rem .5rem; border-radius: 6px; background: #111; color: #fff; font-size: .75rem; font-weight: 700; white-space: nowrap; pointer-events: none; }
.cell--full .cell-head .expand { background: var(--bb-sage); }

/* full-screen cell: the whole cell element moves into a fixed overlay; the shared canvas is raised above it */
.overlay { position: absolute; left: 0; width: 100%; height: 100vh; background: var(--bb-cream); display: flex; flex-direction: column; }
.overlay-body { flex: 1; min-height: 0; display: flex; }
.cell.cell--full { flex: 1; display: flex; flex-direction: column; margin: 0; border: 0; border-radius: 0; box-shadow: none; min-height: 0; }
/* the file tabs scroll sideways (overflow), so as a flex item their minimum height is zero: without this a short
   screen squeezes the bar to a sliver and the tabs vanish */
.cell--full .file-bar { flex: none; }
.cell--full .cell-body { flex: 1; min-height: 0; grid-template-columns: minmax(0, 1fr) 6px minmax(0, 1fr); }
.cell--full .CodeMirror { height: 100%; font-size: calc(var(--code-size) + .06rem); }
.cell--full .CodeMirror-scroll { max-height: none; height: 100%; }
.cell--full .cell-view { min-height: 0; border-left: 1px solid var(--bb-border); border-top: 0; }
.cell--full .cell-view .telemetry { font-size: 14px; left: 1rem; top: .75rem; }
.cell--full .cell-lower { height: 22vh; min-height: 150px; }
/* the embed (an iframe on the main site): side by side down to phone width, a short console, no wasted height */
body.embed .cell--full .cell-body { grid-template-columns: minmax(0, 1fr) 6px minmax(0, 1fr); grid-template-rows: none; }
body.embed .cell--full .cell-lower { height: 118px; min-height: 90px; }
body.embed .cell--full .CodeMirror { font-size: calc(var(--code-size) + .03rem); }
body.embed .cell--full .cell-view { min-height: 0; }
body.embed .splitter { display: block; }     /* the 900px rule hides it, which would drop the robot view into the 6px column */
@media (max-width: 640px) { body.embed .cell--full .cell-body { grid-template-columns: 1fr !important; grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); } body.embed .splitter { display: none; } .cell-foot .best { display: none; }
  /* a phone-width embed is pinned to its frame like a lesson cell: code, robot, camera and depth, console, buttons,
     all inside the height the iframe gives it. Only the code and the console scroll, so a page with the embed on
     it has one scroll bar, the page's own. */
  body.embed { height: 100dvh; overflow: hidden; }
  body.embed .embed-wrap { height: 100dvh; min-height: 0; }
  body.embed .cell.cell--full { flex: 1 1 auto; height: auto; min-height: 0; overflow: hidden; }
  body.embed .cell--full .cell-body { flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr) minmax(0, 1fr) !important; }
  body.embed .cell--full .CodeMirror, body.embed .cell--full .CodeMirror-scroll { height: 100%; max-height: none; }
  body.embed .cell--full .cell-lower { height: auto !important; min-height: 0; flex: none; }
  body.embed .cell--full .cell-lower .cell-out { flex: none; height: 4.5rem; min-height: 0; max-height: none; overflow: auto; }
  body.embed .cell--full .cell-plot { height: 4.5rem; flex: none; }
  /* the code and the console still scroll with a finger, but without a scroll bar drawn over them */
  body.embed .CodeMirror-vscrollbar, body.embed .CodeMirror-hscrollbar, body.embed .CodeMirror-scrollbar-filler { display: none !important; }
  body.embed .cell-out { scrollbar-width: none; }
  body.embed .cell-out::-webkit-scrollbar { display: none; }
  /* the header wraps: the task title on its own line, then the buttons, so nothing runs off the edge */
  body.embed .cell--full .cell-head { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; padding: .45rem .6rem; }
  body.embed .cell--full .cell-head .label { order: 0; flex: 1 1 100%; white-space: normal; overflow: visible; }
  body.embed .cell--full .cell-head .task-hint, body.embed .cell--full .cell-head .task-stdin { order: 1; flex: 1 1 100%; }
  body.embed .cell--full .cell-head > :not(.label):not(.task-hint):not(.task-stdin) { order: 2; }
  body.embed .cell-head .embed-brand { margin-left: auto; padding-left: .25rem; }
  /* .view-wrap pushes itself right with an auto margin, which is for the site's top bar. In this wrapped row the brand
     has one too, so the two split the spare space and "Aa" is left stranded in the middle: here it sits with the
     other buttons, and only the brand goes right. The hint is the same height as the icon buttons beside it. */
  body.embed .cell--full .cell-head .view-wrap { margin-left: 0; }
  body.embed .cell--full .cell-head .hint-btn { min-height: 40px; padding: .2rem .8rem; }
  .cell--full .cell-view, body.embed .cell--full .cell-view { border-left: 0; border-top: 1px solid var(--bb-border); }
  .cell-view .telemetry, .cell--full .cell-view .telemetry { font-size: 9px; left: .35rem; top: .25rem; } }
/* a short frame (the tour's panel, a small iframe on someone's site): drop what can go, keep code, robot and Run */
@media (max-height: 560px) {
  body.embed .insets { display: none; }
  body.embed .cell-out { min-height: 2.6rem; max-height: 4rem; }
  body.embed .cell-lower, body.embed .cell--full .cell-lower { height: auto !important; min-height: 0; }
  body.embed .cell-foot { padding: .3rem .5rem; gap: .35rem; }
  body.embed .cell-foot .scrub, body.embed .cell-foot .best { display: none; }
}
@media (max-height: 420px) {
  body.embed .cell-out { min-height: 2rem; max-height: 2.6rem; }
  body.embed .cell-head .embed-brand { display: none; }
}

body.expanded { overflow: hidden; }
body.expanded .bar, body.expanded .side, body.expanded .drawer-toggle { visibility: hidden; }
@media (max-width: 900px) { .cell--full .cell-body { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; } .splitter { display: none; } }
.cell-foot { display: flex; align-items: center; gap: .6rem; padding: .45rem .75rem; border-top: 1px solid var(--bb-border); flex-wrap: wrap; }
button { font: inherit; font-weight: 700; font-size: .85rem; padding: .35rem .9rem; border-radius: 6px; border: 1px solid var(--bb-green-dark); background: var(--bb-surface); color: var(--bb-dark); cursor: pointer; }
button.primary { background: var(--bb-green); border-color: var(--bb-green); color: var(--bb-on-green); }
button:hover { background: var(--bb-sage); }
button:disabled { opacity: .5; cursor: default; }
.cell-foot .scrub { flex: 1; min-width: 80px; }
/* the console: always open with its own scrollbar, so running a program never resizes the robot view */
.cell-out { flex: 1; min-width: 0; min-height: 0; padding: .5rem .75rem; font-family: 'Roboto Mono', monospace; font-size: calc(var(--code-size) - .05rem); white-space: pre-wrap; background: var(--bb-code-bg); overflow: auto; }
.cell-out:empty::before { content: "console: what your program prints appears here"; color: var(--bb-placeholder); }
.cell-out .err { color: var(--bb-red); }
.cell-out .radio { color: var(--bb-secondary); margin-top: .4rem; }
.verdict { font-weight: 700; padding: .25rem .6rem; border-radius: 6px; font-size: .85rem; }
.verdict.pass { background: var(--bb-green); color: var(--bb-on-green); }
.verdict.fail { background: var(--bb-red-bg); color: var(--bb-red-ink); }
.best { font-size: .8rem; color: var(--bb-secondary); }

@media (max-width: 900px) {
  .lesson { grid-template-columns: 1fr; gap: .5rem; }
  .drawer-toggle { display: inline-block; align-self: start; margin: .25rem 0 .5rem; }
  .side { position: fixed; top: 0; left: 0; bottom: 0; align-self: stretch; height: 100dvh; overscroll-behavior: contain; width: min(320px, 85vw); max-height: none; background: var(--bb-surface); z-index: 26; padding: 1rem 1.25rem 2rem; box-shadow: .5rem 0 2rem rgba(0,0,0,.15); transform: translateX(-105%); transition: transform .18s ease; overflow: auto; }
  .side.open { transform: none; }
  .drawer-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 25; }
  .drawer-backdrop.open { display: block; }
  body.drawer-open { overflow: hidden; }
  .cell-body { grid-template-columns: 1fr; }
  .cell-view { border-left: 0; border-top: 1px solid var(--bb-border); min-height: 240px; }
  /* the links, the Aa button and a student's class badge do not all fit on one line here: let the bar wrap */
  .bar { flex-wrap: wrap; gap: .3rem 1rem; }
  .bar-links { gap: .8rem; }
  .status { display: none; }
}

/* phones: the bar wraps (a bar that cannot wrap makes the browser zoom the whole page out), and a cell stacks
   editor over robot view, then camera and depth, then the console. The drag handles set inline sizes, so !important. */
.burger { display: none; font-size: 1.3rem; line-height: 1; padding: .2rem .55rem; border: 1px solid var(--bb-dark); background: var(--bb-surface); color: var(--bb-dark); }
@media (max-width: 700px) {
  .bar { flex-wrap: wrap; gap: .4rem .7rem; padding: .4rem .8rem; }
  .brand .logo { height: 30px; }
  .burger { display: inline-flex; margin-left: auto; }
  .bar-links { display: none; order: 5; width: 100%; margin-left: 0; flex-direction: column; gap: .15rem; padding: .3rem 0 .2rem; font-size: .95rem; }
  .bar-links a { padding: .35rem .2rem; border-top: 1px solid rgba(0,0,0,.08); }
  .bar.menu-open .bar-links { display: flex; }
  .classbar { margin-left: 0; }
  .status { display: none; }
  .index { padding: 1.25rem .9rem 3rem; }
  .lesson { padding: .75rem .8rem 0; }
  .main { padding-bottom: 3rem; }
  .cell-body, .cell--full .cell-body, .cell.arena .cell-body { grid-template-columns: 1fr !important; grid-template-rows: auto minmax(170px, 28vh); }
  .cell--full .cell-body { grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); }
  .splitter, .hsplitter { display: none; }
  .cell-view, .cell.arena .cell-view { border-left: 0; border-top: 1px solid var(--bb-border); min-height: 0; }
  .cell .CodeMirror-scroll { max-height: 30vh; }
  .cell-lower, .cell--full .cell-lower { flex-direction: column; height: auto !important; min-height: 0; }
  /* one column on a phone: code, the robot, the camera and depth grid side by side, then the console under them.
     The console is what a program talks to you through, so it always has room of its own. */
  .cell-lower .insets { order: 1; border-left: 0; border-bottom: 1px solid var(--bb-border); border-top: 0; height: 6.5rem; flex-direction: row; justify-content: center; gap: .5rem; padding: .45rem; }
  .cell-lower .cell-out { order: 2; min-height: 4.5rem; max-height: 9rem; }
  .cell-plot { height: 5.75rem; }
  .cell-lower .cam-inset { height: 100%; width: auto; aspect-ratio: 4 / 3; }
  .cell-lower .tof-inset { height: 100%; width: auto; aspect-ratio: 1; }
  .cell-lower .inset-label { font-size: 10px; }
  /* tap targets a finger can hit (about 40px) */
  .burger { min-width: 44px; min-height: 44px; justify-content: center; align-items: center; }
  .classbar button { min-height: 40px; padding: .3rem .9rem; }
  .cell-head .icon, .cell-head .view-btn { min-width: 40px; min-height: 40px; }
  .cell-foot button { min-height: 40px; }
  .bar-links a { padding: .6rem .2rem; }
  .side a { padding: .5rem 0; }
  .side-module-title { min-height: 40px; }
  .lesson-nav a { display: inline-block; padding: .6rem 0; }
  .feedback .fb-open { min-height: 36px; }
  .cell-foot .scrub { height: 28px; }
  .cell-out { min-height: 4.5rem; max-height: 9rem; }
  .cell-head { padding: .4rem .6rem; }
  .cell-foot { gap: .45rem; padding: .4rem .6rem; }
  /* the buttons follow you down the cell, so Run is never below the fold while you are typing.
     overflow: hidden on the cell would stop sticky working, so the corners are rounded on the parts instead. */
  .cell { overflow: visible; }
  .cell .cell-head { border-radius: 11px 11px 0 0; }
  .cell .cell-foot { border-radius: 0 0 11px 11px; }
  .cell-foot { position: sticky; bottom: 0; z-index: 9; background: var(--bb-surface); box-shadow: 0 -.35rem .8rem rgba(0, 0, 0, .06); }
  .cell.task .cell-foot { border-top-color: var(--bb-green-dark); }
  body:not(.embed) .cell--full .cell-foot, body.expanded .cell-foot { position: static; box-shadow: none; }
  body.embed .cell--full .cell-foot { position: static; box-shadow: none; flex: none; }
  /* the verdict is the thing you came back for: keep it on its own line, readable */
  .cell-foot .verdict { flex-basis: 100%; order: 9; }
  .cell-foot .run { min-width: 6.5rem; }
}

/* a narrow window on a laptop is a phone as far as a cell is concerned */
@media (min-width: 701px) and (max-width: 900px) {
  .cell-body { grid-template-rows: auto minmax(180px, 30vh); }
  .cell .CodeMirror-scroll { max-height: 36vh; }
  .cell-lower { height: 118px; }
}

/* games */
/* the whole game card is the link */
.module.game .module-head { display: flex; border: 1px solid var(--bb-green-dark); border-radius: 12px; padding: 1rem 1.25rem; background: var(--bb-green); align-items: center; color: var(--bb-on-green); text-decoration: none; cursor: pointer; transition: box-shadow .15s, transform .15s; }
.module.game .module-head .num, .module.game .module-head p { color: var(--bb-on-green-dim); }
.module.game .module-head:hover, .module.game .module-head:focus-visible { box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .12); transform: translateY(-1px); }
.module.game .md-button { text-decoration: none; font-weight: 700; padding: .45rem 1.1rem; border-radius: 6px; background: var(--bb-green); color: var(--bb-on-green); border: 1px solid var(--bb-green); white-space: nowrap; }
.side-game { display: block; margin: .2rem 0 .6rem; font-weight: 700; }
.cell.arena .cell-body { grid-template-columns: minmax(0, 1fr) 6px minmax(0, 1fr); }
.cell.arena .cell-view { min-height: 320px; }
.leaderboard table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.leaderboard th, .leaderboard td { text-align: left; padding: .35rem .75rem; border-top: 1px solid var(--bb-border); }
.leaderboard thead th { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--bb-secondary); border-top: 0; }
.leaderboard tr.me td { background: rgba(162, 197, 148, .25); font-weight: 700; }
.leaderboard .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: .45rem; vertical-align: middle; }
@media (max-width: 900px) { .cell.arena .cell-body { grid-template-columns: 1fr; } }

/* rooms */
.room { border-top: 1px solid var(--bb-border); padding: .6rem .75rem .75rem; background: var(--bb-light-bg); }
.room-head { display: flex; align-items: center; gap: .75rem; margin-bottom: .5rem; }
.room-head .label { font-weight: 700; }
.room-status { font-size: .85rem; color: var(--bb-secondary); }
.room-status.ok { color: var(--bb-green-deep); }
.room-status.err { color: var(--bb-red); }
.room-join { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.room-join input { font: inherit; padding: .35rem .6rem; border: 1px solid var(--bb-border); border-radius: 6px; width: 10rem; }
.room-join .or { color: var(--bb-secondary); font-size: .85rem; }
.room-code-big { font-family: 'Roboto Mono', monospace; font-size: 1.6rem; letter-spacing: .25em; font-weight: 700; margin: .25rem 0 .5rem; }
.room-people { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; margin-bottom: .6rem; }
.room-people .person { background: var(--bb-surface); border: 1px solid var(--bb-border); border-radius: 999px; padding: .15rem .6rem; font-size: .85rem; }
.room-people .person.me { border-color: var(--bb-green-dark); background: var(--bb-green); color: var(--bb-on-green); }
.room-people .count { font-size: .8rem; color: var(--bb-secondary); }
.room-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.room-note { font-size: .8rem; color: var(--bb-secondary); margin-top: .4rem; }
.board-title { font-weight: 700; padding: .5rem .75rem 0; }
.room-join[hidden], .room-live[hidden] { display: none; }

/* in a room the practice buttons go away: the race is the room's */
.cell.arena.in-room .cell-foot .run, .cell.arena.in-room .cell-foot .bots-only { display: none; }

/* embed: one cell fills the page (used inside iframes on the main site) */
body.embed .bar { display: none; }
body.embed .app { padding: 0; max-width: none; }
body.embed .embed-wrap { height: 100vh; display: flex; flex-direction: column; }


/* full-page cells (embed and full screen): the task title on its own line, the hint under it, Reload on the right */
.cell--full .cell-head { display: grid; grid-template-columns: minmax(0, 1fr) repeat(9, auto); align-items: center; row-gap: .15rem; padding: .6rem 1rem; }
.cell--full .cell-head .label { font-size: 1rem; }
.cell--full .cell-head .task-hint, .cell--full .cell-head .spacer { grid-column: 1 / -1; grid-row: 2; }
.cell--full .cell-head .spacer { display: none; }
body.embed .cell--full .cell-body { grid-template-columns: minmax(0, 3fr) 6px minmax(0, 2fr); }
body.embed .cell--full .CodeMirror { font-size: calc(var(--code-size) + .03rem); }


/* the drag handle between code and robot view */
.splitter { position: relative; cursor: col-resize; background: var(--bb-border); touch-action: none; }
.splitter::after { content: ""; position: absolute; top: 0; bottom: 0; left: -6px; right: -6px; }   /* a wider grab zone than the 6 px line */
.splitter:hover, .splitter.active { background: var(--bb-green-dark); }
body.splitting { user-select: none; cursor: col-resize; }
.hsplitter { position: relative; height: 6px; cursor: row-resize; background: var(--bb-border); touch-action: none; }
.hsplitter::after { content: ""; position: absolute; left: 0; right: 0; top: -5px; bottom: -5px; }
.hsplitter:hover, .hsplitter.active { background: var(--bb-green-dark); }
body.splitting-v { user-select: none; cursor: row-resize; }



/* the lower row: the console on the left, the sensor views (camera with detections, depth grid) on the right.
   The camera view is rendered on the shared canvas into its rectangle; the detections are drawn over it. */
.cell-lower { display: flex; align-items: stretch; height: 150px; border-top: 1px solid var(--bb-border); }
/* the chart: only there once a program has called plot(), and it takes the full width under the console */
.cell-plot { height: 104px; border-top: 1px solid var(--bb-border); background: var(--bb-surface); }
.cell-plot canvas { display: block; width: 100%; height: 100%; }
.insets { display: flex; gap: .4rem; padding: .4rem; flex: none; order: 2; background: var(--bb-light-bg); border-left: 1px solid var(--bb-border); }   /* on the right of the console */
.cam-inset { position: relative; height: 100%; aspect-ratio: 4 / 3; border: 1px solid var(--bb-border); border-radius: 4px; overflow: hidden; background: var(--bb-cam-bg); }
.cam-inset canvas.cam3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cam-overlay { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.inset-label { position: absolute; z-index: 8; left: 4px; top: 2px; font: 600 10px 'Nunito', sans-serif; color: #fff; text-shadow: 0 0 3px rgba(0,0,0,.8); letter-spacing: .04em; text-transform: uppercase; pointer-events: none; }
.det { position: absolute; border: 2px solid #ffe14d; border-radius: 2px; box-sizing: border-box; }
.det span { position: absolute; left: 0; top: 100%; white-space: nowrap; font: 500 10px 'Roboto Mono', monospace; color: #fff; text-shadow: 0 0 3px rgba(0,0,0,.9); }
.det.blob { border-radius: 50%; border-color: #fff; }
.det.blob.red { border-color: #ff6b6b; } .det.blob.blue { border-color: #7aa7ff; } .det.blob.green { border-color: #7fe07f; } .det.blob.yellow { border-color: #ffe14d; }
.tof-inset { position: relative; height: 100%; aspect-ratio: 1; border: 1px solid var(--bb-border); border-radius: 4px; background: #444; overflow: hidden; }
.tof-cells { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr); gap: 1px; }
.tof-cells i { display: block; background: #555; }
@media (max-width: 900px) { .cell-lower { height: 120px; } }
.det.line { border-radius: 50%; border-color: #ff8c42; }

/* glossary: a term in the prose, and the one floating tooltip */
.gloss { border-bottom: 1px dashed var(--bb-green-deep); cursor: help; outline: none; }
.gloss:hover, .gloss:focus { background: rgba(162, 197, 148, .3); border-radius: 3px; }
#glosspop { position: fixed; z-index: 40; max-width: 360px; opacity: 0; visibility: hidden; transition: opacity .12s ease; pointer-events: none; background: var(--bb-surface); color: var(--bb-dark); border: 1px solid var(--bb-green-dark); border-radius: 10px; padding: .7rem .85rem; font-size: .88rem; line-height: 1.5; box-shadow: 0 .6rem 1.6rem rgba(0,0,0,.14); }
#glosspop.show { opacity: 1; visibility: visible; pointer-events: auto; }
#glosspop .gp-term { font-weight: 800; color: var(--bb-green-deep); margin-bottom: .2rem; }
#glosspop .gp-def { margin-bottom: .4rem; }
#glosspop .gp-link { display: inline-block; font-size: .8rem; font-weight: 700; text-decoration: none; }

/* feedback cards at the end of each part of a page */
.feedback { margin: .6rem 0 1.6rem; font-size: .85rem; }
.feedback .fb-open { font-size: .78rem; font-weight: 600; padding: .25rem .7rem; border-color: var(--bb-border); color: var(--bb-secondary); background: var(--bb-light-bg); }
.feedback .fb-open:hover { background: var(--bb-sage); color: var(--bb-dark); }
.feedback .fb-form { border: 1px solid var(--bb-green-dark); border-radius: 10px; padding: .7rem .9rem; background: var(--bb-light-bg); display: flex; flex-direction: column; gap: .5rem; max-width: 560px; }
.feedback .fb-form[hidden] { display: none; }
.feedback .fb-row { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.feedback .fb-q { font-weight: 700; }
.feedback label { display: inline-flex; align-items: center; gap: .3rem; }
.feedback .fb-text { font: inherit; font-size: .85rem; padding: .4rem .6rem; border: 1px solid var(--bb-border); border-radius: 6px; resize: vertical; }
.feedback .fb-note { color: var(--bb-secondary); }
.feedback .fb-thanks { color: var(--bb-green-deep); font-weight: 600; }

/* squiggles and the completion popup */
.CodeMirror-lint-mark-error { background-image: none; border-bottom: 2px wavy var(--bb-red); text-decoration: underline wavy var(--bb-red); }
.CodeMirror-lint-markers { width: 10px; }
.CodeMirror-lint-tooltip { font-family: 'Nunito', sans-serif; font-size: .85rem; border: 1px solid var(--bb-border); border-radius: 8px; background: var(--bb-surface); color: var(--bb-dark); box-shadow: 0 .35rem 1rem rgba(0,0,0,.12); }
.CodeMirror-hints { font-family: 'Roboto Mono', monospace; font-size: var(--code-size); border: 1px solid var(--bb-border); border-radius: 8px; background: var(--bb-surface); box-shadow: 0 .35rem 1rem rgba(0,0,0,.12); padding: .2rem 0; max-height: 16em; }
.CodeMirror-hint { padding: .15rem .6rem; display: flex; gap: .8rem; align-items: baseline; border-radius: 0; }
.CodeMirror-hint .h-sig { white-space: nowrap; }
.CodeMirror-hint .h-doc { font-family: 'Nunito', sans-serif; font-size: .78rem; color: var(--bb-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 34em; }
li.CodeMirror-hint-active { background: var(--bb-light-bg); color: var(--bb-dark); }
li.CodeMirror-hint-active .h-doc { color: var(--bb-dark); }

/* the fold arrows in the editor gutter */
.CodeMirror-linenumber { color: var(--bb-secondary); }
.bb-dark .CodeMirror-linenumber { color: #8a97a3; }
.CodeMirror-foldgutter { width: 1em; }
.CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: var(--bb-green-deep); cursor: pointer; }
.CodeMirror-foldmarker { color: var(--bb-green-deep); text-shadow: none; font-family: inherit; }

/* wrapped lines: the continuation of a long line (usually a comment) is dimmed a little */
.CodeMirror-wrap pre.CodeMirror-line { word-break: break-word; }

/* choosing a course: GCSE, robotics or (soon) A level. The chips filter the modules below them. */
.index .level { margin: 1rem 0 1.6rem; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.index .level-label { font-weight: 700; }
.index .level-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.index .level-chip { font: inherit; font-size: .85rem; font-weight: 700; padding: .35rem .85rem; border: 1px solid var(--bb-border); border-radius: 999px; background: var(--bb-surface); color: var(--bb-dark); cursor: pointer; }
.index .level-chip:hover { background: var(--bb-sage); }
.index .level-chip.on { background: var(--bb-dark); color: var(--bb-surface); border-color: var(--bb-dark); }
.index .level-chip.coming { opacity: .5; cursor: default; }
.index .level-chip.coming:hover { background: var(--bb-surface); }
.index .level-blurb { flex: 1 1 100%; margin: 0; font-size: .85rem; color: var(--bb-ink-dim); }

/* the overflow menu in a cell's header: everything that is not needed on every run */
.more-wrap { position: relative; display: inline-flex; }
.more-menu { position: absolute; right: 0; top: calc(100% + .3rem); z-index: 30; min-width: 15rem; padding: .25rem; border: 1px solid var(--bb-border); border-radius: 8px; background: var(--bb-surface); box-shadow: 0 6px 18px rgba(0, 0, 0, .14); }
.more-menu[hidden] { display: none; }
.more-menu .menu-item { display: flex; align-items: center; gap: .55rem; width: 100%; font: inherit; font-size: .85rem; text-align: left; padding: .4rem .5rem; border: 0; border-radius: 6px; background: transparent; color: var(--bb-dark); cursor: pointer; }
.more-menu .menu-item:hover, .more-menu .menu-item:focus { background: var(--bb-sage); outline: none; }
.more-menu .menu-item svg { flex: none; }

/* the hint is asked for, not given: the task is to work it out first */
.cell-head .hint-btn { font: inherit; font-size: .78rem; font-weight: 700; padding: .2rem .6rem; border: 1px solid var(--bb-border); border-radius: 999px; background: var(--bb-surface); color: var(--bb-dark); cursor: pointer; white-space: nowrap; }
.cell-head .hint-btn:hover { background: var(--bb-chip); }
.cell-head .task-hint[hidden] { display: none; }

/* Run turns into Stop while a program is running, so the same button starts and ends the run */
.cell-foot .run { display: inline-flex; align-items: center; gap: .4rem; }
.cell-foot .run.stopping { background: var(--bb-red-bg); border-color: var(--bb-red-ink); color: var(--bb-red-ink); }
.cell-foot .run svg { flex: none; }

/* once a cell has files, its editor keeps one height: swapping tabs must not move the page */
.cell.has-files:not(.cell--full) .CodeMirror { height: var(--file-editor-h); }
.cell.has-files:not(.cell--full) .CodeMirror-scroll { min-height: 0; max-height: none; height: 100%; }

/* an embed on another site: a quiet link back, in the corner of the cell's header */
.embed .cell-head .embed-brand { font-size: .75rem; color: var(--bb-ink-dim); text-decoration: none; white-space: nowrap; padding-left: .5rem; }
.embed .cell-head .embed-brand b { font-weight: 700; }
.embed .cell-head .embed-brand:hover { text-decoration: underline; }
.embed .cell-head .embed-brand span { opacity: .75; }
@media (max-width: 520px) { .embed .cell-head .embed-brand span { display: none; } }
