/* ===========================================================
   askRadek — interaktywne demo ("Jak działa askRadek" on index.html)
   Loaded AFTER styles.css, which owns the brand tokens, the
   header/footer shell and the buttons.

   The demo shows REAL SCREENSHOTS of the running app, so there
   is deliberately NO app-lookalike CSS in here. Everything below
   is the frame around a screenshot: the chapter rail, the shot
   frame, the annotation pins and their callouts. Nothing here
   should ever try to imitate an app surface — the moment a
   component here starts looking like a panel or a control, it
   has become a second, drifting copy of radek.css.
   =========================================================== */

:root {
  --pin: oklch(0.52 0.18 268);
  --pin-on: oklch(0.48 0.19 296);
  /* What shows below a screenshot that does not fill the reserved height, so it
     is matched to the captures' own page background rather than chosen: the
     bottom row of the seven .webp files runs #EAEAEA..#FFFFFF, most of them
     #FC..#FF. Darker than this and the band reads as a grey box under the
     screenshot instead of as the browser window continuing. */
  --shot-bg: oklch(0.992 0.0015 280);
  /* Height reserved for the screenshot INSIDE the window frame, so that every
     chapter's stage measures the same and the caption under it — the arrows and
     Odtworz — never moves. `cqw` is 1% of `.tour-main`, which is the frame's own
     width, so this reads "the tallest capture's aspect ratio, plus a strip".

     69.2% is dyktowanie.webp (1760x1218), the tallest of the seven; the seven
     range from 37% (the report card) to that, which is why the stage was
     jumping ~250px between chapters. The +20px keeps a band of frame below even
     the tallest, so the frame's rounded bottom always lands on background
     rather than clipping an image corner.

     RE-DERIVE THIS AFTER ANY RE-CAPTURE: the 20px band is the ONLY slack. A
     capture taller than 69.5% of its own width eats into it, and once it is
     gone that chapter's stage grows again — which is the whole failure this
     exists to stop. `layout.mjs` measures it. */
  --shot-reserve: calc(69.5cqw + 20px);
  /* The A/B strip's row height. One number in three places — the strip's floor,
     the button's height, and the reserve the frame gives back below — so the
     subtraction is exact by construction rather than by measurement. Left to
     its padding the button computes to 34.58px, which put chapter 4 half a
     pixel off the other five for no reason anyone could see in the CSS.
     A SECOND button on the strip would still fit this row; a THIRD, or a label
     long enough to wrap, would not, and the strip's `flex-wrap` would silently
     make that chapter taller again. */
  --shot-tools-row: 34px;
  --shot-tools-h: calc(var(--shot-tools-row) + 10px); /* + its margin-top */
  /* Diameter of a rail's numbered marker AND the line height of the title it
     sits beside — one value, because equal boxes are what makes the two share a
     centre under `align-items: start`. Nudging one without the other is how the
     number ends up a pixel or two off its heading. */
  --rail-n: 22px;
}

/* ---------------- layout ---------------- */
.tour-wrap { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 26px; align-items: start; }

/* `min-width: 0` on both columns, and it is load-bearing on the rail. A grid
   item defaults to `min-width: auto` — it refuses to shrink below its content —
   so when the rail turns into a horizontal strip below 1200px, its own
   `overflow-x: auto` never got a chance to scroll: the strip pushed the grid
   wider than the viewport and the WHOLE PAGE scrolled sideways instead. */
.tour-rail, .tour-main { min-width: 0; }

/* The query container `--shot-reserve` is measured against. It has to be the
   column rather than `#stage` itself: an element cannot query its own size, and
   `.tour-main` is exactly as wide as the stage inside it. */
.tour-main { container-type: inline-size; }

.tour-rail { position: sticky; top: calc(var(--header-h) + 16px); }
.tour-rail ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.rail-btn {
  display: grid; grid-template-columns: 24px 1fr; gap: 10px; align-items: start;
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius);
  padding: 9px 11px; color: var(--text-muted);
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.rail-btn:hover { background: var(--surface-2); color: var(--text); }
.rail-n {
  display: grid; place-items: center;
  width: var(--rail-n); height: var(--rail-n); border-radius: 50%;
  font-size: 0.72rem; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--surface-3); color: var(--text-muted); border: 1px solid var(--border);
}
/* `display: block` matters as much as the line-height: left inline, the title's
   box is its 19px content area floating inside a taller line box, and the
   marker beside it cannot be aligned to something that is not the box edge. */
