@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap");

/* na-tile-pack.css — pilot: one-tile-per-screen, image-LEFT (2/3) text-RIGHT (1/3),
   zero scrolling. Formatting mirrors CB1 (css/phase1-modern-tutorial.css):
   Manrope body / Space Grotesk headings, navy #003366 + orange #ff9900 on white paper.
   Scoped to body.na-tile-lock so it cannot affect other tutorials. */

/* CB1 design tokens */
body.na-tile-lock {
  --p1-navy: #003366; --p1-orange: #ff9900; --p1-ink: #111827; --p1-muted: #4b5563;
  --p1-paper: #faf8f5; --p1-surface: #ffffff; --p1-soft-blue: #f3f8ff; --p1-border: #dbe7f5;
}
/* Copy protection on the lesson surfaces (owner request). Selection is disabled on the tiles,
   the caption dock and the image overlay, and the JS below refuses copy/cut/drag inside them.

   Be clear about what this is: the text is still delivered to the browser, so devtools, view
   source, disabling JS and calling /api/content directly all still reach it. This raises the
   effort required to lift content casually; it is not a technical barrier to anyone determined.

   Form controls keep normal selection - a learner has to be able to work inside an input - and
   the tile reference chip is exempt because copying it is the entire point of that control. */
body.na-tile-lock .ntp-deck,
body.na-tile-lock .ntp-capdock,
body.na-tile-lock .ntp-anno {
  -webkit-user-select: none; -ms-user-select: none; user-select: none;
  -webkit-touch-callout: none;   /* stops the iOS press-and-hold copy sheet */
}
body.na-tile-lock :is(input, textarea, select, [contenteditable="true"]) {
  -webkit-user-select: text; user-select: text;
}
body.na-tile-lock .ntp-media img { -webkit-user-drag: none; user-drag: none; }
body.na-tile-lock .ntp-deck { font-family: "Manrope", "Segoe UI", system-ui, -apple-system, Arial, sans-serif; }

body.na-tile-lock.ntp-measuring .section-toggle { display: block !important; }

body.na-tile-lock.ntp-on { overflow: hidden !important; height: 100dvh; }
/* hide the ENTIRE original tutorial so nothing shows under the tiles — keep only the deck, controls, and brand bar */
/* Focus mode hides every direct <body> child that is not named here or marked .ntp-keep.

   ADD .ntp-keep TO NEW CHROME — do not extend the list below. The named exceptions are kept for
   the markup that already relies on them; everything new marks itself, in the file where it is
   written, so the coupling is local instead of a remote edit in this file that nobody remembers.

   Why the list is still here at all: the engine overlays ~1,710 flat tutorial pages whose legacy
   markup has never been audited, and hiding unknown content by default is the actual requirement
   there. Inverting to a deny-list would mean auditing all of them, and anything missed becomes
   visible junk over a lesson rather than a missing control.

   Why the opt-out was needed: this rule fails closed AND silently. Six elements were lost to it
   before the class existed — .ntp-exit (the only way out of a lesson), #ntp-tabs, #ntp-status,
   .ntp-prog (the narration progress pointer), .ntp-image-focus (click-to-zoom), and #script (the
   Script & Audio panel). Note the !important: it beat an inline display:block set from JS and a
   higher-specificity rule, so those elements sat in the DOM with correct styles and simply did
   not render.

   Two of those six are now gone for a different reason: #ntp-tabs and #script were a QA panel
   that printed every tile's narration script and audio state, and un-hiding them put a developer
   tool in front of learners. They were removed rather than kept visible, so this list no longer
   names them. */
body.na-tile-lock.ntp-on > *:not(.ntp-keep):not(.ntp-deck):not(.ntp-controls):not(#tutorial-brand-bar):not(.na-tutorial-bar):not(#na-brand-header):not(.ntp-exit):not(#ntp-status):not(.ntp-capdock):not(.ntp-prog):not(.ntp-image-focus) {
  display: none !important;
}
body.na-tile-lock.ntp-on #tutorial-footer,
body.na-tile-lock.ntp-on #scrollTopBtn,
body.na-tile-lock.ntp-on .scroll-top-btn { display: none !important; }

body.na-tile-lock .ntp-deck { position: relative; width: 100%; max-width: min(96vw, 1800px); margin: 0 auto; }
/* once locked, the deck is a fixed box pinned between the top bar and the bottom controls */
body.na-tile-lock.ntp-on .ntp-deck {
  position: fixed;
  left: 0; right: 0;
  top: var(--ntp-top, 92px);
  bottom: var(--ntp-bottom, 76px);
  width: 100%; max-width: min(96vw, 1800px); margin: 0 auto;
}

body.na-tile-lock .ntp-tile { display: none; }
body.na-tile-lock.ntp-on .ntp-tile.ntp-active {
  display: grid;
  grid-template-columns: 2.6fr 1fr;        /* image ~72% · text ~28% — widened image section */
  /* Row 2 is the narration caption + progress, docked UNDER the image. It was a fixed
     bottom-centred overlay spanning both columns, which laid the navy box across the body
     text (and, before 2026-07-24, across the image itself). Giving it its own grid row means
     it can never overlap either — geometry rather than z-index. `auto` collapses to nothing
     when the caption is hidden, so silent tiles look exactly as they did. */
  grid-template-rows: minmax(0, 1fr) auto;
  gap: clamp(12px, 2vw, 24px);
  height: 100%;                            /* fills the fixed deck — never exceeds the screen */
  padding: 16px clamp(12px, 3vw, 40px) 18px;
  box-sizing: border-box;
  overflow: hidden;                         /* no scroll, ever */
  position: relative;
  animation: ntpIn .24s cubic-bezier(.22,.61,.36,1) both;
}
body.na-tile-lock.ntp-on .ntp-tile.ntp-active::after {
  content: "";
  position: absolute;
  left: clamp(12px, 3vw, 40px);
  right: clamp(12px, 3vw, 40px);
  bottom: 5px;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--p1-navy), var(--p1-orange));
  box-shadow: 0 -8px 18px rgba(15, 23, 42, 0.08);
  opacity: 0.42;
  pointer-events: none;
}
@keyframes ntpIn { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }

