/* pytrainer.css — single-viewport app layout and panel styling.
   Injected by engine.js; the host page only provides the mount div. */

/* Minimal page reset so the app fills the viewport with no page scrolling.
   (When embedded in Hugo, the shortcode's page can override this.) */
html, body {
  height: 100%;
  margin: 0;
}

.pt-app {
  height: 100vh;
  height: 100dvh; /* mobile: exclude the browser's collapsing URL bar */
  display: grid;
  grid-template-columns: 1fr 320px;
  grid-template-rows: 1fr 190px;
  grid-template-areas:
    "editor  side"
    "console console";
  gap: 8px;
  padding: 8px;
  box-sizing: border-box;
  /* When the panes don't fit (phones, narrow windows) the whole view pans
     horizontally; panning inside a pane scroll-chains up to here, while the
     dividers (touch-action: none) still resize on drag. */
  overflow-x: auto;
  overflow-y: hidden;
  /* Divider drags change column widths while scrolled; scroll anchoring
     would adjust scrollLeft to visually cancel the resize. */
  overflow-anchor: none;
  background: #f2f3f5;
  color: #1d2129;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
}

/* With a course loaded, the runtime adds nav + lesson panels and switches
   the grid to four columns. Same single-viewport, no-page-scroll rule. */
.pt-app.pt-with-course {
  grid-template-columns: 230px 340px 1fr 300px;
  grid-template-areas:
    "nav     lesson  editor  side"
    "console console console console";
}

/* ---- pane dividers (created by ui.js; each sits in its own 8px grid
   column that replaces the column gap, so dragging one resizes the panes
   beside it) ---- */

.pt-divider {
  cursor: col-resize;
  touch-action: none;
  display: flex;
  align-items: stretch;
  justify-content: center;
}

.pt-divider::after {
  content: "";
  width: 2px;
  border-radius: 1px;
  background: #d5d9de;
}

.pt-divider:hover::after,
.pt-divider.pt-dragging::after {
  background: #7aa7e8;
}

/* Touch: an 8px bar is too thin a target, so extend the hit area over the
   neighboring panes (pseudo-element boxes hit-test as the divider itself;
   dividers are appended after the panes, so they win the overlap). */
@media (pointer: coarse) {
  .pt-divider {
    position: relative;
  }

  .pt-divider::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -14px;
    right: -14px;
    z-index: 1; /* beat the panes' own positioned content in the overlap */
  }
}

/* Short viewports (landscape phones): the fixed 190px console row would
   swallow most of the screen — give the top row the space instead. */
@media (max-height: 520px) {
  .pt-app {
    grid-template-rows: 1fr minmax(80px, 24dvh);
  }
}

/* ---- code pane: toolbar + editor ---- */

