/* The lesson overlay and everything inside it: teaching panels, questions,
   feedback, the simulator, and the dialogs that interrupt it. */

#lesson{position:fixed;inset:0;background:var(--panel);z-index:40;display:none;
 flex-direction:column;overflow-y:auto;-webkit-overflow-scrolling:touch;}

/* No visible scrollbars, anywhere. An overflow container whose content already
   fits still flashes a bar the moment a finger touches it, which reads as a
   scroll that is broken — reported on the final-test screen, and again on other
   screens once the first fix only covered the containers it happened to name.
   A list of selectors could never be complete, so this matches everything:
   any element that scrolls now, or is added later, is covered. Content that is
   genuinely longer still scrolls; only the indicator is gone, which is the
   phone convention. */
*{scrollbar-width:none;-ms-overflow-style:none;}
*::-webkit-scrollbar{width:0;height:0;display:none;}
/* Framed to the app column on a wide window, but still fixed to the window.
   `position:absolute` did the framing for free and cost the thing that
   matters: an absolutely positioned box is sized by its containing block, and
   #app is as tall as the path behind it, so the overlay opened wherever the
   page happened to be scrolled to. Third time for this exact bug — #gate and
   #placement had it before. Same frame as #placement, for the same reason. */
@media(min-width:520px){
  #lesson{left:50%;right:auto;width:480px;transform:translateX(-50%);
          top:24px;bottom:24px;border-radius:20px;}
}
#lesson.show{display:flex;}
.l-head{display:flex;align-items:center;gap:10px;padding:calc(13px + var(--sat)) 16px 13px;
  border-bottom:1px solid var(--line);
  position:sticky;top:0;background:var(--panel);z-index:5;}
.x-btn{width:31px;height:31px;border-radius:8px;border:1px solid var(--line);background:var(--panel);
  display:flex;align-items:center;justify-content:center;cursor:pointer;}
.x-btn svg{width:15px;height:15px;color:var(--ink-soft);}
.l-track{flex:1;height:7px;background:var(--locked-bg);border-radius:6px;overflow:hidden;}
.l-fill{height:100%;background:var(--blue);transition:width .3s;}
.tier-pip{font-size:9.5px;font-weight:700;letter-spacing:.5px;padding:3px 7px;border-radius:5px;
  background:var(--tint);color:var(--blue-deep);}
.l-body{padding:20px;flex:1;}
/* Circuit diagrams. currentColor throughout, so the schematic follows the
   theme instead of pinning a colour that breaks in dark mode. */
.dia{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;
  padding:10px 8px;margin:12px 0;color:var(--ink);overflow-x:auto;text-align:center;}
.dia svg{display:block;margin:0 auto;}
.q-text .dia{margin:14px 0 4px;}

.teach{background:var(--surface-2);border:1px solid var(--line);border-radius:14px;padding:16px;
  font-size:14.5px;line-height:1.6;margin-bottom:16px;}
.teach b{color:var(--blue-deep);}
/* The E/I/R/P grid from Module 4. Every colour comes from the theme, and the
   whole table scrolls sideways rather than squeezing on a narrow phone —
   squeezed, its columns stop lining up with the components they name. */
.teach .eirp{border-collapse:collapse;margin:14px 0;font-family:'IBM Plex Mono',monospace;
  font-size:12px;display:block;overflow-x:auto;white-space:nowrap;}
.teach .eirp th,.teach .eirp td{border:1px solid var(--line);padding:5px 9px;text-align:right;}
.teach .eirp th{background:var(--tint);color:var(--blue-deep);font-weight:700;text-align:center;}
.teach .eirp tr th:first-child{text-align:center;}
/* The colour code from Module 6. The swatches are the one place a colour is
   the content, so they use the band variables — and every swatch is named in
   text beside it, because a table that can only be read in colour is a table
   some people cannot read. */
.teach .colours{border-collapse:collapse;margin:14px 0;font-size:12.5px;}
.teach .colours td{padding:3px 10px 3px 0;white-space:nowrap;}
.teach .colours td i{display:inline-block;width:12px;height:12px;border-radius:3px;
  border:1px solid var(--line);margin-right:7px;vertical-align:-2px;}

.analogy{background:var(--tint-warm);border-left:3px solid var(--amber);border-radius:0 10px 10px 0;
  padding:12px 14px;font-size:13.5px;line-height:1.55;margin-bottom:16px;color:var(--ink);}
.analogy strong{color:var(--amber-text);}

.warnbox{background:var(--tint-warn);border-left:3px solid var(--coral);border-radius:0 10px 10px 0;
  padding:12px 14px;font-size:13px;line-height:1.55;margin-bottom:16px;color:var(--ink);}
.q-text{font-size:15px;font-weight:600;margin-bottom:14px;line-height:1.45;}
.feedback{margin-top:11px;padding:11px 13px;border-radius:10px;font-size:13.5px;line-height:1.5;}
.feedback.good{background:var(--tint-warm);color:var(--amber-text);}
.feedback.bad{background:var(--tint-warn);color:var(--coral-text);}
.numrow{display:flex;gap:8px;margin-bottom:11px;align-items:center;}
.numrow input{flex:1;padding:12px 14px;border-radius:10px;border:1.5px solid var(--line);
  font-size:15px;font-family:'IBM Plex Mono',monospace;}