/* LEFT: image is the driver */
body.na-tile-lock .ntp-media {
  grid-column: 1;
  grid-row: 1;                              /* row 2 belongs to the caption dock */
  min-width: 0; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border: 2px solid #003366; border-radius: 16px;
  overflow: hidden; padding: 10px;
  box-shadow: 0 4px 14px rgba(0,51,102,.08);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
/* reactive: every tile lifts + its visual zooms on hover */
body.na-tile-lock .ntp-media:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(0,51,102,.16);
  border-color: #ff9900;
}
body.na-tile-lock .ntp-media img,
body.na-tile-lock .ntp-media svg,
body.na-tile-lock .ntp-media video,
body.na-tile-lock .ntp-media canvas { transition: transform .4s ease; }
body.na-tile-lock .ntp-media:hover img,
body.na-tile-lock .ntp-media:hover svg,
body.na-tile-lock .ntp-media:hover video,
body.na-tile-lock .ntp-media:hover canvas { transform: scale(1.04); }
body.na-tile-lock .ntp-media.ntp-placeholder {
  border-style: dashed; border-color: #9bb3cc; background: #f6f9fc;
  color: #7c8aa0; font: 700 13px Arial, sans-serif; text-align: center;
}
body.na-tile-lock .ntp-media > * { max-width: 100%; max-height: 100%; margin: 0 auto; }
body.na-tile-lock .ntp-media svg,
body.na-tile-lock .ntp-media img,
body.na-tile-lock .ntp-media video,
body.na-tile-lock .ntp-media canvas {
  display: block; width: 100%; height: 100%; object-fit: contain;
}
body.na-tile-lock .ntp-media img {
  cursor: zoom-in;
}

body.na-tile-lock .ntp-image-focus {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 28px;
  background: rgba(4, 16, 32, 0.94);
}
body.na-tile-lock .ntp-image-focus.ntp-open {
  display: flex;
}
body.na-tile-lock .ntp-image-focus img {
  display: block;
  max-width: calc(100vw - 56px);
  max-height: calc(100vh - 76px);
  width: auto;
  height: auto;
  object-fit: contain;
  background: #ffffff;
  border: 2px solid #ffffff;
  border-radius: 10px;
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.42);
}
body.na-tile-lock .ntp-image-focus-close {
  position: fixed;
  top: 14px;
  right: 18px;
  width: 42px;
  height: 42px;
  border: 1px solid rgba(255, 255, 255, 0.36);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  cursor: pointer;
  font: 900 28px/1 Arial, Helvetica, sans-serif;
}

/* RIGHT: supporting text column */
body.na-tile-lock .ntp-col {
  grid-column: 2;
  grid-row: 1 / -1;                          /* full height — the caption dock sits beside it, not above it */
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column; gap: 8px;
}
/* When the media panel shrinks to hug its picture, the slack goes to this column. Cap the
   measure so a wide window does not produce 200-character lines, which are harder to read than
   the cramped column this replaced. 68ch measures ~775px in Manrope, inside the 45-75 character
   band; 78ch was tried first and ran to ~890px because this face has wide digits. */
body.na-tile-lock .ntp-col > * { max-width: 68ch; }
body.na-tile-lock .ntp-heading {
  flex: 0 0 auto;
  font: 700 clamp(16px, 1.5vw, 22px)/1.25 "Space Grotesk", "Manrope", "Segoe UI", sans-serif;
  color: var(--p1-navy); border-bottom: 3px solid var(--p1-orange); padding-bottom: 6px; margin: 0;
}
/* The reference chip is a button (click to copy), so the UA button styling is reset here and
   the slug is allowed to ellipsis rather than force the chip wider than the text column. */
