/* The village is the page, with a quiet margin for the current conversation. */
.world-mode .mast { max-width: 1600px; padding-top: 20px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.world-mode .quest-main { max-width: 1600px; display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(320px, 1fr); gap: 0 40px; padding-bottom: 36px; }
.world-mode #questEye { grid-column: 1 / -1; margin-top: 26px; font-size: 11px; }
.world-mode #questTitle { grid-column: 1 / -1; font-size: 44px; line-height: 1.15; margin: 8px 0 8px; }
.world-mode #questFixes { grid-column: 1 / -1; font-size: 17px; margin: 0 0 20px; }
.world-mode #questKept { grid-column: 1 / -1; font-size: 12px; margin: 0; color: var(--ink-soft); }
.world-mode .quest-conversation { grid-column: 2; grid-row: 5; margin-top: 42px; min-width: 0; }
.world-mode #questWhere { margin: 0 0 14px; font-size: 12px; }
.world-mode .class-link-row { grid-column: 2; grid-row: 5; margin: 0; }
.world-mode #questProblem { grid-column: 2; margin-top: 0; }
.world-mode .quest-beat { grid-column: 2; grid-row: 7; margin: 12px 0 0; padding: 0 0 20px; border: 0; border-radius: 0; background: transparent; min-width: 0; }
.world-mode .guide-line { font-size: 24px; line-height: 1.45; max-width: none; }
.world-mode .beat-acts { margin-top: 18px; }
.world-mode .beat-foot { margin-top: 16px; }
.world-mode .check-row { flex-wrap: wrap; gap: 8px; }
.world-mode .check-row input { width: 6em; min-height: 50px; border-radius: 6px; font-size: 24px; }
.world-mode .check-unit { font-size: 16px; max-width: 160px; }
.world-mode .beat-body textarea { border-radius: 6px; font-family: var(--sans); font-size: 17px; }
.world-mode .parts-card { padding: 0; border: 0; background: transparent; }
.world-mode .part { border-radius: 6px; }
.world-mode .sim-frame { border-radius: 6px; aspect-ratio: auto; height: 365px; max-height: none; }
.world-mode .sim-values { font-size: 12px; }
.world-mode .beat-link { font-size: 14px; }
.world-mode .world-diagram { margin: 0 0 16px; }
.world-mode .world-diagram summary { font-size: 14px; color: var(--ink-soft); cursor: pointer; padding: 8px 0; }
.world-mode .world-diagram .beat-figure { margin: 6px 0 16px; }
.world-mode .world-diagram img { border-radius: 4px; }
.world-mode button:focus-visible, .world-mode a:focus-visible, .world-mode summary:focus-visible, .world-mode textarea:focus-visible { outline: 3px solid var(--oxblood); outline-offset: 4px; }
.quest-world { grid-column: 1; grid-row: 5; min-width: 0; position: sticky; top: 16px; align-self: start; margin-top: 24px; }
.world-caption { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink); }
.world-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--oxblood); }
.world-location { margin-left: auto; color: var(--ink-soft); font-size: 12px; }
.world-stage { position: relative; width: 100%; height: min(64vh, 620px); min-height: 340px; }
.world-stage canvas { width: 100%; height: 100%; display: block; cursor: pointer; }
.world-fallback { position: absolute; inset: 0; }
.world-fallback img { width: 100%; height: 100%; object-fit: contain; }
.world-fallback p { position: absolute; left: 0; bottom: 0; font-size: 12px; }
.world-hotspots { position: absolute; inset: 0; pointer-events: none; }
.world-spot { position: absolute; display: flex; align-items: center; gap: 6px; border: 1px solid #d4cbb9; border-radius: 5px; padding: 7px 9px; background: #fffcf4; color: var(--ink); font: 500 12px var(--sans); white-space: nowrap; box-shadow: 0 3px 10px #173a3210; pointer-events: auto; min-height: 36px; }
.world-spot::after { content: ""; position: absolute; bottom: -5px; left: calc(50% - 4px); width: 8px; height: 8px; background: #fffcf4; border-right: 1px solid #d4cbb9; border-bottom: 1px solid #d4cbb9; transform: rotate(45deg); }
.world-spot svg { width: 16px; height: 16px; }
.world-spot:hover { background: var(--ink); color: var(--paper); }
.world-spot:hover::after { background: var(--ink); }
.world-nav { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; border-top: 1px solid var(--line); padding-top: 12px; }
.world-nav button { display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 8px 10px; border: 0; border-radius: 5px; background: transparent; color: var(--ink-soft); font: 500 12px var(--sans); }
.world-nav button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.world-nav button:hover { background: #e6e7d9; color: var(--ink); }
.world-nav svg, .mirror-open svg { width: 18px; height: 18px; flex-shrink: 0; }
.world-status { min-height: 2.8em; margin: 10px 0 0; text-align: center; font-size: 12px; }
.world-flat .world-hotspots { position: static; display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-top: -12px; }
.world-flat .world-spot { position: static; transform: none; }
.world-flat .world-spot::after { display: none; }
.world-flat .world-stage { margin-bottom: 48px; }
.mirror-open { display: inline-flex; align-items: center; gap: 9px; margin: 4px 0; }
.code-bench { width: min(900px, calc(100% - 28px)); max-height: calc(100dvh - 28px); padding: 26px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--paper); color: var(--ink); overflow-y: auto; box-shadow: 0 20px 90px #173a3230; }
.code-bench::backdrop { background: #173a3255; }
.code-bench header { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.code-bench .eye { font-size: 11px; }
.code-bench h2 { font: 500 34px/1.2 var(--serif); margin: 5px 0; }
.code-close { border: 1px solid var(--line); background: transparent; color: var(--ink); border-radius: 50%; width: 44px; height: 44px; flex-shrink: 0; font-size: 28px; }
.code-question { font: 400 21px var(--serif); margin: 12px 0 20px; }
.code-columns { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 24px; }
.code-editor { min-width: 0; }
.code-editor label { display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px; }
.code-editor label span { color: var(--ink-soft); }
.code-editor textarea { width: 100%; height: 310px; box-sizing: border-box; padding: 18px; border: 1px solid var(--line-strong); border-radius: 5px; background: #fffcf4; color: var(--ink); font: 14px/1.8 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre; resize: vertical; tab-size: 4; }
.code-controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; }
.code-controls .btn { min-height: 44px; padding: 10px 18px; font-size: 14px; }
.code-controls .tool { font-size: 13px; }
.code-result { min-width: 0; padding: 20px 12px; border-left: 1px solid var(--line); }
.code-result p { font-size: 15px; }
.code-result output { display: block; min-height: 24px; font: 12px/1.6 ui-monospace, monospace; margin: 8px 0 16px; }
.code-result details { margin-top: 20px; font-size: 12px; }
.code-result ol { max-height: 140px; overflow-y: auto; padding-left: 24px; }
.code-result pre { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12px; max-height: 180px; overflow-y: auto; }
.mirror-lamp { width: 90px; height: 155px; position: relative; margin: 0 auto 22px; border-bottom: 8px solid var(--ink); }
.mirror-lamp::before { content: ""; position: absolute; left: 43px; top: 30px; width: 5px; height: 120px; background: var(--ink); }
.mirror-lamp span { display: block; position: absolute; top: 12px; left: 18px; width: 54px; height: 56px; border: 4px solid var(--ink); border-radius: 18px 18px 4px 4px; background: #dfd9cb; }
.mirror-lamp[data-lit="true"] span { background: #e5b855; box-shadow: 0 0 28px #e5b85550; }
#codeScope { margin: 18px 0 0; font-size: 12px; }
@media (min-width: 1500px) { .world-mode .quest-main { gap: 0 56px; } }
@media (max-width: 900px) {
  .world-mode .quest-main { grid-template-columns: minmax(0, 1.25fr) minmax(280px, 1fr); gap: 0 22px; }
  .world-mode #questTitle { font-size: 36px; }
  .world-mode .guide-line { font-size: 22px; }
  .world-spot span { display: none; }
}
@media (max-width: 680px) {
  .world-mode .mast { padding-top: 12px; padding-bottom: 12px; }
  .world-mode .quest-main { display: flex; flex-direction: column; padding-bottom: 24px; }
  .world-mode #questEye { order: 0; margin-top: 16px; }
  .world-mode #questTitle { order: 1; font-size: 32px; margin-top: 6px; }
  .world-mode #questFixes { order: 2; font-size: 15px; margin-bottom: 8px; }
  .world-mode #questKept { order: 3; font-size: 11px; }
  .world-mode .quest-conversation { order: 5; margin-top: 18px; }
  .quest-world { position: relative; top: 0; order: 4; margin-top: 14px; width: 100%; }
  .world-caption { font-size: 10px; }
  .world-location { font-size: 10px; }
  .world-stage { height: 250px; min-height: 0; }
  .world-nav { gap: 2px; padding-top: 6px; }
  .world-nav button { gap: 5px; padding: 6px 8px; font-size: 11px; min-height: 44px; }
  .world-nav svg { width: 16px; height: 16px; }
  .world-spot { min-height: 44px; min-width: 44px; justify-content: center; }
  .world-spot svg { width: 18px; height: 18px; }
  .world-status { min-height: 0; margin: 0; }
  .world-status:not(:empty) { margin-top: 10px; }
  .world-mode #questWhere { order: 5; align-self: start; margin: 18px 0 4px; }
  .world-mode .class-link-row { order: 6; }
  .world-mode .quest-beat { order: 7; margin-top: 4px; padding: 0; }
  .world-mode #questProblem { order: 8; }
  .world-mode .guide-line { font-size: 20px; line-height: 1.4; }
  .world-mode .beat-acts { margin-top: 14px; }
  .code-bench { padding: 18px; }
  .code-columns { grid-template-columns: 1fr; gap: 16px; }
  .code-editor textarea { height: 270px; font-size: 13px; padding: 12px; }
  .code-result { display: grid; grid-template-columns: 82px 1fr; align-items: start; gap: 0 16px; padding: 12px 0; border-left: 0; border-top: 1px solid var(--line); }
  .mirror-lamp { grid-row: 1 / 5; transform: scale(0.65); transform-origin: top left; margin: 0; height: 145px; }
  .code-result p, .code-result output, .code-result details, .code-result button { grid-column: 2; margin-top: 4px; }
}
@media (prefers-reduced-motion: reduce) { .world-mode *, .world-mode *::before, .world-mode *::after { scroll-behavior: auto !important; transition: none !important; animation: none !important; } }

/* Whose turn it is. One steady highlight on the object the current beat
   belongs to, an outline a person can see without colour, and nothing that
   blinks. Every other object stays quiet; a finished one stays visitable. */
.world-spot[aria-current="step"] {
  border-color: var(--oxblood);
  outline: 2px solid var(--oxblood);
  outline-offset: 2px;
  background: color-mix(in srgb, var(--lemon) 55%, #fff);
  color: var(--ink);
}
.world-spot.spot-done { opacity: .85; }
.world-spot.spot-done svg { color: var(--leaf); }

/* One sheet, over the village, with the beat's own picture in it. */
.world-sheet { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; padding: 14px; background: color-mix(in srgb, var(--ink) 38%, transparent); }
.world-sheet[hidden] { display: none; }
.sheet-card { display: grid; gap: 10px; width: min(560px, 100%); max-height: 100%; overflow: auto; padding: 16px 18px; border: 1.5px solid var(--line-strong); border-radius: 16px; background: var(--paper); }
.sheet-title { margin: 0; font: 600 20px/1.2 var(--serif); }
.sheet-figure { margin: 0; display: grid; gap: 6px; }
.sheet-figure img { display: block; width: 100%; max-height: 42vh; object-fit: contain; border: 1px solid var(--line); border-radius: 10px; background: #fff; }
.world-sheet.zoomed .sheet-figure img { max-height: none; }
.sheet-figure figcaption { color: var(--ink-soft); }
.sheet-acts { flex-wrap: wrap; gap: 8px; }
@media (max-width: 640px) {
  .sheet-card { width: 100%; padding: 12px 14px; }
  .sheet-figure img { max-height: 34vh; }
}

/* ---------------------------------------------------------- the tutor is here */
/* A tutor who joined this chapter, and the one object they pointed at. Steady,
   ten seconds, and it never touches the beat the child is on. */
/* The tutor's arrival, beside the village they arrived in. `world-location`
   already takes the free space, so this sits after it. */
.world-caption .world-presence { padding-left: 14px; color: var(--ink); font-weight: 600; font-size: 12px; }
.world-spot.spot-pointed { outline: 2px dashed var(--teal, #2f6f6a); outline-offset: 3px; }

/* The stage: the left of the page is the work (2026-09-25, the founder: "make it show as a picture page on the left instead of mission when there are images involved"). */
.world-mode .quest-stage { grid-column: 1; grid-row: 5; min-width: 0; align-self: start; margin-top: 24px; }
/* The village sits under whatever the beat is showing, not behind it. */
/* The village stands where a picture would, not under it: only one of them is
   ever on screen (see paintStage), so they share the one place on the left. */
.world-mode .quest-world { grid-column: 1; grid-row: 5; position: static; margin-top: 24px; }
.world-mode .quest-stage .beat-figure { margin: 0; background: var(--white); border: 1px solid var(--line); border-radius: 8px; padding: 18px; }
.world-mode .quest-stage img { display: block; width: 100%; height: auto; border-radius: 4px; }
.world-mode .quest-stage figcaption { margin-top: 10px; color: var(--ink-soft); }
.world-mode .quest-stage .sim-frame { height: min(560px, 62vh); border-radius: 8px; }
.world-mode .quest-stage .sim-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.world-mode.website-bench-mode .quest-stage { grid-column: 1 / -1; width: 100%; }
.world-mode.website-bench-mode .quest-conversation { grid-column: 1 / -1; grid-row: 6; width: 100%; max-width: 1244px; margin: 16px auto 0; }
.website-bench-mode #beatText { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* A sim never gets less than 360px on a small screen: below that a staff's note heads sit closer than a finger, and a
   round's buttons fall past the frame's edge (found with the note reader at 282px). */
@media (max-width: 900px) { .world-mode .quest-stage { order: 2; position: static; margin-top: 12px; } .world-mode .quest-stage .sim-frame { height: max(360px, 46vh); } }

/* The mirror opens on the whole screen until Back (2026-09-25: "when i click on the mirror it should open on the whole screen till you hit back"). */
.code-bench { width: 100%; max-width: none; height: 100dvh; max-height: none; border: 0; border-radius: 0; padding: 22px clamp(16px, 5vw, 56px); }
.code-bench .code-close { font-size: 15px; }

/* A generated mission's world (story-world.js): the beat's drawn picture is a print from the visit, framed. */
.story-card { width: min(52%, 400px); margin: 18px auto 0; padding: 6px 6px 4px; background: #fffcf4; border: 1px solid #d4cbb9; border-radius: 6px; box-shadow: 0 6px 18px rgba(23, 58, 50, .16); transform: rotate(1.2deg); }
.story-card button { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.story-card img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 3px; }
.story-card figcaption { margin: 4px 2px 0; font-size: 11px; line-height: 1.3; color: var(--ink-soft); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.story-world .world-spot[aria-current="step"] { background: var(--ink); color: var(--paper); }
.story-world .world-spot[aria-current="step"]::after { background: var(--ink); }
.story-world .world-spot.spot-done { opacity: .72; }
@media (max-width: 700px) { .story-card { width: min(80%, 400px); } }
/* Everything in one screen (the founder, 2026-10-08): the picture is inside the place's own frame, never a card under it.
   Pinned small in the frame's top left corner, or, when it first comes or is pressed, whole over the paper, and back. */
.story-world .world-stage .story-card { position: absolute; left: 10px; top: 10px; z-index: 4; width: min(30%, 220px); margin: 0; }
.story-world .world-stage .story-card.is-full { inset: 3% 5%; width: auto; display: flex; flex-direction: column; transform: none; animation: story-card-in .45s ease both; }
.story-world .world-stage .story-card.is-full button { flex: 1; min-height: 0; cursor: zoom-out; }
.story-world .world-stage .story-card.is-full img { height: 100%; aspect-ratio: auto; object-fit: contain; }
.story-world .world-stage .story-card.is-full figcaption { font-size: 14px; -webkit-line-clamp: 3; }
@keyframes story-card-in { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .story-world .world-stage .story-card.is-full { animation: none; } }
@media (max-width: 700px) { .story-world .world-stage .story-card { width: min(34%, 160px); } }
/* A word of the line that names a thing on the stage, in that thing's colour (story-world.js, STAGE_TEXT_HEX): the ink a child
   can read on the paper and on the lit lemon, with the paint itself underneath. A word naming things of more than one colour
   is underlined in dots, in the line's own ink. */
.guide-line .w.stage-word { color: var(--stage-ink, inherit); text-decoration: underline dotted currentColor; text-decoration-thickness: .1em; text-underline-offset: .18em; }
.guide-line .w.stage-word[data-stage-colour] { text-decoration: underline solid var(--stage-paint); text-decoration-thickness: .16em; }
.guide-line .w.stage-word[data-stage-colour="white"] { text-decoration-color: #c8bfae; }
/* The village's narrow-screen rule hides a label's words and keeps its icon. The story world draws no icons, so that
   rule left empty boxes on a phone and an iPad in portrait; here a label keeps its words, smaller, and placement
   (story-world.js onAnchors) keeps labels off one another and off the zoom button. */
@media (max-width: 900px) { .story-world .world-spot span { display: inline; } }
@media (max-width: 680px) { .story-world .world-spot { min-height: 36px; min-width: 0; padding: 6px 8px; font-size: 11px; } }

/* The mission's camera (story-world.js): a button to see the whole place or look closer, and the beat unfolding from the thing it happens at. */
.world-zoom { position: absolute; top: 8px; right: 8px; z-index: 4; min-height: 36px; padding: 7px 12px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .55); background: rgba(23, 30, 28, .62); color: #fff; font: 600 12px/1 var(--sans); cursor: pointer; backdrop-filter: blur(4px); }
.world-zoom:hover, .world-zoom:focus-visible { background: rgba(23, 30, 28, .8); }
.world-mode #questBeat.unfold { animation: beat-unfold .52s cubic-bezier(.2, .8, .2, 1) both; transform-origin: var(--from-x, 50%) 0; }
@keyframes beat-unfold {
  from { opacity: 0; transform: translateY(-22px) scale(.88); clip-path: inset(0 0 72% 0 round 22px); }
  55% { opacity: 1; }
  to { opacity: 1; transform: none; clip-path: inset(0 0 0 0 round 0); }
}
@media (prefers-reduced-motion: reduce) { .world-mode #questBeat.unfold { animation: none; } }

/* A beat's stage (story-world.js, stage.ts): the maths big in the middle of its place. The labels of the place's
   things step aside; over the picture, the equation the objects count up into (at the foot), the one readout (at
   the head, or one digit over each place column) and the columns' names under them. */
.stage-world .world-hotspots { display: none; }
/* The stage said in words is for a child who cannot see it: read out, not printed under the picture. */
.stage-world .world-status { position: absolute; width: 1px; height: 1px; min-height: 0; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.stage-words { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.stage-equation { position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%); margin: 0; display: flex; gap: .32em; align-items: baseline; padding: 6px 18px; border-radius: 12px; background: color-mix(in srgb, var(--paper) 88%, transparent); font: 600 46px/1.1 var(--serif); color: var(--ink); white-space: nowrap; }
.stage-equation[hidden] { display: none; }
.stage-equation span { opacity: 0; min-width: .55em; text-align: center; transition: opacity .2s; }
.stage-equation span.is-on { opacity: 1; }
.stage-equation .eq-op { color: var(--ink-soft); font-weight: 400; }
.stage-equation .eq-ask { padding: 0 .28em; border-radius: 10px; background: var(--lemon); }
.stage-equation .is-counting { color: var(--oxblood); }
.stage-readout { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); margin: 0; font: 600 58px/1 var(--serif); color: var(--oxblood); opacity: 0; transition: opacity .35s; }
.stage-readout[hidden] { display: none; }
.stage-readout.is-on { opacity: 1; }
.stage-readout.by-place { inset: 0; transform: none; }
.stage-readout.by-place span { position: absolute; transform: translate(-50%, -100%); }
.stage-column { position: absolute; transform: translate(-50%, 0); padding: 2px 7px; border-radius: 6px; background: var(--paper); color: var(--ink-soft); font: 600 13px/1.3 var(--sans); white-space: nowrap; }
.stage-column.is-lit { background: var(--lemon); color: var(--ink); }
@media (max-width: 680px) {
  .stage-world .world-stage { height: 330px; }
  .stage-equation { bottom: 8px; padding: 4px 12px; font-size: 32px; }
  .stage-readout { font-size: 40px; }
  .stage-column { font-size: 11px; padding: 1px 5px; }
}
@media (prefers-reduced-motion: reduce) { .stage-equation span, .stage-readout { transition: none; } }