.rail-t {
  display: block; font-weight: 600; font-size: 0.93rem; color: var(--text);
  line-height: var(--rail-n);
}
.rail-s { display: block; font-size: 0.78rem; color: var(--text-faint); margin-top: 2px; }
.rail-btn[aria-current="step"] { background: var(--accent-soft); border-color: var(--accent-ring); color: var(--text); }
.rail-btn[aria-current="step"] .rail-n {
  background: linear-gradient(135deg, var(--brand-1), var(--brand-2));
  color: var(--btn-fg); border-color: transparent;
}
.rail-btn.done .rail-n { color: var(--accent); border-color: var(--accent-ring); background: var(--accent-soft); }

/* ---------------- the screenshot frame ---------------- */
/* NOT `overflow: hidden` — a callout near the bottom of a screenshot has to be
   allowed past the frame edge or its last line gets cut off. Nothing needs
   clipping any more either: `--shot-reserve` keeps a band of frame under every
   capture, so the rounded bottom corners are drawn on background rather than
   over an image. */
.shotframe {
  position: relative; margin: 0;
  display: flex; flex-direction: column;
  background: var(--shot-bg);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.shotbar { flex: none; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
/* The window's viewport. `1 0 auto` — it grows into the reserve and never
   shrinks under the screenshot, which is the whole point: the image keeps its
   own size at the top of the box and whatever is left shows as frame. */
.shotbody { flex: 1 0 auto; min-height: var(--shot-reserve); }
/* The A/B toggle is a sibling BELOW the frame, so on the one chapter that has
   it the frame gives that strip's height back — otherwise that chapter's stage
   would stand 44px taller than the other five and the caption would move again,
   which is the whole thing the reserve is here to stop. */
.shotframe:has(+ .shot-tools) .shotbody { min-height: calc(var(--shot-reserve) - var(--shot-tools-h)); }
/* Square bottom corners, deliberately: with the reserve above, no screenshot
   reaches the bottom of the frame any more, so the rounding down there belongs
   to the frame and a rounded image edge floating mid-window reads as a second
   card inside the first. */
.shotclip { overflow: hidden; line-height: 0; }
/* The window bar is the ONLY chrome: it says "this is a screenshot of the app",
   which is exactly the claim being made, and it stops a light screenshot from
   bleeding into a light page with no edge. */
.shotbar {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; background: var(--surface-3); border-bottom: 1px solid var(--border);
}
.shotbar .dots { display: flex; gap: 6px; }
.shotbar .dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--border-strong); }
.shotbar .url {
  flex: 1; text-align: center; font-family: var(--font-mono); font-size: 0.74rem;
  color: var(--text-faint); background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 12px; max-width: 320px; margin: 0 auto;
}
.shotwrap { position: relative; line-height: 0; }
.shotwrap img { display: block; width: 100%; height: auto; }
.shotwrap .shotclip { position: relative; }
/* Cross-fade between the A/B pair (highlight on / off) without a reflow. */
.shotwrap img.alt { position: absolute; inset: 0; opacity: 0; transition: opacity .28s ease; }
.shotwrap.show-alt img.alt { opacity: 1; }

/* ---------------- annotation pins ---------------- */
.pin {
  position: absolute; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font: inherit; font-size: 0.76rem; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--btn-fg); cursor: pointer; padding: 0;
  background: var(--pin); border: 2px solid oklch(1 0 0 / 0.9);
  box-shadow: 0 2px 8px oklch(0.2 0.02 260 / 0.28);
  transition: transform .15s ease, background .15s ease;
  z-index: 6;
}
.pin:hover { transform: translate(-50%, -50%) scale(1.14); }
.pin[aria-expanded="true"] { background: var(--pin-on); transform: translate(-50%, -50%) scale(1.14); z-index: 7; }
/* A soft pulse so the eye finds the active pin on a busy screenshot. */
.pin[aria-expanded="true"]::after {
  content: ""; position: absolute; inset: -7px; border-radius: 50%;
  border: 2px solid var(--pin-on); opacity: .55; animation: pinPulse 1.6s ease-out infinite;
}
@keyframes pinPulse { to { inset: -16px; opacity: 0; } }

