/* «Python im Browser»: editor, run controls, results, submissions.
 * Uses the tokens of style.css. */

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ------------------------------------------------------------------ editor */
.code-editor { --ce-lh: 1.55; --ce-fs: .86rem; display: flex; position: relative; border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); background: var(--bg-code); overflow: hidden; min-width: 0; }
.code-editor:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.ce-gutter { flex: none; margin: 0; padding: .75rem .45rem .75rem .6rem; text-align: right; white-space: pre;
  font-family: var(--mono); font-size: var(--ce-fs); line-height: var(--ce-lh); color: var(--ink-faint);
  background: var(--bg-inset); border-right: 1px solid var(--line); user-select: none; min-width: 2.4em; }
.ce-gutter .ce-err { color: var(--bad); font-weight: 700; }
/* the error line: a red mark and a tinted band across the gutter, not only a red number */
.code-editor.has-err .ce-gutter {
  --ce-y: calc(.75rem + (var(--ce-err) - 1) * var(--ce-lh) * var(--ce-fs)); --ce-h: calc(var(--ce-lh) * var(--ce-fs));
  background: linear-gradient(var(--bad), var(--bad)) 0 var(--ce-y) / 3px var(--ce-h) no-repeat,
    linear-gradient(var(--bad-bg), var(--bad-bg)) 0 var(--ce-y) / 100% var(--ce-h) no-repeat, var(--bg-inset); }
.ce-area { position: relative; flex: 1; min-width: 0; overflow-x: auto; overflow-y: hidden; }
.ce-inner { position: relative; display: inline-block; min-width: 100%; vertical-align: top; }
/* .code-editor in front: inside a lesson's code block «.code pre» must not change
   the highlight's font, size or overflow, or the caret drifts away from the text */
.code-editor .ce-hl, .code-editor .ce-input { margin: 0; padding: .75rem .95rem; font-family: var(--mono); font-size: var(--ce-fs);
  line-height: var(--ce-lh); tab-size: 4; white-space: pre; letter-spacing: 0; word-spacing: 0;
  font-variant-ligatures: none; font-kerning: none; }
.code-editor .ce-hl { pointer-events: none; color: var(--ink); background: transparent; overflow: visible;
  min-height: calc(var(--ce-lines, 6) * var(--ce-lh) * var(--ce-fs) + 1.5rem); }
.ce-hl code { font: inherit; }
/* weight and slant change glyph widths in some fonts: keep the overlay exactly aligned */
.ce-hl .py-kw, .ce-hl .py-fn, .ce-hl .py-com { font-weight: inherit; font-style: normal; }
.ce-input { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; outline: 0; resize: none;
  overflow: hidden; background: transparent; color: transparent; caret-color: var(--ink);
  -webkit-text-fill-color: transparent; }
.ce-input::selection { background: var(--accent-ring); -webkit-text-fill-color: transparent; }
@media (max-width: 600px), (hover: none) and (pointer: coarse) {
  /* 16 px keeps iOS from zooming into the field (also on a phone turned sideways) */
  .code-editor { --ce-fs: 16px; }
}

/* ------------------------------------------------------------- run panel */
.py-runner { margin: .9rem 0 .4rem; }
.py-runner-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .8rem; margin-bottom: .45rem; }
.py-runner-title { font-weight: 650; font-size: var(--t-sm); color: var(--ink); }
.py-bar { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; margin-top: .6rem; }
.py-bar .btn { min-width: 0; }
.py-runner [hidden], .code-live [hidden] { display: none !important; }
.py-kbd { font-size: var(--t-xs); color: var(--ink-faint); }
.py-status { display: inline-flex; align-items: center; gap: .4rem; font-size: var(--t-xs); color: var(--ink-faint); min-height: 1.5em; }
.py-dot { width: .55rem; height: .55rem; border-radius: 50%; background: var(--line-strong); flex: none; }
.py-status[data-state="ready"] .py-dot { background: var(--good); }
.py-status[data-state="loading"] .py-dot, .py-status[data-state="busy"] .py-dot { background: var(--warn); animation: py-pulse 1s ease-in-out infinite; }
.py-status[data-state="failed"] .py-dot { background: var(--bad); }
/* the reason may name a long URL: it wraps instead of widening the page */
.py-status[data-state="failed"] { color: var(--bad); overflow-wrap: anywhere; }
@keyframes py-pulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .py-dot { animation: none !important; } }
.py-note { font-size: var(--t-xs); color: var(--ink-faint); margin: .45rem 0 0; line-height: 1.45; }

.py-out { margin-top: .7rem; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); overflow: hidden; }
.py-out[hidden] { display: none; }
.py-out-head { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .6rem; padding: .45rem .75rem;
  border-bottom: 1px solid var(--line); font-size: var(--t-sm); }
