/* PyPath — lesson progress chip and the soft unit lock notice. */

.lesson-progress-chip {
  display: inline-block;
  margin: 4px 0 12px;
  padding: 4px 12px;
  border: 1px solid var(--border, #cfe3f2);
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted, #5b7c92);
  background: var(--surface, #f4f9fd);
}

.lesson-progress-chip.is-complete {
  color: #0b6b3a;
  border-color: #9ad3b4;
  background: #e8f7ef;
}

:root[data-theme="dark"] .lesson-progress-chip.is-complete,
:root:not([data-theme="light"]) .lesson-progress-chip.is-complete {
  color: #7ee2ab;
  border-color: #1f6b45;
  background: rgba(16, 78, 51, 0.35);
}

/* These notices are injected as direct children of <main>, outside the page's
   .container, so they used to run edge to edge with the text jammed against
   the window. The wrapper below borrows the same gutters as lesson content,
   and each notice is capped at a readable measure inside them. */
.main-notice-wrap {
  box-sizing: border-box;
  width: 100%;
  padding-left: clamp(1.5rem, 4.5vw, 3.5rem);
  padding-right: clamp(1.5rem, 4.5vw, 3.5rem);
}

@media (min-width: 1400px) {
  .main-notice-wrap {
    padding-left: clamp(2rem, 5vw, 4rem);
    padding-right: clamp(2rem, 5vw, 4rem);
  }
}

/* On a lesson page the wrapper has to agree with the lesson grid exactly.
   It never did: above 981px .page-unit .layout-course uses
   clamp(1.5rem, 3.5vw, 4rem) and gets a max-width and auto margins, while the
   wrapper used its own gutter -- 50.4px against 64px at a 1440px window. That
   was invisible while these notices were narrow boxes floating in the corner.
   Now that they span the page, a 14px disagreement reads as a misaligned bar,
   so the wrapper borrows the grid's own numbers rather than approximating
   them. Kept beside the rule it mirrors: change one and change both. */
@media (min-width: 981px) {
  .page-unit .main-notice-wrap {
    max-width: 2000px;
    margin-inline: auto;
    padding-inline: clamp(1.5rem, 3.5vw, 4rem);
  }
}

@media (max-width: 980px) {
  /* And the narrow layout's 1rem, for the same reason. */
  .page-unit .main-notice-wrap { padding-inline: 1rem; }
}

/* ------------------------------------------------------------- lock screen
   What a locked unit shows instead of its lesson.

   Not a banner. On a lesson page this IS the page, so it is built to fill the
   column the lesson would have filled: a centred card on a soft, blurred
   backdrop, with the lock as the first thing read.

   The blur behind the card is decorative and empty -- see ghostHTML() in
   lesson-progress.js. It is the shape of a page, not a page. Nothing readable
   is under there, which is the whole point of the rework it belongs to. */

.unit-lock-screen {
  position: relative;
  isolation: isolate;
}

/* The lesson-page case: the lesson is gone and this stands in its place. */
.unit-lock-screen.is-stage {
  display: grid;
  place-items: center;
  min-height: min(70vh, 42rem);
  margin: clamp(1rem, 4vw, 2.5rem) 0;
  padding: clamp(1.25rem, 4vw, 3rem) 0;
  overflow: hidden;
  border-radius: 1.5rem;
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(14, 165, 233, 0.09), transparent 70%),
    var(--bg-elevated, #e8f4fb);
  border: 1px solid var(--border, #d0e4ef);
}

/* The unit-page case: a card above a list of lessons the student can still
   use. Compact, no backdrop, no screenful of empty space -- but spanning the
   page the way the teacher note beside it does, rather than stopping short in
   the left corner. The card's own text keeps its measure. */
.unit-lock-screen.is-inline { margin: 24px 0 28px; }
.unit-lock-screen.is-inline .unit-lock-screen__card { width: 100%; max-width: none; }
.unit-lock-screen.is-inline .unit-lock-screen__body,
.unit-lock-screen.is-inline .unit-lock-screen__title { max-width: 62ch; }

/* ---- the empty page-shape behind the card ---- */

.unit-lock-screen__ghost {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  pointer-events: none;
  /* Never let a screen reader announce a decoration, and never let a text
     selection drag through it. */
  user-select: none;
}

.unit-lock-screen__ghost-orb {
  position: absolute;
  width: 26rem;
  height: 26rem;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.65;
}

.unit-lock-screen__ghost-orb:first-child {
  top: -8rem;
  left: -6rem;
  background: radial-gradient(circle, rgba(56, 189, 248, 0.5), transparent 68%);
}

.unit-lock-screen__ghost-orb:nth-child(2) {
  right: -7rem;
  bottom: -9rem;
  background: radial-gradient(circle, rgba(125, 211, 252, 0.45), transparent 68%);
}

/* Empty bars in the rhythm of a lesson: a heading, some paragraph lines, a
   code block. Blurred hard enough that it reads as texture rather than as
   content somebody is meant to squint at. */
.unit-lock-screen__ghost-page {
  /* Wider than the card on purpose: the point of the shape is the part of it
     that shows past the card's edges. */
  width: min(54rem, 92%);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  filter: blur(5px);
  opacity: 0.9;
}

.unit-lock-screen__ghost-page > span {
  display: block;
  height: 0.8rem;
  border-radius: 999px;
  background: var(--pp-ink-soft, #165a7a);
  opacity: 0.28;
}

/* Scoped through the parent rather than flagged: `.ghost-page > span` above is
   a class-plus-type selector and would otherwise outrank a bare class. */
.unit-lock-screen__ghost-page > .unit-lock-screen__ghost-head {
  height: 1.75rem;
  width: 55%;
  opacity: 0.38;
}

.unit-lock-screen__ghost-page > .unit-lock-screen__ghost-block {
  height: 6.5rem;
  border-radius: 0.75rem;
  margin-top: 0.6rem;
  opacity: 0.2;
}

/* ---- the card ---- */

.unit-lock-screen__card {
  position: relative;
  z-index: 1;
  width: min(34rem, 100% - 2.5rem);
  padding: clamp(1.75rem, 4vw, 2.5rem);
  text-align: center;
  border-radius: 1.25rem;
  background: var(--panel, #fff);
  border: 1px solid var(--border, #d0e4ef);
  box-shadow: var(--shadow-strong, 0 12px 36px rgba(12, 69, 102, 0.12));
}

/* Frosted only on the stage, where there is something behind it to frost.
   Guarded: a browser without backdrop-filter keeps the solid panel above and
   the card stays readable rather than going translucent over the blur. */
@supports (backdrop-filter: blur(1px)) {
  .unit-lock-screen.is-stage .unit-lock-screen__card {
    background: color-mix(in srgb, var(--panel, #fff) 82%, transparent);
    backdrop-filter: blur(18px) saturate(1.3);
  }
}

.unit-lock-screen__badge {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  margin: 0 auto 1.1rem;
  border-radius: 50%;
  color: var(--primary-strong, #0284c7);
  background: var(--pp-fog, #e8f4fb);
  border: 1px solid var(--border, #d0e4ef);
}

.unit-lock-screen__badge svg {
  width: 1.6rem;
  height: 1.6rem;
}

.unit-lock-screen__eyebrow {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted, #4a7390);
}

.unit-lock-screen__title {
  margin: 0 0 0.75rem;
  font-family: var(--pp-display, inherit);
  font-size: clamp(1.35rem, 3vw, 1.75rem);
  line-height: 1.2;
  color: var(--text-strong, #0c4566);
}

.unit-lock-screen__body {
  margin: 0;
  color: var(--muted, #4a7390);
  line-height: 1.65;
  text-wrap: pretty;
}

.unit-lock-screen__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: center;
  margin: 1.5rem 0 0;
}

/* The inline card keeps the lock and the type scale, drops the centring: it
   sits in a column of left-aligned page text and should not fight it. */
.unit-lock-screen.is-inline .unit-lock-screen__card { text-align: left; }
.unit-lock-screen.is-inline .unit-lock-screen__badge { margin-left: 0; }
.unit-lock-screen.is-inline .unit-lock-screen__actions { justify-content: flex-start; }

@media (prefers-reduced-motion: reduce) {
  /* Nothing here animates, but the heavy blur is a rendering cost on a weak
     machine and buys nothing once motion is being asked to calm down. */
  .unit-lock-screen__ghost { display: none; }
}

[data-theme="dark"] .unit-lock-screen.is-stage {
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(56, 189, 248, 0.10), transparent 70%),
    var(--bg-elevated, #101820);
}

[data-theme="dark"] .unit-lock-screen__ghost-page > span {
  background: var(--pp-ink, #e8f4fb);
}

[data-theme="dark"] .unit-lock-screen__badge {
  background: rgba(56, 189, 248, 0.12);
}

/* A locked unit stays clickable in the lists, and reads as not-yet-open:
   clicking one is how a student reaches the lock screen that explains it. */
.unit-card.locked,
.dd-panel a.locked {
  opacity: 0.55;
}
.unit-card.locked::after,
.dd-panel a.locked::after {
  content: " · locked";
  font-size: 0.8em;
  color: var(--muted, #5b7c92);
  letter-spacing: 0.02em;
}

/* Entry points to the end of unit test: one card on each unit page, and a
   list of all ten on the curriculum. Styled here rather than in unit-test.css
   because that file is only loaded on the test page itself. */
.unit-test-status {
  margin: 0;
  color: var(--muted, #5b7c92);
  font-size: 0.95rem;
}

.unit-test-status.is-pass {
  color: var(--ok, #1f9d55);
  font-weight: 600;
}

.ut-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}

.ut-link {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--border, rgba(20, 60, 90, 0.14));
  border-radius: 14px;
  text-decoration: none;
  color: inherit;
  background: var(--card, rgba(255, 255, 255, 0.6));
}

.ut-link:hover,
.ut-link:focus-visible {
  border-color: var(--accent, #2f7ea8);
}

.ut-link__unit {
  font-weight: 700;
}

/* Lesson check-off on a unit page. */
.lesson-check {
  margin-left: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15em;
  height: 1.15em;
  border-radius: 999px;
  font-size: 0.85em;
  line-height: 1;
  vertical-align: baseline;
}

.lesson-check--done {
  color: #0b6b3a;
  background: #d9f2e4;
}

.lesson-check--started {
  color: var(--muted, #5b7c92);
  background: rgba(91, 124, 146, 0.16);
}

.unit-lesson-list li.is-lesson-done > a {
  color: #0b6b3a;
}

:root[data-theme="dark"] .lesson-check--done,
:root:not([data-theme="light"]) .lesson-check--done {
  color: #7ee2ab;
  background: rgba(16, 78, 51, 0.55);
}

:root[data-theme="dark"] .unit-lesson-list li.is-lesson-done > a,
:root:not([data-theme="light"]) .unit-lesson-list li.is-lesson-done > a {
  color: #7ee2ab;
}

.unit-lesson-summary {
  margin: 14px 0 0;
  color: var(--muted, #5b7c92);
  font-size: 0.92rem;
  font-weight: 600;
}

.unit-lesson-summary.is-complete {
  color: var(--ok, #1f9d55);
}

/* ------------------------------------------------------- teacher view note
   Deliberately not the amber of .unit-lock-screen: nothing here is a warning,
   it is a statement of which view you are in.

   It used to be capped at 68ch, which on a wide screen left a 796px box
   floating above lesson content that ran to 1390px -- the note read as
   orphaned in the corner rather than as a bar across the top of the page. The
   fix is not to stretch one line of text to 1400px, which is unreadable; it is
   to use the width structurally. Badge, text, action: three columns, so the
   bar spans the page while the sentence keeps a readable measure of its own.

   Same three columns wherever this appears -- injected onto a lesson by
   lesson-progress.js, or authored into progress.html and curriculum.html --
   so a teacher meets one component rather than three that nearly match. */
.teacher-view-note {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem 1.4rem;
  margin: 20px 0 26px;
  padding: 1.15rem 1.4rem;
  border: 1px solid var(--border, #cfe3f2);
  border-left: 4px solid var(--accent, #2f7ea8);
  border-radius: 14px;
  background:
    linear-gradient(100deg,
      rgba(14, 165, 233, 0.10) 0%,
      rgba(14, 165, 233, 0.04) 42%,
      transparent 78%),
    var(--panel, #fff);
  box-shadow: var(--shadow, 0 4px 20px rgba(12, 69, 102, 0.07));
}

/* The badge carries the meaning of the whole bar -- "you are looking at this
   as somebody else" -- so it is an eye rather than a decorative dot. */
.teacher-view-note__badge {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: #fff;
  background: linear-gradient(135deg, var(--pp-line, #0ea5e9), var(--pp-line-deep, #0284c7));
  box-shadow: 0 3px 10px rgba(2, 132, 199, 0.28);
}

.teacher-view-note__badge svg { width: 1.35rem; height: 1.35rem; }

/* The measure the sentence is actually read at, independent of how wide the
   bar has grown. */
.teacher-view-note__text { max-width: 62ch; }

.teacher-view-note__title {
  margin: 0 0 3px;
  font-family: var(--pp-display, inherit);
  font-weight: 700;
  font-size: 1.08rem;
  letter-spacing: 0.01em;
  color: var(--text-strong, #0c4566);
}

.teacher-view-note p { margin: 0; }
.teacher-view-note__body { color: var(--muted, #4a7390); line-height: 1.55; }

.teacher-view-note__actions { justify-self: end; }
.teacher-view-note__actions .btn { white-space: nowrap; }

/* Narrow: the action stops being a third column and becomes a row of its own,
   under the text rather than squeezed beside it. */
@media (max-width: 720px) {
  .teacher-view-note {
    grid-template-columns: auto minmax(0, 1fr);
    padding: 1rem 1.1rem;
  }
  .teacher-view-note__actions {
    grid-column: 1 / -1;
    justify-self: start;
    margin-top: 0.15rem;
  }
}

[data-theme="dark"] .teacher-view-note {
  background:
    linear-gradient(100deg,
      rgba(56, 189, 248, 0.14) 0%,
      rgba(56, 189, 248, 0.05) 42%,
      transparent 78%),
    var(--bg-elevated, #101820);
}

/* ---------- your progress in this unit ---------- */

.unit-progress {
  margin-top: 1.25rem;
  padding: .85rem 1rem;
  border: 1px solid var(--border, #cbd5e1);
  border-radius: .5rem;
  background: var(--panel, #fff);
  max-width: 26rem;
}

.unit-progress__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
}

.unit-progress__label {
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--muted, #475569);
}

.unit-progress__pct {
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong, #0f172a);
}

.unit-progress__meter {
  margin: .45rem 0 .4rem;
  height: .5rem;
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-elevated, #f1f5f9);
  border: 1px solid var(--border, #cbd5e1);
}

.unit-progress__meter .bar {
  height: 100%;
  width: 0;
  background: var(--primary, #0ea5e9);
  transition: width .3s ease;
}

.unit-progress.is-complete .unit-progress__meter .bar {
  background: var(--success, #16a34a);
}

.unit-progress.is-complete .unit-progress__pct {
  color: var(--success, #16a34a);
}

.unit-progress__detail {
  margin: 0;
  font-size: .82rem;
  color: var(--muted, #475569);
}

@media (prefers-reduced-motion: reduce) {
  .unit-progress__meter .bar { transition: none; }
}

/* The reflection floor's note. Beside the box, never in place of it: the
   answer stays exactly where the learner left it so they can edit rather than
   retype. Worded as what is missing, never as a verdict on them. */
.reflection-note {
  margin: .4rem 0 0;
  padding: .4rem .6rem;
  border-left: 3px solid var(--warn, #d97706);
  border-radius: .25rem;
  font-size: .85rem;
  color: var(--text, #334155);
  background: var(--bg-elevated, #f1f5f9);
}