/* The region a pin is about, boxed while that pin is open. */
.pinbox {
  position: absolute; border: 2px solid var(--pin-on); border-radius: 6px;
  background: oklch(0.52 0.18 268 / 0.10);
  opacity: 0; transition: opacity .2s ease; pointer-events: none; z-index: 1;
}
.pinbox.on { opacity: 1; }

/* ABOVE the pins (z 6/7), so a neighbouring number can never land on top of the
   sentence this box is asking you to read — that is the whole job of a callout.
   `pointer-events: none` is what makes that safe: clicks fall straight through
   to whatever is underneath, so a pin the box happens to cover is still one
   click away, and clicking the box itself just closes it like clicking the
   screenshot does. `placeCallout` additionally scores candidate positions by
   how many pins they cover, so the overlap is usually avoided outright. */
.callout {
  position: absolute; z-index: 8; pointer-events: none; max-width: min(340px, 68vw);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  padding: 11px 13px; font-size: 0.86rem; line-height: 1.45;
  opacity: 0; visibility: hidden; transition: opacity .18s ease;
}
.callout.on { opacity: 1; visibility: visible; }
.callout b { display: block; margin-bottom: 3px; font-size: 0.88rem; }
.callout p { margin: 0; color: var(--text-muted); }
.callout code {
  font-family: var(--font-mono); font-size: 0.86em;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 5px; padding: 0 4px;
}

/* ---------------- tools strip under the shot ---------------- */
.shot-tools {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; min-height: var(--shot-tools-row);
}
.tool-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 0.83rem; font-weight: 600; cursor: pointer;
  height: var(--shot-tools-row); padding: 0 13px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-muted);
}
.tool-btn:hover { border-color: var(--border-strong); color: var(--text); }
.tool-btn[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* ---------------- the text-only chapter ---------------- */
/* No screenshot here: it is a grid of before-after cards about screens the
   visitor has already been shown, plus the two checks that run before a
   template is ever used. */
.pairs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
@media (max-width: 860px) { .pairs { grid-template-columns: 1fr; } }
.pair {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); padding: 12px 13px;
}
.pair .tag {
  display: inline-block; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 8px;
  background: none; border: 0; padding: 0;
}
.pair .row { display: grid; grid-template-columns: 1fr 16px 1fr; gap: 8px; align-items: center; }
.pair .box {
  font-family: var(--font-mono); font-size: 0.73rem; line-height: 1.45;
  border-radius: var(--radius-sm); padding: 7px 9px;
}
.pair .from { background: var(--surface-3); color: var(--text-muted); }
.pair .to { background: oklch(0.945 0.045 258); color: var(--text); }
.pair .ar { color: var(--text-faint); display: grid; place-items: center; }
.pair p { margin: 9px 0 0; font-size: 0.82rem; color: var(--text-muted); }
.pair p b { color: var(--text); font-weight: 600; }
.pair.wide { grid-column: 1 / -1; }

/* ---------------- caption + controls ---------------- */
/* `align-items: start`, not `center`: the blurb runs one to four lines
   depending on the chapter, and centred controls ride half that difference —
   another ~57px of movement on top of the stage's, in the one place a visitor
   is meant to be able to keep clicking. Anchored to the top they sit level with
   the chapter title and stay put whatever the text does. */