.py-verdict { font-weight: 700; }
.py-verdict.is-ok { color: var(--good); }
.py-verdict.is-bad { color: var(--bad); }
.py-verdict.is-part { color: var(--warn); }
.py-time { margin-left: auto; font-size: var(--t-xs); color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.py-meter { flex-basis: 100%; height: .35rem; border-radius: 99px; background: var(--bg-sunken); overflow: hidden; }
.py-meter > span { display: block; height: 100%; background: var(--good); }
.py-section { padding: .5rem .75rem; }
.py-section + .py-section { border-top: 1px solid var(--line); }
.py-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); margin: 0 0 .25rem; }
.py-out pre { margin: 0; font-size: .8rem; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 22rem; overflow-y: auto; }
.py-error pre { color: var(--bad); }
.py-checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.py-check { display: grid; grid-template-columns: 1.2rem 1fr; gap: .1rem .4rem; font-size: var(--t-sm); align-items: start; }
.py-check-mark { font-weight: 700; text-align: center; }
.py-check.is-ok .py-check-mark { color: var(--good); }
.py-check.is-bad .py-check-mark { color: var(--bad); }
.py-check.is-skip { color: var(--ink-faint); }
.py-check-src { font-family: var(--mono); font-size: .76rem; color: var(--ink-soft); overflow-wrap: anywhere; }
/* monospace: numpy lines up ACTUAL and DESIRED column by column */
.py-check-msg { grid-column: 2; white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--mono); font-size: .76rem;
  line-height: 1.5; color: var(--ink); }
.py-check details { grid-column: 2; }
.py-check summary { cursor: pointer; font-size: var(--t-xs); color: var(--ink-faint); }
.py-figs { display: grid; gap: .5rem; }
.py-figs img { max-width: 100%; height: auto; border-radius: var(--r-xs); background: #fff; }

/* -------------------------------------------------------- submissions */
.py-history { margin-top: .7rem; font-size: var(--t-sm); }
.py-history > summary { cursor: pointer; color: var(--ink-soft); font-weight: 600; }
.py-history ol { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .3rem; }
.py-sub { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .6rem; padding: .35rem .55rem;
  border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--bg-inset); }
.py-sub-when { color: var(--ink-faint); font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
.py-sub-acts { display: flex; gap: .4rem; margin-left: auto; }
.py-badge { display: inline-block; padding: .05rem .45rem; border-radius: 99px; font-size: var(--t-xs); font-weight: 650;
  font-variant-numeric: tabular-nums; border: 1px solid transparent; }
.py-badge.is-ok { background: var(--good-bg); color: var(--good); border-color: var(--good-line); }
.py-badge.is-part { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-line); }
.py-badge.is-bad { background: var(--bad-bg); color: var(--bad); border-color: var(--bad-line); }
.py-badge.is-run { background: var(--bg-sunken); color: var(--ink-soft); border-color: var(--line); }
.py-sub-code { flex-basis: 100%; }
.py-sub-code pre { margin: .3rem 0 0; padding: .5rem .7rem; font-size: .78rem; max-height: 18rem; overflow: auto;
  background: var(--bg-code); border: 1px solid var(--line); border-radius: var(--r-xs); }

/* ------------------------------------------------- lesson code blocks */
.code-run { border: 1px solid var(--accent); background: var(--accent-soft); color: var(--accent-text); border-radius: 5px;
  font-size: .7rem; font-weight: 650; padding: .12rem .55rem; cursor: pointer; }
.code-run:hover { background: var(--accent); color: var(--bg-raised); }
.code-run:disabled { opacity: .6; cursor: progress; }
.code-run.is-running { border-color: var(--bad-line); background: var(--bad-bg); color: var(--bad); }
.code-run.is-running:hover { background: var(--bad); color: var(--bg-raised); }
/* a narrow screen: the title keeps the first line, the buttons move to the
   second as a group (instead of the title squeezed into a column beside them) */
.code-head.has-run { flex-wrap: wrap; row-gap: .3rem; }
.code-head.has-run .code-title { min-width: min(13rem, 100%); }
.code-acts { display: flex; align-items: center; gap: .5rem; margin-left: auto; }
.code-edit { border: 1px solid var(--line); background: var(--bg-raised); color: var(--ink-soft); border-radius: 5px;
  font-size: .7rem; padding: .12rem .5rem; cursor: pointer; }
.code-edit[aria-pressed="true"] { border-color: var(--accent); color: var(--accent-text); }
.code .code-editor { border: 0; border-radius: 0; }
/* an outline, drawn over the gutter too (a shadow would lie under it), in the full accent colour (≥ 3 : 1) */
.code .code-editor:focus-within { box-shadow: none; outline: 2px solid var(--accent); outline-offset: -2px; }
.code-live { margin: -.2em 0 1.1em; }
.code-live .py-out { margin-top: 0; }

/* ---------------------------------------------------------- progress */
.lr-subs { display: block; font-size: var(--t-xs); color: var(--ink-faint); margin-top: .1rem; }
.py-progress-subs { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.py-progress-subs li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .6rem; font-size: var(--t-sm); }
.py-progress-subs a { flex: 1 1 14rem; min-width: 0; overflow-wrap: anywhere; }
/* narrow: badge and title share the first line, time and chapter the second — for every badge width */
@media (max-width: 600px) {
  .py-progress-subs a { flex-basis: 0; }
  .py-progress-subs .py-sub-when { flex-basis: 100%; }
}

@media print {
  .py-bar, .py-status, .py-note, .code-run, .code-edit, .py-sub-acts { display: none !important; }
  /* paper does not scroll: the code wraps (without line numbers, which would no longer match) */
  .ce-gutter, .ce-input { display: none; }
  .code-editor .ce-hl { white-space: pre-wrap; overflow-wrap: anywhere; min-height: 0; }
  .py-out pre, .py-sub-code pre { max-height: none; overflow: visible; }
}