.unit{font-family:'IBM Plex Mono',monospace;color:var(--ink-soft);font-size:14px;}

/* The boxes the app asks you to type into: passwords, and the fields on the
   screen an emailed link lands on. It was written for backup codes, which
   are gone -- a textarea rather than a prompt(), because an Android WebView
   renders prompt() as a system dialog that truncates a long string and gives
   no reliable way to copy it. The reason still holds for what is left. */
.code-box{width:100%;box-sizing:border-box;padding:11px 12px;border-radius:10px;
  border:1.5px solid var(--line);background:var(--panel);color:var(--ink);
  font-family:'IBM Plex Mono',monospace;font-size:12px;line-height:1.5;
  resize:vertical;margin:8px 0;}
.code-msg{font-size:13px;margin:6px 0 0;min-height:18px;}
.code-msg.good{color:var(--teal-text);}
.code-msg.bad{color:var(--coral-text);}

/* simulator */

.sim{background:var(--sim-bg);border-radius:14px;padding:17px;color:#E9ECF6;margin-bottom:15px;}
.sim-row{margin-bottom:14px;}
.sim-row label{display:block;font-size:11.5px;color:#9AA3C0;margin-bottom:6px;font-weight:600;}
.sim-row input[type=range]{width:100%;}
.sim-val{float:right;font-family:'IBM Plex Mono',monospace;font-size:12.5px;color:var(--amber);}
.sim-row input[type=number]{width:100%;padding:10px 12px;border-radius:8px;border:none;
  font-family:'IBM Plex Mono',monospace;font-size:14px;background:#1C2038;color:#F0EAE0;}
.meter{background:#000;border-radius:8px;padding:13px;text-align:center;margin-top:9px;
  font-family:'IBM Plex Mono',monospace;font-size:25px;color:#39FF88;border:2px solid #2A2E4A;}
.meter.dim{color:#6E7690;}
.circuit-svg{width:100%;height:auto;margin-bottom:12px;background:var(--sim-bg);border-radius:10px;padding:8px;}

.done-wrap{text-align:center;padding:28px 20px;}
.done-ring{width:80px;height:80px;border-radius:50%;margin:0 auto 16px;
  background:linear-gradient(135deg,var(--amber),var(--amber-deep));display:flex;align-items:center;justify-content:center;}
.done-ring svg{width:38px;height:38px;color:var(--on-accent);}
.xp-pill{display:inline-block;margin-top:9px;padding:6px 14px;border-radius:20px;background:var(--tint);
  color:var(--blue-deep);font-weight:700;font-size:13px;font-family:'IBM Plex Mono',monospace;}

#ad-modal{position:fixed;inset:0;background:rgba(var(--scrim-ink),.93);z-index:55;display:none;
  align-items:flex-start;justify-content:center;overflow-y:auto;
  padding:calc(64px + var(--sat)) 24px calc(24px + var(--sab));}
#ad-modal.show{display:flex;}
/* Was position:absolute here, which put the scrim inside #app and so let the
   ad open above or below the visible part of a long page. A scrim's whole job
   is to cover the window, so on a wide screen it now does. */
@media(min-width:520px){#ad-modal{padding-top:80px;}}
/* In-app confirm. window.confirm() renders as a stock Android system dialog
   that looks nothing like the app and ignores the theme. */
#ask{position:fixed;inset:0;background:rgba(var(--scrim-ink),.55);z-index:70;display:none;
  align-items:center;justify-content:center;
  padding:calc(24px + var(--sat)) 24px calc(24px + var(--sab));}
#ask.show{display:flex;}
/* This one was the worst of the three. #ask gates every destructive action —
   'Delete all progress?', 'Last chance', 'Sign out?' — and those buttons are
   at the bottom of a long Settings screen. As position:absolute the dialog
   centred inside #app rather than in the window, so on any screen wide enough
   to hit this rule you tapped Delete, the page dimmed, and the dialog was
   several hundred pixels above the fold: the app looked frozen, and the
   promise ask() returns stayed unresolved until you thought to scroll up.
   A confirm dialog belongs in the middle of the window. Nothing here now
   overrides the position. */
.ask-box{background:var(--panel);color:var(--ink);border:1px solid var(--line);
  border-radius:16px;padding:24px 22px;width:100%;max-width:320px;
  box-shadow:0 18px 40px rgba(var(--scrim-ink),.28);}
.ask-box h3{margin:0 0 9px;font-size:16.5px;font-family:'Space Grotesk',sans-serif;}
.ask-box p{margin:0 0 18px;font-size:13.5px;line-height:1.55;color:var(--ink-soft);}
.ask-box .btn+.btn{margin-top:9px;}

.ad-box{background:#1C2038;border-radius:16px;padding:32px 24px;width:100%;max-width:280px;color:#fff;text-align:center;}
.ad-box .tag{font-size:9.5px;letter-spacing:1px;color:#8A91B5;margin-bottom:10px;}
.ad-box h3{margin:0 0 8px;font-size:17px;} .ad-box p{font-size:12.5px;color:#9AA3C0;margin:0 0 18px;}
.ad-count{font-family:'IBM Plex Mono',monospace;font-size:12.5px;color:#F2B455;margin-bottom:13px;}