.tour-caption {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: start;
  margin-top: 12px; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
}
.cap-t { font-weight: 700; font-size: 1.02rem; }
.cap-p { margin: 5px 0 0; color: var(--text-muted); font-size: 0.92rem; }
.tour-ctl { display: flex; align-items: center; gap: 7px; }
.ctl-b {
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--radius);
  font: inherit; cursor: pointer; color: var(--text-muted);
  background: var(--surface-2); border: 1px solid var(--border);
}
.ctl-b:hover { color: var(--text); border-color: var(--border-strong); }
/* An inline SVG sits on the TEXT baseline, so it reserves descender space below
   itself and rides ~2px above the optical centre of its button — measurable, and
   visible on the play button where the triangle sits beside a word while the
   arrow buttons next to it hold nothing else. Block-level takes it off the
   baseline so `place-items: center` can actually centre it. */
.ctl-b svg { display: block; }
.ctl-b.play { width: auto; padding: 0 13px; gap: 7px; grid-auto-flow: column; font-size: 0.83rem; font-weight: 600; }
.ctl-b[disabled] { opacity: .4; cursor: default; }
.dots-nav { display: flex; gap: 5px; margin-right: 4px; }
.dots-nav i { width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); transition: all .2s ease; }
.dots-nav i.on { width: 18px; border-radius: 3px; background: linear-gradient(90deg, var(--brand-1), var(--brand-2)); }
@media (max-width: 620px) {
  .tour-caption { grid-template-columns: 1fr; }
  .tour-ctl { justify-content: space-between; }
  /* Stacked, the arrows would land under eight to ten lines of chapter blurb —
     far enough down a phone that reaching them scrolls the step card they move
     off the screen, and a tap then changes nothing the visitor can see. Lift
     them to the top of the caption, directly under the card they drive. Only
     here: above 620px the caption is two columns and they already sit beside
     it, and this would merely swap the two halves round. */
  .tour-ctl { order: -1; }
}

/* ---------------- narrow ---------------- */
/* 1200, not 940. The rail costs the screenshot 286px of width, and between
   those two numbers that produced an inversion: the shot was NARROWER at
   1000px (rail still vertical, ~626px of image) than at 900px (rail horizontal,
   ~850px), which is where the layout check found callouts with nowhere to go.
   Dropping the rail to a horizontal strip earlier keeps the image close to the
   full container width at every size that still draws pins. */
@media (max-width: 1200px) {
  .tour-wrap { grid-template-columns: 1fr; }
  .tour-rail { position: static; }
  .tour-rail ol { flex-direction: row; overflow-x: auto; gap: 8px; padding-bottom: 6px; scrollbar-width: none; }
  .tour-rail ol::-webkit-scrollbar { display: none; }
  .rail-btn { width: auto; white-space: nowrap; grid-template-columns: 22px auto; }
  .rail-s { display: none; }
}
/* The two OFF states of the phone swap. They must stay ABOVE the breakpoint
   that turns them on: a media query adds no specificity, so the same
   declaration written afterwards wins at every width — which is how this page
   shipped a phone view with the screenshots and none of the annotations. */
.pinlist { display: none; margin: 12px 0 0; padding: 0; list-style: none; }
.if-pinlist { display: none; }

/* Callouts need room. Below this width the screenshot renders under ~850px
   while the callout stays 340px wide — nearly half of it — so a callout
   covering the thing it describes, or a neighbouring pin, stops being avoidable
   by placement. Raised from 620px after the layout check measured unavoidable
   overlaps at 760px.

   So the FLOATING caption goes, and the tour steps one annotation at a time
   instead: the active pin stays on the shot with its region boxed, and its text
   renders as a card underneath (`.pinlist li.on`, further down). The inactive
   pins go with the callout — at 344px of image the tightest pair of pins
   measures ~24px apart, which two 26px discs cannot occupy without touching,
   and a phone tap target cannot honestly be shrunk to fit. One number, one
   boxed region, one caption: the number still points at something, which is
   what the earlier plain list could not do. */
