/* src/modules/demo/walkthrough.css — the guided walkthrough's panel and spotlight.
   The app underneath keeps its own appearance and stays fully usable: the whole point is that the
   trainer performs the step on the real control, so nothing here may cover or restyle it.
   The pointer is styled in demoTour.css — shared with the automatic demo, which is the same tap.
   The panel and the ring around the step's control are drawn outside the control's box, so they
   never hide the label a trainer is being asked to recognise. There is no backdrop at all, because
   a scrim would block the tap the walkthrough is asking for.
   The panel is bounded to 45vh and laid out as a column. It gets out of the way by docking at the
   other end of the screen, which needs an end to be free. A chapter's card had grown it to 63% of an
   iPhone SE, where neither end is free. The prose scrolls inside the panel. The step number, the
   instruction and the buttons keep their own height. */

.walkthrough {
  position: fixed;
  inset: 0;
  /* Above the clipboard overlay (activeSessionOverlay.css, 120/130), below the demo hand (9999) so
     the pointer reads as being over the app rather than behind the panel. No backdrop and no
     pointer-events: the app must stay tappable, since the trainer doing the step IS the walkthrough. */
  z-index: 9400;
  pointer-events: none;
}

/* Hidden for the instant dialogScrollsItself measures the dialog underneath — the guide's own frame
   is deliberately bigger than the dialog and would otherwise make every dialog measure as scrolling
   (walkthroughOverlay.js). */
.walkthrough.is-measuring {
  display: none;
}

/* Lets a dialog draw outside its own box while the guide is docked in it (walkthroughOverlay.js's
   clipEscapedDialog) — the app styles no dialog this way, so this class is the walkthrough's alone. */
.walkthrough-escaped-dialog {
  overflow: visible;
}

/* A ring around the control the step is about, drawn OUTSIDE its box so it never obscures a label or
   an icon a trainer is being asked to recognise. */