body.na-tile-lock button.ntp-tile-ref {
  gap: 7px; cursor: pointer; max-width: 100%;
  font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  text-transform: none;
}
body.na-tile-lock button.ntp-tile-ref:hover { background: #eef5ff; border-color: #b9d2ee; color: #003366; }
body.na-tile-lock button.ntp-tile-ref:focus-visible { outline: 2px solid #ff9900; outline-offset: 2px; }
body.na-tile-lock button.ntp-tile-ref.is-copied { background: #eaf7ee; border-color: #9fd3ae; color: #1d6b34; }
body.na-tile-lock .ntp-tile-ref .ntp-ref-txt {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
body.na-tile-lock .ntp-tile-ref .ntp-ref-copy {
  flex: 0 0 auto; padding-left: 7px; border-left: 1px solid #d6e3f2;
  font-weight: 700; opacity: .72; text-transform: uppercase; letter-spacing: .06em;
}
body.na-tile-lock .ntp-tile-ref {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  margin: 0 10px 7px 0;
  border: 1px solid #d6e3f2;
  background: #f8fbff;
  color: #5b6b82;
  border-radius: 7px;
  padding: 3px 7px;
  font: 800 11px/1 Arial, Helvetica, sans-serif;
  letter-spacing: .04em;
  white-space: nowrap;
  vertical-align: middle;
}
/* a demoted section sub-heading when a sparse heading tile was merged into its content tile */
body.na-tile-lock .ntp-body .ntp-subhead {
  font: 700 clamp(14px, 1.3vw, 18px)/1.3 "Space Grotesk", "Manrope", "Segoe UI", sans-serif;
  color: var(--p1-navy) !important; margin: 10px 0 4px; padding-bottom: 3px; border-bottom: 2px solid var(--p1-soft-blue);
}
body.na-tile-lock .ntp-body {
  flex: 1 1 auto;
  min-height: 0;
  /* Was `overflow: hidden` — "clipped, never scrolled, packer guarantees fit". The packer does
     not guarantee fit here: measured on a real 481-word tile, only 23-28% of the text was
     reachable at 1440-1920px, clipped with no scrollbar and no sign that more existed. The
     <=820px branch already set overflow:auto, which is why an iPad could read the whole tile
     and a desktop could not — the defect was desktop/laptop only. Scrolling at every width
     costs a scrollbar on the few long tiles and returns the other ~75% of the teaching. */
  overflow-y: auto;
  overscroll-behavior: contain;
  font-family: "Manrope", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  font-size: clamp(13.5px, 1.45vw, 16px);
  line-height: 1.6;
  color: var(--p1-ink);
}
/* With the body scrollable, the scrollbar is the only signal that there is more teaching below
   the fold, so it is given a visible thumb instead of the platform's auto-hiding overlay bar. */
body.na-tile-lock .ntp-body { scrollbar-width: thin; scrollbar-color: #c7d7ea transparent; }
body.na-tile-lock .ntp-body::-webkit-scrollbar { width: 10px; }
body.na-tile-lock .ntp-body::-webkit-scrollbar-track { background: transparent; }
body.na-tile-lock .ntp-body::-webkit-scrollbar-thumb {
  background: #c7d7ea; border-radius: 6px;
  border: 3px solid transparent; background-clip: padding-box;
}
body.na-tile-lock .ntp-body::-webkit-scrollbar-thumb:hover { background: #9dbbdd; background-clip: padding-box; }
/* Scroll affordance. The body is a scroll container, so a line falling on the bottom edge is
   sliced in half - which looks like a rendering fault rather than "keep reading". The padding
   keeps the last line off the edge, and .ntp-more (set by the renderer, and cleared once the
   learner reaches the end) fades the boundary so the half-line reads as deliberate. */
body.na-tile-lock .ntp-body { padding-bottom: 6px; }
body.na-tile-lock .ntp-body.ntp-more {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}
body.na-tile-lock .ntp-body > *:first-child { margin-top: 0; }
body.na-tile-lock .ntp-body :is(h1,h2,h3,h4,h5,h6) {
  font-family: "Space Grotesk", "Manrope", Arial, sans-serif;
  color: var(--p1-navy); font-size: 1.1em; line-height: 1.25; margin: .4em 0 .3em;
}

/* ===== Standardize typography across every tile (override the tutorials' varied inline fonts/sizes) ===== */
body.na-tile-lock .ntp-body,
body.na-tile-lock .ntp-body :is(p,li,ul,ol,td,th,label,dd,dt,blockquote,a,small,em,strong,b,span,div) {
  font-family: "Manrope", "Segoe UI", system-ui, -apple-system, Arial, sans-serif !important;
  letter-spacing: 0 !important;
}
body.na-tile-lock .ntp-body :is(h1,h2,h3,h4,h5,h6),
body.na-tile-lock .ntp-body .ntp-subhead {
  font-family: "Space Grotesk", "Manrope", Arial, sans-serif !important;
}
/* one consistent body size + heading scale, taming inline font-size:Xrem from the source tutorials */
body.na-tile-lock .ntp-body :is(p,li,td,th,label,blockquote,span,div)[style*="font-size"] { font-size: clamp(13.5px, 1.45vw, 16px) !important; }
body.na-tile-lock .ntp-body :is(h1,h2) { font-size: clamp(17px, 1.7vw, 21px) !important; }
body.na-tile-lock .ntp-body :is(h3,h4) { font-size: clamp(15px, 1.5vw, 18px) !important; }
body.na-tile-lock .ntp-body :is(h5,h6) { font-size: clamp(14px, 1.4vw, 16px) !important; }

/* CB1 color cleanup — strip the original tutorial's loud inline colors/backgrounds */
body.na-tile-lock .ntp-body,
body.na-tile-lock .ntp-body :is(p,li,span,div,label,dd,dt,blockquote,a,small,em),
body.na-tile-lock .ntp-body [style*="color"] { color: var(--p1-ink) !important; }
body.na-tile-lock .ntp-body :is(h1,h2,h3,h4,h5,h6,strong,b),
body.na-tile-lock .ntp-body :is(h1,h2,h3,h4,h5,h6,strong,b)[style*="color"] { color: var(--p1-navy) !important; }
body.na-tile-lock .ntp-body [style*="background"] {
  background: var(--p1-surface) !important;
  border: 1px solid var(--p1-border) !important;
  border-left: 4px solid var(--p1-orange) !important;
  color: var(--p1-ink) !important;
  box-shadow: none !important;
}
/* BRAND RULE: keep dark-blue/navy backgrounds, but text on them must be white (or brand yellow/orange) */
body.na-tile-lock .ntp-body [style*="background:#003366"],
body.na-tile-lock .ntp-body [style*="background: #003366"],
body.na-tile-lock .ntp-body [style*="background:#0f2f57"],
body.na-tile-lock .ntp-body [style*="background: #0f2f57"],
body.na-tile-lock .ntp-body [style*="background:#0a1f3a"],
body.na-tile-lock .ntp-body [style*="background:#091327"],
body.na-tile-lock .ntp-body [style*="background:#04284f"],
body.na-tile-lock .ntp-body [style*="background:#0a2a52"],
body.na-tile-lock .ntp-body [style*="background:#0d2b50"],
body.na-tile-lock .ntp-body [style*="background:#1a2540"],
body.na-tile-lock .ntp-body [style*="background:#0a4a8a"],
body.na-tile-lock .ntp-body [style*="background:#003"][style*="gradient"],
body.na-tile-lock .ntp-body [style*="#003366"][style*="gradient"] {
  background: var(--p1-navy) !important;
  border-color: var(--p1-navy) !important;
  border-left: 4px solid var(--p1-orange) !important;
  color: #fff !important;
}
body.na-tile-lock .ntp-body [style*="background:#003366"] *,
body.na-tile-lock .ntp-body [style*="background: #003366"] *,
body.na-tile-lock .ntp-body [style*="background:#0f2f57"] *,
body.na-tile-lock .ntp-body [style*="background:#0a1f3a"] *,
body.na-tile-lock .ntp-body [style*="background:#091327"] *,
body.na-tile-lock .ntp-body [style*="background:#04284f"] *,
body.na-tile-lock .ntp-body [style*="background:#0a2a52"] *,
body.na-tile-lock .ntp-body [style*="background:#0d2b50"] *,
body.na-tile-lock .ntp-body [style*="background:#1a2540"] *,
body.na-tile-lock .ntp-body [style*="#003366"][style*="gradient"] * {
  color: #fff !important;
}
body.na-tile-lock .ntp-body table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; }
body.na-tile-lock .ntp-body th { background: var(--p1-navy) !important; color: #fff !important; border-color: var(--p1-border) !important; }
body.na-tile-lock .ntp-body td { color: var(--p1-ink) !important; border-color: var(--p1-border) !important; }
body.na-tile-lock .ntp-body :is(ul,ol) { margin: .2em 0 .2em 18px !important; padding: 0 !important; }

/* full-width tile for tables — no image slot, table gets the whole row so nothing clips */
body.na-tile-lock.ntp-on .ntp-tile.ntp-wide.ntp-active { grid-template-columns: 1fr; }
body.na-tile-lock .ntp-wide .ntp-col { grid-column: 1 / -1; min-width: 0; }
body.na-tile-lock .ntp-wide .ntp-body { display: flex; flex-direction: column; }
body.na-tile-lock .ntp-wide .ntp-body table { width: 100%; font-size: clamp(12px, 1.25vw, 15px); }
body.na-tile-lock .ntp-wide .ntp-body :is(th,td) { padding: 7px 12px; }

/* quiz tiles — question + answer choices, full width, no image slot */
body.na-tile-lock .ntp-quiz .ntp-heading,
body.na-tile-lock .ntp-quiz .ntp-body { max-width: 940px; margin-left: auto; margin-right: auto; width: 100%; }
body.na-tile-lock .ntp-quiz .ntp-body {
  font-size: clamp(13.5px, 1.35vw, 16px);
  overflow-y: auto;
  padding: 0 8px 18px 0;
  scrollbar-gutter: stable;
}
body.na-tile-lock .ntp-quiz .ntp-body :is(label, .option, .quiz-option, .answer-option, .choice) {
  display: block; margin: clamp(4px, .65vh, 7px) 0; padding: clamp(8px, 1.1vh, 11px) 14px;
  border: 1px solid var(--p1-border) !important; border-radius: 10px; background: #fff !important; cursor: pointer;
  line-height: 1.28;
}
body.na-tile-lock .ntp-quiz .ntp-body :is(label:hover, .option:hover, .quiz-option:hover, .choice:hover) {
  border-color: var(--p1-orange) !important; background: #fff8ec !important;
}
body.na-tile-lock .ntp-quiz .ntp-body input[type="radio"],
body.na-tile-lock .ntp-quiz .ntp-body input[type="checkbox"] { margin-right: 10px; }

/* Submit / Retry sit under the last question — render as real buttons, not cleanup cards */
body.na-tile-lock .ntp-quiz-actions { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
body.na-tile-lock .ntp-quiz .quiz-btn,
body.na-tile-lock .ntp-quiz .submit-quiz-btn,
body.na-tile-lock .ntp-quiz-actions button {
  background: var(--p1-orange) !important; color: var(--p1-navy) !important;
  border: 1.5px solid var(--p1-orange) !important; box-shadow: -2px 3px 0 rgba(0,51,102,.18) !important;
  padding: 12px 26px !important; border-radius: 10px !important;
  font: 800 15px "Space Grotesk", "Manrope", sans-serif !important; cursor: pointer !important;
  width: auto !important; display: inline-block;
}
/* disabled submit (until all questions answered) must LOOK disabled, not falsely active */
body.na-tile-lock .ntp-quiz button:disabled,
body.na-tile-lock .ntp-quiz .submit-quiz-btn:disabled {
  background: #cbd5e1 !important; color: #64748b !important; border-color: #cbd5e1 !important;
  cursor: not-allowed !important; box-shadow: none !important;
}
/* Retake / Retry — a distinct navy button (shown after submit) */
body.na-tile-lock .ntp-quiz .retake-btn,
body.na-tile-lock .ntp-quiz .retry-btn,
body.na-tile-lock .ntp-quiz [onclick*="retry" i],
body.na-tile-lock .ntp-quiz [onclick*="retake" i],
body.na-tile-lock .ntp-quiz [onclick*="resetquiz" i] {
  background: var(--p1-navy) !important; color: #fff !important; border: 1.5px solid var(--p1-navy) !important;
  padding: 12px 26px !important; border-radius: 10px !important; box-shadow: -2px 3px 0 rgba(0,51,102,.18) !important;
  font: 800 15px "Space Grotesk", "Manrope", sans-serif !important; cursor: pointer !important; width: auto !important;
}
body.na-tile-lock .ntp-quiz-actions .score-display { width: 100%; background: var(--p1-soft-blue) !important; border: 1px solid var(--p1-border) !important; border-radius: 10px; padding: 12px 16px; color: var(--p1-ink) !important; }

/* an intact quiz is an assessment — allow it to scroll internally (questions + results + review) */
body.na-tile-lock .ntp-quiz-intact .ntp-body { overflow: auto; }

/* any dark-background element (navy, dark green, etc.) → white text incl. descendants */
body.na-tile-lock .ntp-body .ntp-ondark,
body.na-tile-lock .ntp-body .ntp-ondark * { color: #fff !important; }

/* quiz result summary banner (shown after submit) */
body.na-tile-lock .ntp-quiz-result { padding: 14px 18px; border-radius: 12px; margin: 0 0 16px; font-size: 15px; line-height: 1.5; }
body.na-tile-lock .ntp-quiz-result.ntp-pass { background: #ecfdf3 !important; border: 1px solid #16a34a; border-left: 5px solid #16a34a; color: #14532d !important; }
body.na-tile-lock .ntp-quiz-result.ntp-fail { background: #fff7ed !important; border: 1px solid var(--p1-orange); border-left: 5px solid var(--p1-orange); color: #7a3e00 !important; }
body.na-tile-lock .ntp-quiz-result strong { color: inherit !important; }
body.na-tile-lock .ntp-retake-btn { display: inline-block; margin-top: 12px; background: var(--p1-orange); color: #fff !important; border: 0; border-radius: 10px; padding: 9px 20px; font-weight: 700; font-size: 14px; cursor: pointer; box-shadow: 0 2px 8px rgba(255,153,0,.28); }
body.na-tile-lock .ntp-retake-btn:hover { filter: brightness(1.06); transform: translateY(-1px); }

/* ===== Flashcard + quiz frame inside tiles (adaptive stepper tutorials) ===== */
/* The engine forces dark ink on all text, which inverts the flashcard FRONT (white on a dark
   gradient) and dark quiz surfaces. Re-assert correct contrast: white on dark, navy on white. */
body.na-tile-lock .ntp-body .flashcard-front,
body.na-tile-lock .ntp-body .flashcard-front * { color: #fff !important; }
body.na-tile-lock .ntp-body .flashcard-back,
body.na-tile-lock .ntp-body .flashcard-back *,
body.na-tile-lock .ntp-body .flashcard-answer { color: var(--p1-navy) !important; }
body.na-tile-lock .ntp-body .flashcard-topic { color: #fff !important; }

/* Keep the 3D flip working (engine restyling can flatten preserve-3d so you'd see the front
   mirrored "from behind" instead of the answer). */
body.na-tile-lock .ntp-body .flashcard { perspective: 1000px !important; }
body.na-tile-lock .ntp-body .flashcard-inner { transform-style: preserve-3d !important; position: relative; }
body.na-tile-lock .ntp-body .flashcard-front,
body.na-tile-lock .ntp-body .flashcard-back { -webkit-backface-visibility: hidden !important; backface-visibility: hidden !important; }
body.na-tile-lock .ntp-body .flashcard-back { transform: rotateY(180deg) !important; }
body.na-tile-lock .ntp-body .flashcard.flipped .flashcard-inner { transform: rotateY(180deg) !important; }

/* Fit the quiz/flashcard frame to the screen so no manual browser zoom is needed. */
body.na-tile-lock .ntp-quiz .ntp-body { overflow: auto !important; max-height: 100%; }
body.na-tile-lock .ntp-body .flashcard { height: clamp(210px, 36vh, 320px) !important; max-width: 460px; margin: 10px auto !important; }
body.na-tile-lock .ntp-body .flashcard-question { font-size: clamp(15px, 1.6vw, 21px) !important; }
body.na-tile-lock .ntp-body .flashcard-container { padding: 6px !important; }
body.na-tile-lock .ntp-body .question-card { padding: 12px 16px !important; margin: 8px 0 !important; }
body.na-tile-lock .ntp-body .question-scenario { font-size: clamp(13px, 1.5vw, 15px) !important; }
body.na-tile-lock .ntp-body .question-text { font-size: clamp(14px, 1.6vw, 17px) !important; }
body.na-tile-lock .ntp-body .options-container .option,
body.na-tile-lock .ntp-body .quiz-results { font-size: clamp(13px, 1.5vw, 16px) !important; }

/* TABLETS / PHONES: stack image on top, text below */
@media (max-width: 820px) {
  body.na-tile-lock.ntp-on .ntp-tile.ntp-active {
    grid-template-columns: 1fr; grid-template-rows: auto 1fr; gap: 10px;
    padding: 12px clamp(10px, 4vw, 22px) 6px;
  }
  body.na-tile-lock .ntp-media { grid-column: 1; max-height: 40vh; }
  body.na-tile-lock .ntp-col { grid-column: 1; min-height: 0; }
  body.na-tile-lock .ntp-body { overflow: auto; -webkit-overflow-scrolling: touch; }
  body.na-tile-lock .ntp-heading { font-size: clamp(16px, 4vw, 20px); }
}
/* SMALL PHONES: compact controls + type */
@media (max-width: 560px) {
  body.na-tile-lock .ntp-btn { min-width: 0; padding: 9px 12px; font-size: 13px; }
  body.na-tile-lock .ntp-audio { padding: 9px 12px; }
  body.na-tile-lock .ntp-count { font-size: 12px; }
  body.na-tile-lock .ntp-center { gap: 8px; }
  body.na-tile-lock .ntp-controls { padding: 8px 12px; gap: 8px; }
  body.na-tile-lock .ntp-media { max-height: 34vh; }
  body.na-tile-lock .ntp-body { font-size: 14.5px; }
}
/* LANDSCAPE PHONES (short height): keep side-by-side, shrink media so text fits */
@media (max-height: 520px) and (orientation: landscape) {
  body.na-tile-lock.ntp-on .ntp-tile.ntp-active { grid-template-columns: 1.6fr 1fr; grid-template-rows: 1fr; }
  body.na-tile-lock .ntp-media { max-height: none; grid-column: 1; }
  body.na-tile-lock .ntp-col { grid-column: 2; }
  body.na-tile-lock .ntp-body { overflow: auto; }
}

/* fixed control bar — the page itself never scrolls */
body.na-tile-lock .ntp-controls {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 9000;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px clamp(12px, 3vw, 40px);
  background: rgba(255,255,255,.97); border-top: 1px solid #dbe4f0;
  box-shadow: 0 -6px 20px rgba(0,0,0,.06);
}
body.na-tile-lock .ntp-count { font: 700 14px "Space Grotesk", "Manrope", sans-serif; color: var(--p1-navy); }
body.na-tile-lock .ntp-btn {
  min-width: 116px; padding: 10px 18px; border-radius: 10px;
  font: 600 14px "Space Grotesk", "Manrope", sans-serif; cursor: pointer; border: 1.5px solid var(--p1-navy);
}
body.na-tile-lock .ntp-next { background: var(--p1-orange); color: var(--p1-navy); border-color: var(--p1-orange); box-shadow: -2px 3px 0 rgba(0,51,102,.18); }
body.na-tile-lock .ntp-back { background: #fff; color: var(--p1-navy); }
body.na-tile-lock .ntp-center { display: flex; align-items: center; gap: 14px; }
body.na-tile-lock .ntp-audio { background: var(--p1-navy); color: #fff; border-color: var(--p1-navy); }
body.na-tile-lock .ntp-audio:hover { background: var(--p1-orange); color: var(--p1-navy); border-color: var(--p1-orange); }
body.na-tile-lock .ntp-btn:disabled { opacity: .4; cursor: default; box-shadow: none; }
/* Captions toggle + speed selector */
body.na-tile-lock .ntp-cc { min-width: 0; padding: 9px 12px; background: var(--p1-navy); color: #fff; border-color: var(--p1-navy); letter-spacing: .04em; }
body.na-tile-lock .ntp-mute { min-width: 0; padding: 9px 12px; background: var(--p1-navy); color: #fff; border-color: var(--p1-navy); }
body.na-tile-lock .ntp-cc.ntp-cc-off { background: #fff; color: var(--p1-navy); opacity: .8; }
/* Silent mode. Reads as an active state rather than a disabled one - the walk is still
   running, the learner has just chosen to follow it on captions alone. */
body.na-tile-lock .ntp-mute.ntp-mute-off { background: #fff; color: var(--p1-navy); opacity: .8; }
body.na-tile-lock .ntp-mute.ntp-mute-off::after { content: " silent"; font-size: .72em; letter-spacing: .02em; }
body.na-tile-lock .ntp-cc:hover { background: var(--p1-orange); color: var(--p1-navy); border-color: var(--p1-orange); }
body.na-tile-lock .ntp-speed { padding: 9px 10px; border-radius: 10px; border: 1.5px solid var(--p1-navy); background: #fff; color: var(--p1-navy); font: 600 13px "Space Grotesk", "Manrope", sans-serif; cursor: pointer; }
body.na-tile-lock .ntp-caption { font-family: "Manrope", "Segoe UI", sans-serif; font-weight: 600; }
@media (max-width: 640px) { body.na-tile-lock .ntp-btn { min-width: 92px; padding: 9px 12px; } body.na-tile-lock .ntp-cc { min-width: 0; } body.na-tile-lock .ntp-caption { font-size: .92rem; bottom: 70px; } }

/* ── Synced audio-teaching annotation overlay (the "teacher walks the page" experience) ── */
.ntp-media { position: relative; }
/* The overlay must cover the PICTURE, because cue coordinates are fractions of the picture.
   `inset: 0` resolves against .ntp-media's padding box, so it also covered the panel's 10px
   padding - mapping every dot, label and arrow onto a box larger than the artwork and pushing
   them outward from the centre (measured: 8px off at 0.1 and 0.9). Inset by the padding so the
   overlay matches the content box instead. */
.ntp-anno { position: absolute; inset: 10px; pointer-events: none; z-index: 6; }
.ntp-anno-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* line/marker geometry is authored in pixels now (no viewBox), so nothing here may scale it. */
.ntp-anno-line { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); animation: ntp-anno-draw .5s ease-out; }
@keyframes ntp-anno-draw { from { stroke-dashoffset: 60; opacity: 0; } to { stroke-dashoffset: 0; opacity: 1; } }
.ntp-anno-label { position: absolute; transform: translate(-50%, -50%); display: flex; align-items: center; gap: 7px; animation: ntp-anno-pop .35s ease-out; white-space: nowrap; }
@keyframes ntp-anno-pop { from { opacity: 0; transform: translate(-50%, -42%) scale(.9); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
.ntp-anno-dot { width: 13px; height: 13px; border-radius: 50%; background: #ff9900; box-shadow: 0 0 0 4px rgba(255,153,0,.32), 0 1px 3px rgba(0,0,0,.4); animation: ntp-anno-pulse 1.4s ease-out infinite; flex: 0 0 auto; }
@keyframes ntp-anno-pulse { 0% { box-shadow: 0 0 0 2px rgba(255,153,0,.5), 0 1px 3px rgba(0,0,0,.4); } 70% { box-shadow: 0 0 0 11px rgba(255,153,0,0), 0 1px 3px rgba(0,0,0,.4); } 100% { box-shadow: 0 0 0 2px rgba(255,153,0,0), 0 1px 3px rgba(0,0,0,.4); } }
/* The cue label was a filled navy panel dropped on top of the diagram at the cue point — the
   exact thing the anatomy layer below was rewritten to stop doing. It is now the same outlined
   glyph: white fill, navy stroke, no panel, so it names the structure without hiding it. The
   pulsing orange dot and the arrow are unchanged; they were never the complaint. */
.ntp-anno-txt { background: transparent; box-shadow: none; padding: 0; border-radius: 0;
  color: #fff; font: 700 14px/1.2 "Space Grotesk", system-ui, sans-serif; letter-spacing: .2px;
  max-width: 260px; white-space: normal;
  text-shadow: -1.5px -1.5px 0 #003366, 1.5px -1.5px 0 #003366, -1.5px 1.5px 0 #003366, 1.5px 1.5px 0 #003366, 0 2px 5px rgba(0,0,0,.45); }
@supports (paint-order: stroke) {
  .ntp-anno-txt { paint-order: stroke fill; -webkit-text-stroke: 3px #003366; text-shadow: 0 2px 5px rgba(0,0,0,.45); }
}
.ntp-readpause { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); background: rgba(0,51,102,.94); color: #ffd9a3; font: 700 14px/1 "Space Grotesk", system-ui, sans-serif; padding: 9px 16px; border-radius: 999px; box-shadow: 0 3px 12px rgba(0,0,0,.3); animation: ntp-anno-pop .3s ease-out; }

/* ── Structure labels (anatomy-figure layer) ─────────────────────────────────
   Short part name sitting LATERAL to its own pulsing marker. FONT ONLY — no
   background, no panel, no border. Legibility comes from weight plus a dark
   text-shadow, so the word never covers the structure it names. This is the
   distinction that mattered in the 2026-07-24 call: the old .ntp-anno-txt drew
   a navy box over the diagram; this draws glyphs and nothing else.
   Cumulative — each stays lit once its segment is reached. */
/* The DOT is the anchor: x,y lands on the structure itself and the word extends
   laterally from it. Centring the whole flex pair on x,y (the obvious transform)
   would push the dot left of the structure by half the label's width, which grows
   with the length of the word — so a long name would drift further off target than
   a short one. Offsetting by half the dot instead keeps the marker exactly on the
   structure whatever the word is. */
.ntp-struct-label { position: absolute; transform: translate(-4.5px, -50%); display: flex; align-items: center; gap: 6px; white-space: nowrap; pointer-events: none; }
.ntp-struct-label.left { flex-direction: row-reverse; transform: translate(calc(-100% + 4.5px), -50%); }
.ntp-struct-label.is-new { animation: ntp-struct-in .45s ease-out; }
@keyframes ntp-struct-in { from { opacity: 0; } to { opacity: 1; } }
/* Owner call: the label was competing with the anatomy it points at. The dot and the word both
   shrink - a smaller marker with a smaller word stays a pointer instead of becoming the subject.
   The halo is trimmed to match so the pulse does not reintroduce the bulk. */
.ntp-struct-dot { width: 9px; height: 9px; border-radius: 50%; background: #ff9900; box-shadow: 0 0 0 3px rgba(255,153,0,.30), 0 1px 2px rgba(0,0,0,.4); animation: ntp-anno-pulse 1.4s ease-out infinite; flex: 0 0 auto; }
/* White infill, navy outline — legible on any diagram, light regions included.
   A drop-shadow alone only works over dark pixels; these images run from near-black
   to pale washes, so the letter carries its own contrast instead of borrowing it
   from the background. Still font only: an outlined glyph, never a filled panel.
   Base rule uses a 4-way shadow so the outline survives without paint-order. */
.ntp-struct-text { font: 700 clamp(10px, 0.72vw, 12px)/1 "Space Grotesk", system-ui, sans-serif; color: #fff; letter-spacing: .2px;
  text-shadow: -1px -1px 0 #003366, 1px -1px 0 #003366, -1px 1px 0 #003366, 1px 1px 0 #003366, 0 1px 4px rgba(0,0,0,.45); }
/* Where paint-order is supported, use a real stroke drawn BEHIND the fill — cleaner
   letterforms than stacked shadows, and it thickens evenly on every glyph edge. */
@supports (paint-order: stroke) {
  .ntp-struct-text { -webkit-text-stroke: 2px #003366; paint-order: stroke fill; text-shadow: 0 1px 4px rgba(0,0,0,.45); }
}
@media (max-width: 640px) { .ntp-struct-text { font-size: 10px; } .ntp-struct-label { gap: 5px; } }
@media (prefers-reduced-motion: reduce) { .ntp-struct-dot { animation: none; } .ntp-struct-label.is-new { animation: none; } }

/* Case C: a tile that is just an image with no text — full-bleed it, no empty text column */
body.na-tile-lock.ntp-on .ntp-tile.ntp-solo.ntp-active { grid-template-columns: 1fr; }
body.na-tile-lock .ntp-tile.ntp-solo .ntp-body { display: none; }
body.na-tile-lock .ntp-tile.ntp-solo .ntp-media { grid-column: 1; max-height: 78vh; }

/* ── Phase-1 tutorials migrated to the tile engine: define the --p1-* tokens their quiz/result/content
   styling expects (these previously came from phase1-modern-tutorial.css, removed on migration). ── */
body.na-tile-lock {
  --p1-navy:#003366; --p1-orange:#ff9900; --p1-orange-dark:#cc7700; --p1-teal:#007799;
  --p1-green:#006633; --p1-red:#b42318; --p1-purple:#660099; --p1-gold:#b77900;
  --p1-ink:#111827; --p1-muted:#4b5563; --p1-paper:#faf8f5; --p1-surface:#ffffff;
  --p1-soft-blue:#f3f8ff; --p1-soft-amber:#fff8ec; --p1-border:#dbe7f5;
  --p1-shadow-sm:0 2px 10px rgba(15,23,42,.07); --p1-shadow-md:0 10px 24px rgba(15,23,42,.13);
}
/* Phase-1 quiz score/result visibility under the tile engine (fallback colours; JS toggles display) */
body.na-tile-lock .quiz-result { margin:12px 0; padding:12px 16px; border-radius:10px; background:#f3f8ff; border:1px solid #dbe7f5; color:#111827; font-size:15px; line-height:1.5; }
body.na-tile-lock .quiz-result.quiz-pass, body.na-tile-lock .quiz-pass { background:#ecfdf3; border-color:#067647; color:#054f31; }
body.na-tile-lock .quiz-result.quiz-fail, body.na-tile-lock .quiz-fail { background:#fef3f2; border-color:#b42318; color:#7a271a; }
body.na-tile-lock .quiz-submit, body.na-tile-lock .score-display { color:#111827; }

/* ── Post-fail review flashcards: make them WAY more apparent (highlighted panel + header + big cards) ── */
body.na-tile-lock .ntp-body .flashcard-container:not(:empty) {
  margin: 20px 0 10px !important;
  padding: 16px 14px 20px !important;
  background: linear-gradient(180deg, #fff8ec, #ffffff) !important;
  border: 2px solid var(--p1-orange) !important;
  border-radius: 14px !important;
  box-shadow: 0 8px 24px rgba(255, 153, 0, 0.22) !important;
}
body.na-tile-lock .ntp-body .flashcard-container:not(:empty)::before {
  content: "📇 Review these flashcards, then retake — tap a card to flip";
  display: block; margin: 0 0 14px; text-align: center;
  font: 800 clamp(15px, 1.8vw, 20px)/1.3 "Space Grotesk", "Manrope", system-ui, sans-serif;
  color: var(--p1-navy);
}
body.na-tile-lock .ntp-body .flashcard-container:not(:empty) .flashcard {
  height: clamp(250px, 42vh, 380px) !important;
  max-width: 560px !important;
  box-shadow: 0 10px 26px rgba(0, 51, 102, 0.22) !important;
  cursor: pointer;
}
body.na-tile-lock .ntp-body .flashcard-container:not(:empty) .flashcard-question { font-size: clamp(16px, 1.8vw, 23px) !important; }

/* ════ LAPTOP / DESKTOP: use the full screen, scale type so the tile fills comfortably ════ */
@media (min-width: 1500px) {
  body.na-tile-lock.ntp-on .ntp-tile.ntp-active { grid-template-columns: 1.7fr 1fr; gap: 28px; padding: 22px clamp(28px, 4vw, 64px) 14px; }
  body.na-tile-lock .ntp-heading { font-size: clamp(22px, 1.7vw, 30px); }
  body.na-tile-lock .ntp-body { font-size: clamp(16px, 1.15vw, 19px); line-height: 1.62; }
  body.na-tile-lock .ntp-body .ntp-subhead { font-size: clamp(18px, 1.4vw, 22px); }
}
@media (min-width: 1900px) {
  body.na-tile-lock.ntp-on .ntp-deck { max-width: min(95vw, 1960px); }
  body.na-tile-lock .ntp-heading { font-size: clamp(24px, 1.5vw, 33px); }
  body.na-tile-lock .ntp-body { font-size: clamp(17px, 1.05vw, 21px); }
}

/* ════ CONTRAST SAFETY (brand) — additive to the rules above; never light-on-light or dark-on-dark ════ */
/* dark GREEN / TEAL inline backgrounds (brand) → KEEP them dark + force white text (else line 138 whitens them) */
body.na-tile-lock .ntp-body :is([style*="background:#006633"],[style*="background: #006633"],[style*="background:#004d40"],[style*="background: #004d40"],[style*="background:#0a5c3e"],[style*="background:#007799"],[style*="background: #007799"],[style*="background:#00557a"]) { background: #0a5c3e !important; border-left: 4px solid var(--p1-orange) !important; color: #fff !important; }
body.na-tile-lock .ntp-body :is([style*="background:#006633"],[style*="background:#004d40"],[style*="background:#0a5c3e"]) :is(p,li,span,strong,b,em,h1,h2,h3,h4,h5,h6,td,div,a) { color: #fff !important; }
body.na-tile-lock .ntp-body :is([style*="background:#007799"],[style*="background:#00557a"]) { background: #00627e !important; }
body.na-tile-lock .ntp-body :is([style*="background:#007799"],[style*="background:#00557a"]) :is(p,li,span,strong,b,em,h1,h2,h3,h4,h5,h6,td,div,a) { color: #fff !important; }
/* class-based dark cards from the cell-factory tutorials (NOT caught by inline [style] rules) → brand navy + white */
body.na-tile-lock .ntp-body :is(.agent-box,.agent-card,.factory-agent) { background: var(--p1-navy) !important; border-left: 4px solid var(--p1-orange) !important; color: #fff !important; }
body.na-tile-lock .ntp-body :is(.agent-box,.agent-card,.factory-agent) :is(p,li,span,strong,b,em,h1,h2,h3,h4,h5,h6,td,div,a) { color: #fff !important; }
/* light/muted greys (authored for dark backgrounds) → brand ink when sitting on the light tile */
body.na-tile-lock .ntp-body :is([style*="color:#94a3b8"],[style*="color: #94a3b8"],[style*="color:#a8c4dd"],[style*="color: #a8c4dd"],[style*="color:#b8d0ec"],[style*="color: #b8d0ec"],[style*="color:#cfe0f5"],[style*="color: #cfe0f5"],[style*="color:#dceafa"],[style*="color: #dceafa"],[style*="color:#cbd5e1"],[style*="color: #cbd5e1"]) { color: var(--p1-ink) !important; }

/* Tile whose image is only a PLACEHOLDER (real image not generated yet) → run text full-width (no tall empty box) */
body.na-tile-lock.ntp-on .ntp-tile.ntp-noimg.ntp-active { grid-template-columns: 1fr; }
body.na-tile-lock .ntp-tile.ntp-noimg .ntp-media { display: none; }
body.na-tile-lock .ntp-tile.ntp-noimg .ntp-col { grid-column: 1; }

/* ── narration caption + progress, docked under the image (grid row 2, column 1) ──────────
   Replaces the fixed bottom-centred overlay. Two rules matter:
     · it occupies its OWN grid row, so it cannot sit on the image or the body text
     · it is column 1 only, so the text column is untouched
   Tiles with no media (quiz / text-only) fall back to the old fixed position — see
   .ntp-capdock--full — because there is no image to sit under. */
/* Caption + progress, docked UNDER THE PLAYER (owner call). Fixed just above the control
   bar and full width, so it is identical on image, text and quiz tiles. setBottom() adds its
   height to --ntp-bottom, so the deck is pinned above it and it cannot overlap the tile.
   Font is deliberately small — this is a subtitle, not a second body column. */
body.na-tile-lock .ntp-capdock {
  position: fixed; left: 0; right: 0; bottom: var(--ntp-controls-h, 64px); z-index: 59;
  display: none; flex-direction: column; gap: 5px;
  padding: 7px clamp(12px, 3vw, 40px) 8px;
  background: rgba(250,248,245,.98); border-top: 1px solid rgba(0,51,102,.12);
}
body.na-tile-lock .ntp-capdock.on { display: flex; }
body.na-tile-lock .ntp-capdock .ntp-caption {
  position: static; transform: none; bottom: auto; left: auto;
  width: 100%; max-width: 1100px; margin: 0 auto;
  background: transparent; color: var(--p1-ink, #111827); border: 0;
  font-size: clamp(12px, 1.02vw, 14px); line-height: 1.45; font-weight: 500;
  padding: 0; border-radius: 0; text-align: center; box-shadow: none;
  /* long segments are clamped rather than allowed to grow the chrome and squeeze the tile */
  max-height: 4.4em; overflow-y: auto;
}
/* Text-only and quiz tiles have no image to sit under, so the dock spans the full tile width
   on its own row BENEATH the text. It used to float over the text, which was the original
   complaint in a different place. In flow it cannot overlap anything. */
body.na-tile-lock .ntp-tile.ntp-nomedia .ntp-col { grid-row: 1; }
body.na-tile-lock .ntp-capdock--full { grid-column: 1 / -1; grid-row: 2; }

/* progress: a track with a fill and a visible pointer riding its leading edge, so the
   learner can see how far through the narration this tile is. The 4px line pinned to the
   very bottom edge of the window was easy to miss entirely. */
body.na-tile-lock .ntp-prog { position: relative; width: 100%; max-width: 1100px; margin: 0 auto; height: 6px; border-radius: 999px;
  background: rgba(0,51,102,.14); overflow: visible; }
body.na-tile-lock .ntp-prog-fill { height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, #ff9900, #ffb347); transition: width .12s linear; }
body.na-tile-lock .ntp-prog-thumb { position: absolute; top: 50%; left: 0; width: 15px; height: 15px;
  margin-left: -7.5px; border-radius: 50%; background: #ff9900; border: 2.5px solid #fff;
  box-shadow: 0 0 0 3px rgba(255,153,0,.30), 0 1px 4px rgba(0,0,0,.35);
  transform: translateY(-50%); transition: left .12s linear; }
body.na-tile-lock .ntp-prog-thumb::after { content: ""; position: absolute; inset: -3px;
  border-radius: 50%; animation: ntp-anno-pulse 1.4s ease-out infinite; }

/* read-pause prompt: was position:absolute inside .ntp-anno, i.e. a navy pill sitting ON the
   bottom of the artwork. It now rides in the caption dock with everything else. */
body.na-tile-lock .ntp-capdock .ntp-readpause { position: static; transform: none;
  left: auto; bottom: auto; display: inline-block; align-self: center; }