@media (max-width: 900px) {
  .callout { display: none !important; }
  .pin { display: none !important; }
  /* No scale-up and no pulse: both exist to pick the open pin out of the four
     or five around it, and here it is the only one drawn. At ~340px of image
     the pulse ring is a 58px smudge sitting over the very region the pin is
     pointing at — it costs what it was meant to buy. */
  .pin[aria-expanded="true"] { display: grid !important; transform: translate(-50%, -50%); }
  .pin[aria-expanded="true"]::after { display: none; }
  /* the section lead's second sentence swaps with the layout — see index.html */
  .if-pins { display: none; }
  .if-pinlist { display: inline; }
  /* `narrow()` turns autoplay off here — the caption is below the shot rather
     than on it, so following a timed walk would mean the page scrolling itself
     between the two — and the play button's handler returns immediately.
     Leaving the button on screen meant a phone got a labelled control that
     answered a tap with nothing; the arrows beside it are the control, and they
     step annotations here exactly as they do on the desktop layout. Without the
     button in the middle, the 620px rule's `space-between` would push the
     remaining pair to opposite ends of the row, so group them instead. */
  #btn-play { display: none; }
  .tour-ctl { justify-content: flex-end; }
  /* Progress left, controls right: with the play button gone they are the only
     two things in the row, and grouping all three at one end reads as one
     cluster of buttons with a decoration stuck to it. */
  .dots-nav { margin-right: auto; }
}
.pinlist li {
  display: grid; grid-template-columns: 22px 1fr; gap: 9px;
  padding: 9px 0; border-top: 1px solid var(--border); font-size: 0.86rem;
}
.pinlist .n {
  display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%;
  background: var(--pin); color: var(--btn-fg); font-size: 0.7rem; font-weight: 700;
}
.pinlist b { display: block; }
.pinlist p { margin: 2px 0 0; color: var(--text-muted); }

/* The step card. Same source-order trap as `.pinlist` itself two rules up: the
   base `li` rules above are written AFTER the 900px block, so the one-at-a-time
   switch has to be its OWN media query down here or the `display: grid` above
   would win at every width and the phone would get all five items again. */
@media (max-width: 900px) {
  /* `min-height` for the same reason the frame has one, and it matters more
     here: this card is re-written on every press of the arrows, so without a
     floor the arrows move under the thumb that is pressing them.

     The floor has to clear the LONGEST annotation at the NARROWEST width in its
     band, which is a step function of the width and was measured rather than
     guessed — the tallest card over all 29 annotations comes to 111.3px from
     530px up (three lines), 132.6px between ~430 and ~510 (four), 154px at 390
     (five). 7.25rem = 116px clears the three-line case by 4.7px; the value
     below clears the other two. The margins are deliberately small — a floor
     far above the tallest card is just dead space under it — which is why
     `layout.mjs` walks every annotation at the tight end of BOTH bands. */
  .pinlist { display: block; margin-top: 10px; min-height: 7.25rem; }
  .pinlist li { display: none; }
  /* Not `border-top`: a lone card reads as a card, not as the top edge of a
     list that is not there. Tinted to tie it to the pin it belongs to. */
  .pinlist li.on {
    display: grid; border: 1px solid var(--accent-ring); border-radius: var(--radius-lg);
    background: var(--accent-soft); padding: 11px 13px;
  }
  .pinlist code {
    font-family: var(--font-mono); font-size: 0.86em;
    background: var(--surface); border: 1px solid var(--border); border-radius: 5px; padding: 0 4px;
  }
}
/* Below this the card wraps to four lines and then, under ~420px, to five:
   10rem = 160px clears the tallest of them (154px at 390px) by 6px. The
   breakpoint is 620 rather than the ~520 the measurements point at, because 620
   is already a breakpoint here — the one that stacks the caption — and erring
   wide costs a band of empty card at 530-620px, while erring narrow costs the
   moving arrows this exists to stop. Written after the block above and at the
   same specificity, so it is the later rule that wins — the ordering discipline
   the rest of this file documents. */
@media (max-width: 620px) { .pinlist { min-height: 10rem; } }

@media (prefers-reduced-motion: reduce) {
  .pin[aria-expanded="true"]::after { animation: none; }
  .shotwrap img.alt, .callout, .pinbox { transition: none; }
  /* Same reason as the phone: `reduced` disables autoplay in demo-tour.js, so
     the button would do nothing. The arrows remain, and they are the honest
     control for a visitor who asked not to be animated at. */
  #btn-play { display: none; }
}