.walkthrough-spotlight {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--spot-w, 0);
  height: var(--spot-h, 0);
  transform: translate3d(var(--spot-x, 0), var(--spot-y, 0), 0);
  border-radius: var(--border-radius-md, 12px);
  box-shadow: 0 0 0 3px var(--primary, #6366f1), 0 0 0 9px
    color-mix(in srgb, var(--primary, #6366f1) 28%, transparent);
  opacity: 0;
  /* Only the fade. The ring does not travel between controls (decided 2026-08-19): across a step
     that also changes view, gliding from one control to another is motion between two things that
     never shared a screen — and the HAND already carries movement, which is the familiar version of
     it. Without the position/size transitions, the ring simply is where the control is. */
  transition: opacity 0.2s ease;
}

.walkthrough-spotlight.is-visible {
  opacity: 1;
}

/* A breathing GLOW around the ring, asked for directly: the static ring said "this
   one" and nothing said "now". The pulse is on the outer halo only — the inner 3px ring stays put,
   so the control's own edge never appears to move while a trainer is aiming at it with a thumb.
   Dropped entirely under prefers-reduced-motion below. */
@media (prefers-reduced-motion: no-preference) {
  .walkthrough-spotlight.is-visible {
    animation: walkthroughGlow 1.9s ease-in-out infinite;
  }
  @keyframes walkthroughGlow {
    0%,
    100% {
      box-shadow: 0 0 0 3px var(--primary, #6366f1), 0 0 0 9px
        color-mix(in srgb, var(--primary, #6366f1) 28%, transparent);
    }
    50% {
      box-shadow: 0 0 0 3px var(--primary, #6366f1), 0 0 0 15px
        color-mix(in srgb, var(--primary, #6366f1) 10%, transparent), 0 0 22px 6px
        color-mix(in srgb, var(--primary, #6366f1) 45%, transparent);
    }
  }
}

.walkthrough-panel {
  position: absolute;
  left: 50%;
  bottom: calc(12px + var(--safe-bottom, 0px));
  transform: translateX(-50%);
  /* BOUNDED, and the bound is what lets it move at all. The panel gets out of the way of the control
     it is pointing at by docking at the other end of the screen — which needs an end to be free. A
     chapter's opening card rides on the first real step, so the panel carries a paragraph AND an
     instruction, and that came to 63% of an iPhone SE at the story's own first step: docked low it
     covered a control in the middle of the board, and flipping it high covered the same control
     (measured 2026-08-30). The prose scrolls inside the panel now instead of pushing
     it taller.
     A column, so the card is the part that gives: everything else — the step number, the
     instruction, the buttons — keeps its own height and stays where a thumb expects it. */
  display: flex;
  flex-direction: column;
  max-height: 45vh;
  /* NARROWER than the app it sits on (asked 2026-09-11): a panel as wide as the screen reads as a
     new screen, and a trainer waits for it to go away instead of looking past it. A margin of app
     down both sides says the app is still there, underneath, and still theirs to tap. */
  width: min(calc(100% - 56px), calc(var(--app-max-width, 480px) - 40px));
  padding: 14px 16px;
  /* Tinted, so one glance says this is the GUIDE and not a screen of the app (asked 2026-09-11).
     Mixed into the app's own card colour rather than picked as a new one, so it lands right in both
     themes and moves with the palette. */
  background: color-mix(in srgb, var(--primary) 12%, var(--card-bg));
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid color-mix(in srgb, var(--primary) 45%, var(--card-border));
  border-radius: var(--border-radius-lg, 16px);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
  color: var(--text-main);
  /* The panel itself IS interactive — only the transparent frame around it is not. */
  pointer-events: auto;
}

/* PARKED: the guide as a bar, the way the message drawer parks itself (asked for 2026-08-30 —
   "find a way for the demo card to be collapsed only ... that allows for the user to return to
   demo"). Everything but the head goes; the head is already the one line worth reading from across
   the room, and tapping the bar brings the rest back. The guide keeps running while it is parked, so
   a trainer who does the step by hand meanwhile comes back to a guide that moved on with them. */
.walkthrough.is-collapsed .walkthrough-panel {
  max-height: none;
  cursor: pointer;
  /* ABOVE the message drawer's handle, not on top of it (reported 2026-09-10: "minimizirani demo
     cardi pokrivajo message area, predlagam, da ga premakneva tik nad sporočila"). Parked, this bar
     sat 12px off the bottom — exactly where the drawer's own bar lives — so the guide got out of the
     way of the app by covering the one surface that tells the trainer what the app wants from them.
     `--notif-handle-height` already carries the safe-area inset, so it is not added twice; the 8px
     is the gap that keeps the two bars reading as two, and it also covers the taller handle the
     drawer takes while a session is running, which is scoped to the drawer and not readable here. */
  bottom: calc(var(--notif-handle-height, 56px) + 8px);
}
.walkthrough.is-collapsed .walkthrough-panel > *:not(.walkthrough-head) {
  display: none;
}
/* The ✕ ENDS the demo, and it is offered only here — one tap from a guide already out of the way,
   two from one you are reading, which is the right way round for the act with nothing after it. */
.walkthrough:not(.is-collapsed) .walkthrough-exit {
  display: none;
}

/* ABOVE the message drawer's handle, not on it (asked 2026-09-11, the same complaint the parked bar
   answered on 2026-09-10). The drawer's bar is where the app says what it wants from the trainer
   next; a guide that covers it to explain the app has covered the app's own voice.
   `--notif-handle-height` already carries the safe-area inset, so it is not added twice, and the 8px
   is the gap that keeps the two bars reading as two.

   NOT while one of the app's own modals is open: the drawer is behind it and inert, so there is
   nothing there to clear, and lifting the card only takes room from a form. That covers both ways a
   dialog can hold the panel — docked inside it, or escaped out over the screen. The panel's padding
   drops the safe-area inset with the same move — nothing sits on the bottom edge any more, so
   reserving room for the home indicator would be a second gap under the first. */
.walkthrough:not(.is-over-dialog) .walkthrough-panel {
  bottom: calc(var(--notif-handle-height, 56px) + 8px);
}

/* A step with nothing in the APP to point at — a card whose only control is on the card itself —
   has no control to get out of the way of, so it stops hugging an edge and takes the middle of the
   screen (asked 2026-09-11). That is also the reading position: the first card is a paragraph
   somebody stands still to read, not an instruction glanced at over a thumb.

   Taller than a docked panel is allowed to be, and deliberately as tall as the screen will take:
   nothing is being covered that a trainer is about to tap, so the height is free, and height is what
   keeps the whole card on screen at once. The 45% cap two rules down is for a panel that still has
   to move out of the way of a control; this one has nowhere to be.

   It can still overflow on a short screen, and then it scrolls WITH its scrollbar showing (asked
   2026-09-11): hiding the bar on a box that scrolls leaves the fade as the only sign that a
   paragraph carries on, which is a hint where a reader needs a control. */
.walkthrough.is-centred:not(.is-collapsed):not(.is-over-dialog) .walkthrough-panel {
  top: 50%;
  bottom: auto;
  transform: translate(-50%, -50%);
  max-height: calc(100% - 48px);
}

/* The control this step is about sits where the panel would be, so the panel gets out of the way
   rather than hiding it (walkthroughOverlay.js's keepPanelClearOf). */
.walkthrough.is-top .walkthrough-panel {
  top: calc(var(--hdr-height, 64px) + 12px);
  bottom: auto;
}

/* Inside one of the app's own modals the frame is the DIALOG's visible box, not the screen
   (walkthroughOverlay.js's keepPanelReachable explains why it has to be). Two consequences, both
   about staying inside that box: there is no app header to clear up there, and a card that outgrew
   the modal would be clipped by it — a dialog clips what hangs off its edges, which is exactly how
   the card disappeared when the frame was stretched over the viewport instead. */
.walkthrough.is-in-dialog.is-top .walkthrough-panel {
  top: 12px;
}

.walkthrough.is-in-dialog .walkthrough-panel {
  max-height: calc(100% - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The panel gives up height to stay clear of the control it is pointing at
   (walkthroughOverlay.js's trimPanelToFitBeside). The room is only known once the control and the
   panel are both on screen, so JS hands it over as a custom property instead of picking a class per
   pixel. Two classes beat the base rule's 45vh, which is the only rule this ever has to win against
   — trimming never runs while the panel is collapsed, centred or docked inside a dialog. */
.walkthrough-panel.is-trimmed {
  max-height: var(--walkthrough-panel-max-height);
}

.walkthrough-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.walkthrough-progress {
  font-family: var(--font-header);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--primary);
}

/* 44px of target for a 14px glyph: leaving the walkthrough must be reachable with a thumb, not just
   visible. */
.walkthrough-exit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -12px -12px -12px 0;
  border: 0;
  background: none;
  color: var(--text-main);
  font-size: 1rem;
  cursor: pointer;
}

.walkthrough-caption {
  margin: 6px 0 0 0;
  font-size: 1rem;
  line-height: 1.4;
}

.walkthrough-problem {
  margin: 8px 0 0 0;
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--danger);
}

.walkthrough-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

.walkthrough-btn {
  flex: 1 1 auto;
  min-height: 46px;
  padding: 0 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--btn-radius, 12px);
  background: transparent;
  color: var(--text-main);
  font-family: var(--font-header);
  font-size: 0.95rem;
  cursor: pointer;
}

.walkthrough-btn-primary {
  background: var(--primary-gradient);
  color: var(--on-primary);
  border-color: transparent;
}

.walkthrough-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Someone who asked for less motion still gets the guide: only the travel of the ring stops. */
/* Reduced motion used to strip the ring's travel here. The ring no longer travels for anybody
   (2026-08-19), so the only motion left on it is the glow, which its own no-preference block adds
   and this therefore has nothing to undo. Kept as a marker rather than deleted silently: the next
   person adding motion to the spotlight should find the place where motion is opted out of. */
@media (prefers-reduced-motion: reduce) {
  .walkthrough-spotlight {
    animation: none;
  }
}