.pt-editor-pane {
  grid-area: editor;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pt-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  background: #fff;
  border: 1px solid #d5d9de;
  border-radius: 6px;
  /* Always a single row: when it doesn't fit, the row slides sideways.
     Contained so a swipe here doesn't pan the whole app. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

/* Groups and the status pill keep their natural width instead of being
   squeezed — overflow slides, it never shrinks or wraps. */
.pt-toolbar > * {
  flex-shrink: 0;
}

/* One button group: (Run, Stop), (Step mode, Next, Stop), (Restore). */
.pt-group {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px;
  background: #f1f3f5;
  border: 1px solid #e0e4e8;
  border-radius: 7px;
}

/* The group that owns the current activity: yellow while running or
   stepping, and on the Restore group while its inline query is open. */
.pt-group.pt-group-active {
  background: #fdeaa0;
  border-color: #dfc45a;
}

.pt-toolbar button {
  font: inherit;
  padding: 5px 12px;
  border: 1px solid #c2c8cf;
  border-radius: 5px;
  background: #fafbfc;
  cursor: pointer;
  white-space: nowrap;
}

.pt-toolbar button:hover:not(:disabled) {
  background: #eef1f4;
}

.pt-toolbar button:disabled {
  opacity: 0.45;
  cursor: default;
}

.pt-toolbar button.pt-active {
  background: #dbe9ff;
  border-color: #7aa7e8;
}

/* Inline restore query: gentle amber strip inside the Restore group. */
.pt-restore-confirm {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px 2px 8px;
  background: #fff8e1;
  border: 1px solid #ecd9a0;
  border-radius: 5px;
  font-size: 13px;
  color: #6b5615;
}

.pt-restore-confirm[hidden] {
  display: none;
}

.pt-restore-confirm button {
  padding: 2px 9px;
  font-size: 13px;
}

/* Settings group (gear, far right). Its controls unfold inline. */
.pt-settings-inline {
  display: inline-flex;
  align-items: center;
  padding: 0 4px;
  font-size: 13px;
  color: #3c4652;
}

.pt-settings-inline[hidden] {
  display: none;
}

.pt-settings-inline label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.pt-settings-inline input {
  width: 52px;
  font: inherit;
  font-size: 13px;
  padding: 2px 5px;
  border: 1px solid #c2c8cf;
  border-radius: 4px;
  background: #fff;
}

.pt-status {
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 13px;
  background: #e8eaed;
}

.pt-status::before {
  content: "●";
  margin-right: 6px;
}

.pt-status[data-state="loading"]::before  { color: #e6a817; }
.pt-status[data-state="ready"]::before    { color: #2e9e44; }
.pt-status[data-state="running"]::before  { color: #d97706; }
.pt-status[data-state="stepping"]::before { color: #2563eb; }
.pt-status[data-state="error"]::before    { color: #d32f2f; }

/* ---- editor ---- */

.pt-editor {
  flex: 1;
  min-height: 0;
  border: 1px solid #d5d9de;
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
}

.pt-editor .CodeMirror {
  height: 100%;
  font-family: "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;
  font-size: 14px;
}

.pt-editor .CodeMirror.pt-readonly {
  background: #f7f8f9;
}

/* Line about to execute in step mode. */
.pt-current-line {
  background: #fff1a8 !important;
}

/* ---- side panels ---- */

.pt-side {
  grid-area: side;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pt-panel {
  background: #fff;
  border: 1px solid #d5d9de;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.pt-vars { flex: 3; }
.pt-files { flex: 1; }

.pt-panel h2 {
  margin: 0;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #5b6470;
  background: #f6f7f8;
  border-bottom: 1px solid #e3e6ea;
}

/* The lesson panel's header is the path to the current step, with each
   segment a control that re-orients the outline. That needs to be readable
   and clickable, so it drops the uppercase micro-label treatment the other
   panel headers use. */
.pt-lesson-title {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  color: #3c4652;
}

.pt-crumb {
  font: inherit;
  color: #2c6cc4;
  background: none;
  border: 0;
  margin: 0;
  padding: 1px 4px;
  border-radius: 3px;
  cursor: pointer;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* When the pane is narrow the chapter gives up room first — the lesson is
   the more useful half of the path to keep readable. */
.pt-crumb { flex: 0 1 auto; min-width: 4ch; }
.pt-crumb:first-of-type { flex-shrink: 4; }

.pt-crumb:hover { background: #e6eefb; text-decoration: underline; }

.pt-crumb:focus-visible {
  outline: 2px solid #7aa7e8;
  outline-offset: 1px;
}

.pt-crumb-sep { flex: none; color: #98a2ad; }

.pt-vars-body {
  overflow: auto;
  padding: 6px 8px;
  flex: 1;
}

.pt-vars-section + .pt-vars-section {
  margin-top: 10px;
}

.pt-vars-title {
  font-size: 11px;
  font-weight: 600;
  color: #7a828d;
  margin-bottom: 3px;
}

/* Locals of the current frame, distinguished from globals. */
.pt-vars-locals {
  background: #eef5ff;
  border: 1px solid #cfe0f7;
  border-radius: 5px;
  padding: 5px 7px;
}

.pt-vars-locals .pt-vars-title {
  color: #2b5aa0;
}

.pt-vars-body table {
  width: 100%;
  border-collapse: collapse;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
}

.pt-vars-body td {
  padding: 2px 6px 2px 0;
  vertical-align: top;
  border-bottom: 1px solid #f0f2f4;
}

.pt-var-name {
  color: #8a4baf;
  white-space: nowrap;
}

.pt-var-value {
  color: #1d2129;
  word-break: break-all;
  width: 100%;
}

.pt-files-body {
  margin: 0;
  padding: 6px 10px;
  overflow: auto;
  list-style: none;
  flex: 1;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
}

.pt-files-body li {
  padding: 2px 0;
}

.pt-files-body li::before {
  content: "📄 ";
}

.pt-empty {
  color: #9aa1ab;
  font-style: italic;
  font-size: 13px;
}

/* ---- course navigation panel ---- */

.pt-nav { grid-area: nav; }

.pt-nav-body {
  overflow: auto;
  flex: 1;
  padding: 8px 10px;
  font-size: 13px;
}

/* The outline is a browser: expanded/collapsed is a viewing preference,
   independent of which lesson is current. "You are here" is a quiet left
   stripe (.pt-here) carried by the deepest row still visible on the path
   to the current step, so collapsing hands it up rather than losing it. */

.pt-nav-twisty {
  display: inline-block;
  width: 14px;
  flex: none;
  color: #98a2ad;
  font-size: 10px;
  line-height: inherit;
  text-align: center;
  user-select: none;
}

/* The lesson twisty is a real button: its own hit target, so it can
   expand without selecting. */
.pt-nav-twisty-btn {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: inherit;
}

.pt-nav-twisty-btn:hover { color: #3c4652; }

.pt-nav-twisty-btn:focus-visible {
  outline: 2px solid #7aa7e8;
  outline-offset: 1px;
  border-radius: 3px;
}

.pt-nav-chapter {
  display: flex;
  align-items: center;
  gap: 2px;
  font-weight: 700;
  color: #3c4652;
  margin: 10px 0 2px;
  padding: 3px 6px 3px 2px;
  border-left: 2px solid transparent;
  border-radius: 4px;
  cursor: pointer;
}

.pt-nav-chapter:first-child { margin-top: 0; }
.pt-nav-chapter:hover { background: #eef1f4; }

.pt-nav-chapter:focus-visible {
  outline: 2px solid #7aa7e8;
  outline-offset: -2px;
}

.pt-nav-chapter-title { flex: 1; min-width: 0; }

.pt-nav-count {
  flex: none;
  font-weight: 400;
  font-size: 11px;
  color: #98a2ad;
  font-variant-numeric: tabular-nums;
}

.pt-nav-lessons {
  list-style: none;
  margin: 0 0 4px;
  padding: 0 0 0 8px;
}

.pt-nav-lesson-row {
  display: flex;
  align-items: baseline;
  gap: 2px;
  padding: 3px 6px 3px 2px;
  border-left: 2px solid transparent;
  border-radius: 4px;
}

.pt-nav-lesson-label {
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.pt-nav-lesson-row:hover { background: #f4f6f8; }
.pt-nav-lesson-label:hover { text-decoration: underline; }

.pt-nav-badge {
  flex: none;
  font-size: 11px;
  color: #5b6470;
  font-variant-numeric: tabular-nums;
}

/* Outline numbering (courses that set `numberedOutline`). The digits are a
   column the eye runs down, so they stay quiet and tabular instead of
   thickening the title they sit beside. */
.pt-nav-num {
  margin-right: 0.45em;
  color: #98a2ad;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

/* Quiet position marker — not a filled block. */
.pt-here {
  border-left-color: #4b8ee0;
  background: #f2f6fc;
}

/* Reveal from the breadcrumb: a brief pulse so the eye catches the row. */
@keyframes pt-flash {
  0%, 100% { background: transparent; }
  25%      { background: #ffe9a8; }
}

.pt-flash { animation: pt-flash 1.1s ease-in-out 1; }

@media (prefers-reduced-motion: reduce) {
  .pt-flash { animation-duration: 0.01s; }
}

.pt-nav-steps {
  list-style: none;
  margin: 2px 0 4px;
  padding: 0 0 0 14px;
}

.pt-nav-step {
  padding: 2px 6px;
  border-radius: 4px;
  color: #5b6470;
  cursor: pointer;
}

.pt-nav-step:hover { background: #eef1f4; }

.pt-nav-step.pt-current {
  color: #1d2129;
  font-weight: 600;
  background: #eaf1fc;
}

/* Progress ✓ marks: the same success green as the Check button/result,
   so a passed step/lesson is visible at a glance in the nav. */
.pt-nav-mark {
  color: #1d6b2a;
  font-weight: 700;
}

/* Reset options at the foot of the nav (mirrors LxTrainer's block). */
.pt-danger {
  flex: none;
  border-top: 1px solid #e3e6ea;
  padding: 6px 10px;
  font-size: 12px;
  color: #7a828d;
}

.pt-danger summary { cursor: pointer; }

.pt-danger button {
  display: block;
  margin: 6px 0;
  font: inherit;
  font-size: 12px;
  padding: 4px 10px;
  border: 1px solid #c2c8cf;
  border-radius: 5px;
  background: #fafbfc;
  cursor: pointer;
}

.pt-danger button:hover { background: #eef1f4; }

/* ---- lesson text panel ---- */

.pt-lesson { grid-area: lesson; }

.pt-lesson-text {
  flex: 1;
  overflow-y: auto;     /* the text scrolls; the page never does */
  padding: 10px 14px;
  line-height: 1.5;
}

.pt-lesson-text h1, .pt-lesson-text h2, .pt-lesson-text h3 {
  margin: 0.3em 0 0.5em;
  font-size: 16px;
}

.pt-lesson-text p { margin: 0.6em 0; }

.pt-lesson-text code {
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: #eef1f4;
  padding: 1px 4px;
  border-radius: 3px;
}

.pt-lesson-text pre {
  background: #f4f5f7;
  border: 1px solid #e3e6ea;
  border-radius: 5px;
  padding: 8px 10px;
  overflow-x: auto;
}

.pt-lesson-text pre code {
  background: none;
  padding: 0;
}

.pt-lesson-foot {
  border-top: 1px solid #e3e6ea;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pt-step-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pt-step-controls button {
  font: inherit;
  padding: 4px 10px;
  border: 1px solid #c2c8cf;
  border-radius: 5px;
  background: #fafbfc;
  cursor: pointer;
}

.pt-step-controls button:hover:not(:disabled) { background: #eef1f4; }
.pt-step-controls button:disabled { opacity: 0.45; cursor: default; }

.pt-step-pos {
  font-size: 12px;
  color: #7a828d;
  white-space: nowrap;
}

.pt-check-btn {
  margin-left: auto;
  background: #2e7d32 !important;
  border-color: #2e7d32 !important;
  color: #fff;
  font-weight: 600;
}

.pt-check-btn:hover:not(:disabled) { background: #256b29 !important; }

/* ---- check result + hint ---- */

.pt-check-result {
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 13px;
}

.pt-check-result pre {
  margin: 6px 0 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px;
}

.pt-check-result.pt-pass {
  background: #e6f6e8;
  border: 1px solid #79c284;
  color: #1d6b2a;
}

.pt-check-result.pt-fail {
  background: #fdecea;
  border: 1px solid #f2a49e;
  color: #a8352a;
}

.pt-hint summary {
  cursor: pointer;
  color: #2563eb;
  font-size: 13px;
}

.pt-hint-text {
  margin-top: 6px;
  padding: 6px 10px;
  background: #fff8e1;
  border: 1px solid #ecd9a0;
  border-radius: 5px;
  font-size: 13px;
}

.pt-hint-text p { margin: 0.3em 0; }

.pt-hint-text code {
  font-family: "SF Mono", Menlo, Consolas, monospace;
  background: #f2ecd9;
  padding: 1px 4px;
  border-radius: 3px;
}

/* ---- course load error ---- */

.pt-course-error {
  max-width: 640px;
  margin: 12vh auto;
  padding: 20px 24px;
  background: #fff;
  border: 1px solid #f2a49e;
  border-radius: 8px;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.pt-course-error h2 {
  margin: 0 0 10px;
  color: #a8352a;
  font-size: 18px;
}

.pt-course-error pre {
  background: #fdecea;
  border-radius: 5px;
  padding: 10px 12px;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 13px;
}

/* ---- console ---- */

.pt-console {
  grid-area: console;
  margin: 0;
  padding: 8px 10px;
  overflow-y: auto;
  background: #14181d;
  color: #d8dde3;
  border-radius: 6px;
  font-family: "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;
  font-size: 13px;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}

.pt-out-stdout { color: #d8dde3; }
.pt-out-stderr { color: #ff6b6b; }   /* exceptions / stderr in red */
.pt-out-info   { color: #6f7a86; font-style: italic; }

/* Standing course-wide banner at the top of the nav pane, from the course
   file's optional `notice`. Yellow so it reads as a caveat, not chrome.
   No `display` property here on purpose: the element carries the `hidden`
   attribute when there is no notice, and a display rule would override it. */
.pt-nav-notice {
  margin: 0;
  padding: 7px 10px;
  flex: none;
  font-size: 12px;
  line-height: 1.4;
  font-weight: 600;
  color: #6b5200;
  background: #fff3bf;
  border-bottom: 1px solid #ecd77a;
}

/* ---- narrow screens ----------------------------------------------------

   Below the breakpoint in ui.js the panes stack into one column and the page
   scrolls, instead of the four-pane grid panning sideways off a phone. Same
   breakpoint and same reasoning as RefTrainer: this is as much about 200-400%
   browser zoom as about phones (WCAG 1.4.10 Reflow).

   Python still runs here — Pyodide is WebAssembly, not a virtual machine —
   and most steps ship with their code already written, so Run and Step mode
   work without typing on a touch keyboard.

   ui.js clears the inline grid-template-columns/areas below this width;
   inline styles would otherwise beat everything in this block. */
@media (max-width: 859px) {
  .pt-app,
  .pt-app.pt-with-course {
    height: auto;
    min-height: 100dvh;
    /* One column: everything stacks, full width, and the page scrolls in
       ONE direction only. Two side-by-side columns were tried and dropped —
       at phone width each was ~190px, and turning the pair into a swiped
       strip would have meant scrolling in two dimensions with a whole pane
       hidden off-screen, which is the thing WCAG 1.4.10 Reflow exists to
       prevent.

       minmax(0, 1fr), not 1fr: a plain 1fr is minmax(AUTO, 1fr), and that
       auto floor stops a track shrinking below its content's min-content
       width — so one long token in the console or the editor would widen
       the column and push the page sideways anyway. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-template-areas: none;
    overflow-x: hidden;
    overflow-y: visible;
    gap: 8px;
  }
  /* Nothing to drag when the panes are stacked. */
  .pt-divider { display: none; }
  /* Every pane carries a named grid-area (some inline, from ui.js). With the
     template areas gone those names resolve to lines that do not exist and
     the grid invents implicit COLUMNS for them — rebuilding the side-by-side
     layout. Hence auto, and hence !important for the inline ones. */
  .pt-nav, .pt-lesson, .pt-editor-pane, .pt-side, .pt-console, .pt-divider {
    grid-area: auto !important;
    /* Same reason as the track floor above: a grid item defaults to
       min-width:auto, which is min-content, and refuses to shrink. */
    min-width: 0;
  }
  /* Long output lines scroll inside the console rather than widening it. */
  .pt-console { overflow-x: auto; }
  /* The toolbar is a single sliding row on a desktop, which hides controls
     behind a horizontal scroll on a phone — the buttons ARE the interface
     here, so they wrap onto as many rows as they need instead. Groups stay
     intact when they can, and may wrap internally if one is wider than the
     screen on its own. */
  .pt-toolbar {
    flex-wrap: wrap;
    overflow-x: visible;
    row-gap: 6px;
  }
  .pt-group { flex-wrap: wrap; }
  /* DOM order is editor, side, console, nav, lesson — not the reading order
     a student wants, so it is set explicitly: outline, lesson, code, the
     results of running it, then the variables. Code and its output stay
     adjacent, one above the other rather than side by side. */
  .pt-nav         { order: 1; max-height: 38vh; }
  .pt-lesson      { order: 2; }
  .pt-editor-pane { order: 3; min-height: 40vh; }
  .pt-console     { order: 4; min-height: 18vh; max-height: 40vh; }
  .pt-side        { order: 5; }
}
