/* tutorial.css — the walkthrough that runs on top of the real desk view.
 *
 * A TENTH OF A DIM, AND NOT A MODAL
 * The page is dimmed by ten percent while the walkthrough is running, and no
 * more than that. Enough that a white card, a blue ring and the line between
 * them sit forward of the page rather than in it; not enough to stop somebody
 * reading the table the bubble is talking about, which is still the only job a
 * coach mark has. The one time the page really goes dark is the iPad interlude,
 * where the subject genuinely is somewhere else.
 *
 * WHY THERE IS A LINE
 * A card beside a ring is two marks the reader has to associate. A card, a
 * ring, and a line from one to the other is one mark. It matters most where the
 * bubble had to be moved to fit — the line is what keeps "this text is about
 * that tile" true after the layout has had its say.
 *
 * NO INLINE STYLE
 * Positions are set through the CSSOM from js/tutorial.js, never as a style
 * attribute written into markup, so the page is served under the same
 * `style-src 'self'` policy as the rest of the application.
 *
 * Loaded only by the preview build. Nothing in the application depends on it,
 * and its absence changes nothing.
 */

/* ---------------- timing, in one place ----------------
   Three durations and one curve, reused by every entrance and fade below.
   Before this they were each picked separately — a bubble arriving on one
   easing while its ring arrived on another, a scrim taking half a second to
   fade while the tablet under it took slightly longer — and the mismatch
   read as sloppiness even though no single number was wrong. */
:root {
  --tut-ease: cubic-bezier(.2, .8, .3, 1);
  --tut-fast: .18s;   /* toasts, the panel — things that are not the main event */
  --tut-base: .3s;    /* rings, lines, notes, the two progress fills */
  --tut-slow: .45s;   /* the dim, the scrim, the iPad — the page-level fades */
}

/* Every ring, line and card is placed once, from getBoundingClientRect() at
   the moment it is drawn, and never repositioned. The page scrolling under a
   bubble does not move the bubble with it — it only makes the two disagree
   about where the anchor is. Locked for exactly the run's duration: set and
   cleared from js/tutorial.js's lockScroll(), never left standing. */
html.tut-scroll-lock, html.tut-scroll-lock body { overflow: hidden; }

/* ---------------- the dim ---------------- */

.tut-dim {
  position: fixed; inset: 0; z-index: 820;
  background: #0c1119;
  opacity: 0; pointer-events: none;
  transition: opacity var(--tut-slow) var(--tut-ease);
}
.tut-dim.is-on { opacity: .10; }

/* ---------------- annotations ---------------- */

/* Above the interlude, not below it.
   The scrim and the tablet are drawn over the whole page, so a note layer
   underneath them is a note layer nobody can read during the one part of the
   walkthrough that most needs narrating. Everything is stacked in the order it
   has to be read: page, dim, scrim, tablet, notes, presses, transport. */
.tut-layer {
  position: fixed; inset: 0; z-index: 850;
  pointer-events: none;
}

/* The leader lines share one canvas, sized to the window, so the geometry in
   js/tutorial-place.js can be written in the same viewport coordinates
   getBoundingClientRect() hands back. */
.tut-lines {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible; pointer-events: none;
}
.tut-line {
  stroke: var(--brand);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 5 4;
  opacity: .85;
  animation: tut-line-in var(--tut-base) var(--tut-ease) .06s both;
}
.tut-line-dot { fill: var(--brand); animation: tut-line-in var(--tut-base) var(--tut-ease) .12s both; }
@keyframes tut-line-in { from { opacity: 0; } to { opacity: .85; } }

.tut-ring {
  position: absolute;
  border: 2px solid var(--brand);
  border-radius: 10px;
  box-shadow: 0 0 0 4px rgb(15 94 168 / .14);
  animation: tut-ring-in var(--tut-base) var(--tut-ease) both;
}
@keyframes tut-ring-in {
  from { opacity: 0; transform: scale(1.035); }
  to   { opacity: 1; transform: scale(1); }
}

.tut-note {
  position: absolute;
  width: min(330px, calc(100vw - 28px));
  background: var(--surface);
  border: 1px solid var(--brand-line);
  border-radius: var(--radius-lg);
  box-shadow: 0 2px 6px rgb(19 26 36 / .10), 0 14px 40px rgb(19 26 36 / .16);
  padding: 15px 17px;
  font-size: .875rem; line-height: 1.55; color: var(--text-2);
  pointer-events: auto;
  /* Placed by script; until then it is measured off-screen rather than flashing
     in the top-left corner of the page. */
  left: -9999px; top: -9999px;
  opacity: 0;
}
.tut-note.tut-note-placed { animation: tut-note-in var(--tut-base) var(--tut-ease) .05s both; }
@keyframes tut-note-in {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: translateY(0); }
}
.tut-note strong { color: var(--text); font-weight: 600; }
.tut-note-body { display: block; }

/* A remark with no particular anchor — about the screen rather than a control. */
/* Centred with `translate` rather than with `transform`, because the entrance
   animation below animates `transform` — and a keyframe that sets one wipes out
   a centring written in the other. That is how a free-standing remark ended up
   with its left edge at the middle of the window instead of its middle. */
.tut-note-free {
  left: 50%; top: auto; bottom: 96px;
  translate: -50% 0;
  width: min(520px, calc(100vw - 28px));
  text-align: center;
  opacity: 1;
  animation: tut-note-in var(--tut-base) var(--tut-ease) both;
}

.tut-note-next {
  display: inline-block; margin-top: 11px;
  background: var(--brand); color: var(--brand-ink);
  border: 0; border-radius: var(--radius);
  padding: 7px 16px; font: inherit; font-size: .8125rem; font-weight: 550;
  cursor: pointer;
}

/* ---------------- the glow ----------------
   Put on the application's own buttons, for as long as the step that is talking
   about them. A press the tutorial is about to make lights up first: a page
   that changes with no visible cause reads as a recording, and a button
   lighting up and then being pressed reads as somebody using the board.

   It is a box-shadow and an outline and nothing else — no transform, no size,
   no colour change — because this is the store's markup and a walkthrough that
   moves the furniture is a walkthrough of a different board. */
.tut-glow {
  position: relative;
  border-radius: var(--radius);
  animation: tut-glow 1.6s ease-in-out infinite;
}
@keyframes tut-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgb(15 94 168 / .42), 0 0 0 1px rgb(15 94 168 / .55); }
  50%      { box-shadow: 0 0 0 7px rgb(15 94 168 / 0), 0 0 0 1px rgb(15 94 168 / .55); }
}
@media (prefers-reduced-motion: reduce) {
  .tut-glow { animation: none; box-shadow: 0 0 0 3px rgb(15 94 168 / .30); }
  .tut-line { animation: none; }
}

/* ---------------- the transport ----------------
   The meter and the pill are one fixed stack, not two elements independently
   pinned to hand-picked pixel offsets. Two fixed positions at the same
   z-index guessing at each other's height is exactly how the meter once ended
   up painted underneath the pill it was meant to sit above; a flex column
   makes "above" a fact of the layout rather than arithmetic that can drift
   the moment the pill's own height changes (a longer step title, a narrower
   screen, a translated build). */
.tut-transport {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%);
  z-index: 860;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  max-width: calc(100vw - 32px);
}
.tut-transport[hidden] { display: none; }

/* How much of this step's reading time is left before autoplay moves on. Its
   own bar, not folded into tut-bar-fill, because that one answers a different
   question — how far through the whole tutorial this step is — and the two
   should not be read as one number. */
.tut-meter {
  width: min(280px, calc(100vw - 32px));
  height: 3px; border-radius: 3px;
  background: var(--surface-3);
  overflow: hidden;
  box-shadow: 0 1px 3px rgb(19 26 36 / .12);
  transition: opacity var(--tut-fast) var(--tut-ease);
}
.tut-meter.is-idle { opacity: .35; }
.tut-meter-fill {
  display: block; height: 100%; width: 0;
  background: var(--brand);
  transition: width .08s linear;
}

.tut-bar {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 100px;
  box-shadow: 0 2px 6px rgb(19 26 36 / .10), 0 12px 32px rgb(19 26 36 / .18);
  padding: 9px 12px 9px 18px;
  max-width: 100%;
}
.tut-bar-step {
  font-size: .8125rem; color: var(--text-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 34ch;
}
.tut-bar-progress {
  width: 72px; height: 3px; border-radius: 3px;
  background: var(--surface-3); overflow: hidden; flex: none;
}
.tut-bar-fill { display: block; height: 100%; width: 0; background: var(--brand); transition: width var(--tut-base) var(--tut-ease); }

/* The disable-autoplay switch. A step still plays out everything it does —
   the switch only decides whether reaching the end of a step's reading time
   carries the tour on by itself, or waits for Next. */
.tut-auto {
  display: flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: 100px; padding: 5px 10px 5px 6px;
  font: inherit; font-size: .75rem; color: var(--text-2); cursor: pointer;
  flex: none;
}
.tut-auto:hover { background: var(--surface-2); }
.tut-auto-dot {
  width: 16px; height: 10px; border-radius: 100px; flex: none;
  background: var(--surface-3); position: relative;
  transition: background var(--tut-fast) var(--tut-ease);
}
.tut-auto-dot::after {
  content: ''; position: absolute; top: 1px; left: 1px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted);
  transition: translate var(--tut-fast) var(--tut-ease), background var(--tut-fast) var(--tut-ease);
}
.tut-auto.is-on .tut-auto-dot { background: var(--brand); }
.tut-auto.is-on .tut-auto-dot::after { translate: 6px 0; background: #fff; }

.tut-btn {
  border: 1px solid var(--line); background: var(--surface);
  border-radius: 100px; padding: 6px 15px;
  font: inherit; font-size: .8125rem; color: var(--text); cursor: pointer;
}
.tut-btn:hover { background: var(--surface-2); }
.tut-btn-primary { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); min-width: 82px; }
.tut-btn-primary:hover { background: #0d5395; }
.tut-skip {
  background: none; border: 0; padding: 6px 8px;
  color: var(--muted); font: inherit; font-size: .8125rem;
  cursor: pointer; text-decoration: underline; white-space: nowrap;
}
.tut-skip:hover { color: var(--text-2); }

/* The two ways back in, for somebody who ended the walkthrough: run it again,
   or go and do the half of it that happens in a hand. */
.tut-corner {
  position: fixed; right: 20px; bottom: 20px; z-index: 855;
  display: flex; gap: 10px; align-items: center;
}
.tut-corner-btn {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 100px; padding: 10px 18px;
  font: inherit; font-size: .875rem; font-weight: 550;
  box-shadow: var(--shadow-lg); cursor: pointer;
}
.tut-corner-btn:hover { background: var(--surface-2); }
.tut-corner-primary { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); }
.tut-corner-primary:hover { background: #0d5395; }

/* ---------------- the iPad interlude ----------------
   The desk view does not go anywhere. It dims, a tablet fades up over it, the
   walk happens, and the tablet fades away again — because the claim being made
   is that these are two halves of one evening rather than two products. */

.tut-scrim {
  position: fixed; inset: 0; z-index: 840;
  background: #0c1119;
  opacity: 0; pointer-events: none;
  transition: opacity var(--tut-slow) var(--tut-ease);
}
.tut-scrim.is-on { opacity: .82; pointer-events: auto; }

.tut-ipad {
  --k: .55;
  position: fixed; inset: 0; z-index: 845;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
  opacity: 0;
  transform: scale(.965) translateY(14px);
  transition: opacity var(--tut-slow) var(--tut-ease), transform var(--tut-slow) var(--tut-ease);
  pointer-events: none;
}
.tut-ipad.is-on { opacity: 1; transform: none; }
/* Belt and braces on the teardown: the script hides the tablet by setting
   `hidden`, and this makes that stick whatever state the fade was left in.
   A cancelled fade used to leave a full-screen iPad over the steps that
   followed — see hideIpad() in js/tutorial.js. */
.tut-ipad[hidden] { display: none !important; }

.tut-ipad-shell {
  background: #1b212a;
  border-radius: 30px;
  padding: 15px;
  box-shadow: 0 30px 80px rgb(0 0 0 / .55), inset 0 0 0 1px rgb(255 255 255 / .07);
}
/* The walk view is laid out at a real tablet viewport and then scaled, rather
   than squeezed into a small box: the application decides which view a device
   gets from the viewport it reports, so a frame that lied about its width would
   be showing the wrong view. */
.tut-ipad-screen {
  display: block; border: 0; background: var(--bg);
  border-radius: 4px;
  width: 834px; height: 1112px;
  transform: scale(var(--k));
  transform-origin: top left;
  /* The box the scaled document actually occupies. */
  margin-right: calc(834px * (var(--k) - 1));
  margin-bottom: calc(1112px * (var(--k) - 1));
}
.tut-ipad-home {
  height: 16px; display: grid; place-items: center; margin-top: 6px;
}
.tut-ipad-home::after {
  content: ''; width: 96px; height: 4px; border-radius: 100px; background: #4a5462;
}
.tut-ipad-caption {
  color: #cfd8e3; font-size: .9375rem; letter-spacing: .01em;
}

/* A press somebody can see. A programmatic click never fires the keypad's own
   :active state, so without this the digits appear with no visible cause and
   the whole thing reads as a recording rather than as somebody using it. */
.tut-press {
  position: fixed; z-index: 852;
  width: 34px; height: 34px; margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 2px solid rgb(120 180 255 / .95);
  background: rgb(120 180 255 / .22);
  pointer-events: none;
  animation: tut-press .5s ease-out forwards;
}
@keyframes tut-press {
  from { opacity: .95; transform: scale(.45); }
  to   { opacity: 0;   transform: scale(1.5); }
}

/* Notes and lines drawn over the tablet need to read against the dark ground. */
.tut-ipad.is-on ~ .tut-layer .tut-note,
.tut-scrim.is-on ~ .tut-layer .tut-note { border-color: var(--brand); }
.tut-ipad.is-on ~ .tut-layer .tut-line,
.tut-scrim.is-on ~ .tut-layer .tut-line { stroke: #7fb6ff; opacity: 1; }
.tut-ipad.is-on ~ .tut-layer .tut-line-dot,
.tut-scrim.is-on ~ .tut-layer .tut-line-dot { fill: #7fb6ff; }
.tut-ipad.is-on ~ .tut-layer .tut-ring,
.tut-scrim.is-on ~ .tut-layer .tut-ring { border-color: #7fb6ff; box-shadow: 0 0 0 4px rgb(127 182 255 / .18); }

/* ---------------- walking it yourself ----------------
   The panel behind the desk view's "Open the key walk" link: a tablet in a
   second tab that is wired back to this one, and a QR code for a real phone.
   See TABLET PANEL in js/tutorial.js for what wired back means on a board that
   has no database. */

.tut-panel {
  position: fixed; inset: 0; z-index: 870;
  display: grid; place-items: center;
  background: rgb(12 17 25 / .55);
  padding: 20px;
  opacity: 0; pointer-events: none;
  transition: opacity var(--tut-fast) var(--tut-ease);
}
.tut-panel.is-on { opacity: 1; pointer-events: auto; }

.tut-panel-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 30px 80px rgb(0 0 0 / .35);
  width: min(620px, 100%);
  max-height: calc(100vh - 40px); overflow: auto;
  padding: 22px 24px 24px;
}
.tut-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tut-panel-head h2 { margin: 0; font-size: 1.125rem; color: var(--text); }
.tut-panel-close {
  background: none; border: 0; cursor: pointer;
  font-size: 1.5rem; line-height: 1; color: var(--muted); padding: 0 4px;
}
.tut-panel-close:hover { color: var(--text); }
.tut-panel-lead {
  margin: 8px 0 18px; color: var(--text-2); font-size: .875rem; line-height: 1.55;
}
.tut-panel-lead strong, .tut-panel-text strong { color: var(--text); font-weight: 600; }

.tut-panel-row {
  display: flex; gap: 18px; align-items: flex-start;
  border-top: 1px solid var(--line);
  padding: 18px 0 0; margin-top: 4px;
}
.tut-panel-row + .tut-panel-row { margin-top: 18px; }
.tut-panel-text { flex: 1; min-width: 0; }
.tut-panel-text h3 { margin: 0 0 6px; font-size: .9375rem; color: var(--text); }
.tut-panel-text p { margin: 0 0 12px; font-size: .8125rem; line-height: 1.6; color: var(--text-2); }

.tut-panel-btn {
  background: var(--brand); color: var(--brand-ink);
  border: 1px solid var(--brand); border-radius: var(--radius);
  padding: 8px 16px; font: inherit; font-size: .8125rem; font-weight: 550; cursor: pointer;
}
.tut-panel-btn:hover { background: #0d5395; }
.tut-panel-btn-quiet {
  background: var(--surface); color: var(--text); border-color: var(--line);
}
.tut-panel-btn-quiet:hover { background: var(--surface-2); }

.tut-panel-url {
  font-size: .75rem; color: var(--muted); word-break: break-all; margin-bottom: 10px;
}
.tut-panel-qr {
  flex: none; background: #fff; padding: 8px;
  border: 1px solid var(--line); border-radius: var(--radius);
  line-height: 0;
}
.tut-qr { display: block; image-rendering: pixelated; }

/* Running commentary from the tablet tab, bottom left, gone in a few seconds. */
.tut-toast {
  position: fixed; left: 20px; bottom: 20px; z-index: 875;
  background: var(--surface); color: var(--text-2);
  border: 1px solid var(--brand-line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 11px 15px; font-size: .8125rem; line-height: 1.5;
  max-width: min(380px, calc(100vw - 40px));
  opacity: 0; transform: translateY(8px);
  transition: opacity var(--tut-fast) var(--tut-ease), transform var(--tut-fast) var(--tut-ease);
}
.tut-toast.is-on { opacity: 1; transform: none; }
.tut-toast strong { color: var(--text); font-weight: 600; }

/* ---------------- the tablet tab ----------------
   The ordinary walk view, wearing a tablet's shape. Nothing here changes what
   the page reports as its viewport — the application decides which view a
   device gets from that, and a simulator that lied about it would be showing
   the wrong view. This is a frame drawn around the real one. */

body.tut-sim {
  background: #10151d;
  padding: 26px 0 30px;
}
body.tut-sim .walk-shell {
  max-width: 834px; margin: 0 auto;
  background: var(--bg);
  border-radius: 26px;
  border: 14px solid #1b212a;
  box-shadow: 0 30px 80px rgb(0 0 0 / .5), inset 0 0 0 1px rgb(255 255 255 / .06);
  overflow: hidden;
  min-height: calc(100vh - 100px);
}
.tut-sim-pill {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 14px; z-index: 880;
  background: rgb(27 33 42 / .94); color: #cfd8e3;
  border-radius: 100px; padding: 7px 16px;
  font-size: .8125rem; letter-spacing: .01em;
}
.tut-sim-pill strong { color: #fff; font-weight: 600; }

/* ---------------- the sign-in card ---------------- */

.tut-signin-note {
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  border-radius: var(--radius);
  padding: 11px 13px; margin-bottom: 16px;
  font-size: .8125rem; line-height: 1.5; color: var(--text-2);
  text-align: left;
}
.tut-signin-skip {
  display: block; width: 100%; margin-top: 11px;
  background: none; border: 0; padding: 4px;
  color: var(--muted); font: inherit; font-size: .8125rem;
  cursor: pointer; text-decoration: underline;
}
.tut-signin-skip:hover { color: var(--text-2); }

@media print {
  .tut-layer, .tut-transport, .tut-corner, .tut-ipad, .tut-scrim,
  .tut-dim, .tut-panel, .tut-toast, .tut-sim-pill { display: none !important; }
}

@media (max-width: 900px) {
  .tut-bar { gap: 8px; padding: 8px 10px 8px 14px; }
  .tut-bar-step { max-width: 16ch; }
  .tut-bar-progress { display: none; }
  .tut-auto { padding: 5px 8px 5px 6px; }
  .tut-auto-label { display: none; }
  .tut-corner { left: 20px; justify-content: center; }
  .tut-panel-row { flex-direction: column; }
  body.tut-sim { padding: 0; }
  body.tut-sim .walk-shell { border: 0; border-radius: 0; min-height: 100vh; }
}

@media (prefers-reduced-motion: reduce) {
  .tut-meter-fill { transition: none; }
}
