[{"data":1,"prerenderedAt":2569},["ShallowReactive",2],{"cycle-doc-design-c125-tour-layer.md":3},{"cycle":4,"project":7,"path":10,"title":11,"toc":12,"ast":19},{"id":5,"title":6},"c125","Operations Wizard",{"id":8,"label":9},"design","Design","tour-layer.md","The tour layer: IDs, a floating panel, Examples and Drills",[13,14,15,16,17,18],"1. The protocol: what the dashboard carries","2. The materials: Live, Example, Drill, and the tour itself","3. Drills","4. Content as data","5. Where to pick it up (work packages)","6. Panel iterations (2026-10-29)",{"type":20,"children":21},"root",[22,39,48,68,80,106,112,224,253,286,303,328,333,468,473,483,611,621,626,645,699,707,745,750,771,817,829,862,867,872,1305,1310,1315,1341,1390,1557,1565,1778,1796,2057,2098,2177,2291,2324,2482,2498,2508,2516],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27,30,37],{"type":28,"value":29},"text","From c123's addressable tour (thread ",{"type":23,"tag":31,"props":32,"children":34},"code",{"className":33},[],[35],{"type":28,"value":36},"owasp-agentic",{"type":28,"value":38},", 2026-10-27), built in the lab as a working prototype for c125 to pick up. Mark's direction, the same day:",{"type":23,"tag":40,"props":41,"children":42},"blockquote",{},[43],{"type":23,"tag":24,"props":44,"children":45},{},[46],{"type":28,"value":47},"We'll need a way to highlight sections … clear design distinction to separate the \"Tour guide \u002F meta narrative\" from the live dashboard it floats over. We want to be as non-intrusive as possible to the UI … IDs that we use to highlight a component is much preferred over the component needing to know about this meta layer. We should be able to play these tours over the top of the real dashboard without polluting the dashboard space with more than ids. The tour space should have a way to create example instances of various pieces of the dashboard (error states).",{"type":23,"tag":24,"props":49,"children":50},{},[51,53,59,61,66],{"type":28,"value":52},"And on drills: show what would happen if a violation occurred (the gauge it lights, your notification settings), with a ",{"type":23,"tag":54,"props":55,"children":56},"strong",{},[57],{"type":28,"value":58},"Simulate violation",{"type":28,"value":60}," button that sends ",{"type":23,"tag":54,"props":62,"children":63},{},[64],{"type":28,"value":65},"real messages",{"type":28,"value":67}," through the customer's channels, end to end. Drill receipts are worth keeping: \"we track everything\".",{"type":23,"tag":24,"props":69,"children":70},{},[71,73,78],{"type":28,"value":72},"Ruled in the same conversation: the panel ",{"type":23,"tag":54,"props":74,"children":75},{},[76],{"type":28,"value":77},"floats",{"type":28,"value":79},", it doesn't dock. Row keys: \"start as light as possible, implementation will answer this one\". c125 owns the runtime and protocol; c123 owns the OWASP content.",{"type":23,"tag":24,"props":81,"children":82},{},[83,88,90,96,98,104],{"type":23,"tag":54,"props":84,"children":85},{},[86],{"type":28,"value":87},"Try it:",{"type":28,"value":89}," ",{"type":23,"tag":31,"props":91,"children":93},{"className":92},[],[94],{"type":28,"value":95},"\u002Fpages\u002Fphase4\u002Ftour-owasp-agentic",{"type":28,"value":97}," (the route, with Start and per-beat links), or any composed mock with ",{"type":23,"tag":31,"props":99,"children":101},{"className":100},[],[102],{"type":28,"value":103},"?tour=owasp-agentic&step=\u003Cstep id>",{"type":28,"value":105},".",{"type":23,"tag":107,"props":108,"children":110},"h2",{"id":109},"_1-the-protocol-what-the-dashboard-carries",[111],{"type":28,"value":13},{"type":23,"tag":113,"props":114,"children":115},"table",{},[116,135],{"type":23,"tag":117,"props":118,"children":119},"thead",{},[120],{"type":23,"tag":121,"props":122,"children":123},"tr",{},[124,130],{"type":23,"tag":125,"props":126,"children":127},"th",{},[128],{"type":28,"value":129},"On the dashboard",{"type":23,"tag":125,"props":131,"children":132},{},[133],{"type":28,"value":134},"What it is",{"type":23,"tag":136,"props":137,"children":138},"tbody",{},[139,165,198],{"type":23,"tag":121,"props":140,"children":141},{},[142,152],{"type":23,"tag":143,"props":144,"children":145},"td",{},[146],{"type":23,"tag":31,"props":147,"children":149},{"className":148},[],[150],{"type":28,"value":151},"data-qp-id=\"\u003Cpage>.\u003Cregion>\"",{"type":23,"tag":143,"props":153,"children":154},{},[155,157,163],{"type":28,"value":156},"A stable name on the element whose box can be highlighted. A layer component takes it on its root by attribute fallthrough (",{"type":23,"tag":31,"props":158,"children":160},{"className":159},[],[161],{"type":28,"value":162},"\u003CDataMachine data-qp-id=\"home.findings\" …>",{"type":28,"value":164},"), so components don't change.",{"type":23,"tag":121,"props":166,"children":167},{},[168,179],{"type":23,"tag":143,"props":169,"children":170},{},[171,177],{"type":23,"tag":31,"props":172,"children":174},{"className":173},[],[175],{"type":28,"value":176},"data-qp-key=\"\u003Cinstance>\"",{"type":28,"value":178}," (optional)",{"type":23,"tag":143,"props":180,"children":181},{},[182,184,190,192,197],{"type":28,"value":183},"On a repeated element (a row's name cell), the instance it is. The step picks keys and can ",{"type":23,"tag":31,"props":185,"children":187},{"className":186},[],[188],{"type":28,"value":189},"expand",{"type":28,"value":191}," each match to its closest ",{"type":23,"tag":31,"props":193,"children":195},{"className":194},[],[196],{"type":28,"value":121},{"type":28,"value":105},{"type":23,"tag":121,"props":199,"children":200},{},[201,212],{"type":23,"tag":143,"props":202,"children":203},{},[204,210],{"type":23,"tag":31,"props":205,"children":207},{"className":206},[],[208],{"type":28,"value":209},"\u003CTourHost \u002F>",{"type":28,"value":211},", once, in the layout",{"type":23,"tag":143,"props":213,"children":214},{},[215,217,223],{"type":28,"value":216},"Inert until a tour starts. In the lab: ",{"type":23,"tag":31,"props":218,"children":220},{"className":219},[],[221],{"type":28,"value":222},"app\u002Flayouts\u002Fgovernance-mock.vue",{"type":28,"value":105},{"type":23,"tag":24,"props":225,"children":226},{},[227,229,235,237,243,245,251],{"type":28,"value":228},"Nothing else. No tour imports, props or state in a page or component. The tour's own state lives in the tour layer (",{"type":23,"tag":31,"props":230,"children":232},{"className":231},[],[233],{"type":28,"value":234},"useState",{"type":28,"value":236}," + ",{"type":23,"tag":31,"props":238,"children":240},{"className":239},[],[241],{"type":28,"value":242},"sessionStorage",{"type":28,"value":244},"), not the dashboard's URL. ",{"type":23,"tag":31,"props":246,"children":248},{"className":247},[],[249],{"type":28,"value":250},"?tour=&step=",{"type":28,"value":252}," is only a way in, and the host strips it once read.",{"type":23,"tag":24,"props":254,"children":255},{},[256,261,262,268,270,276,278,284],{"type":23,"tag":54,"props":257,"children":258},{},[259],{"type":28,"value":260},"Naming.",{"type":28,"value":89},{"type":23,"tag":31,"props":263,"children":265},{"className":264},[],[266],{"type":28,"value":267},"\u003Cpage>.\u003Cregion>",{"type":28,"value":269}," in kebab case, with sub-regions dotted (",{"type":23,"tag":31,"props":271,"children":273},{"className":272},[],[274],{"type":28,"value":275},"mcp.policy.approval-verbs",{"type":28,"value":277},"). An ID names a region by what it ",{"type":23,"tag":279,"props":280,"children":281},"em",{},[282],{"type":28,"value":283},"is",{"type":28,"value":285},", not by the tour that uses it, so any tour, the help mode and the MCP guide can share it.",{"type":23,"tag":24,"props":287,"children":288},{},[289,294,296,301],{"type":23,"tag":54,"props":290,"children":291},{},[292],{"type":28,"value":293},"What a missing ID does.",{"type":28,"value":295}," The step still shows its panel with no ring. ",{"type":23,"tag":279,"props":297,"children":298},{},[299],{"type":28,"value":300},"To build:",{"type":28,"value":302}," a check that every ID a tour names exists in an ID registry, so a renamed region fails a build instead of silently losing its ring.",{"type":23,"tag":24,"props":304,"children":305},{},[306,311,313,319,321,326],{"type":23,"tag":54,"props":307,"children":308},{},[309],{"type":28,"value":310},"Row keys (open, as Mark ruled).",{"type":28,"value":312}," The lab uses them on three lists: Sources rows, ",{"type":23,"tag":31,"props":314,"children":316},{"className":315},[],[317],{"type":28,"value":318},"github",{"type":28,"value":320},"'s tools, and notification channels. Expanding a key to its ",{"type":23,"tag":31,"props":322,"children":324},{"className":323},[],[325],{"type":28,"value":121},{"type":28,"value":327}," keeps the attribute on a cell the row already renders. If implementation shows that region-level IDs are enough, drop keys.",{"type":23,"tag":107,"props":329,"children":331},{"id":330},"_2-the-materials-live-example-drill-and-the-tour-itself",[332],{"type":28,"value":14},{"type":23,"tag":113,"props":334,"children":335},{},[336,357],{"type":23,"tag":117,"props":337,"children":338},{},[339],{"type":23,"tag":121,"props":340,"children":341},{},[342,347,352],{"type":23,"tag":125,"props":343,"children":344},{},[345],{"type":28,"value":346},"Kind",{"type":23,"tag":125,"props":348,"children":349},{},[350],{"type":28,"value":351},"Looks like",{"type":23,"tag":125,"props":353,"children":354},{},[355],{"type":28,"value":356},"Means",{"type":23,"tag":136,"props":358,"children":359},{},[360,381,402,431],{"type":23,"tag":121,"props":361,"children":362},{},[363,371,376],{"type":23,"tag":143,"props":364,"children":365},{},[366],{"type":23,"tag":54,"props":367,"children":368},{},[369],{"type":28,"value":370},"Live",{"type":23,"tag":143,"props":372,"children":373},{},[374],{"type":28,"value":375},"the dashboard as it is; the tour only draws a ring around it",{"type":23,"tag":143,"props":377,"children":378},{},[379],{"type":28,"value":380},"your data",{"type":23,"tag":121,"props":382,"children":383},{},[384,392,397],{"type":23,"tag":143,"props":385,"children":386},{},[387],{"type":23,"tag":54,"props":388,"children":389},{},[390],{"type":28,"value":391},"Example",{"type":23,"tag":143,"props":393,"children":394},{},[395],{"type":28,"value":396},"a real dashboard component with example props, floated exactly over its live counterpart: white card, dashed grape frame, a dark tab reading \"Example · your live value is N\"",{"type":23,"tag":143,"props":398,"children":399},{},[400],{"type":28,"value":401},"what it would look like if …",{"type":23,"tag":121,"props":403,"children":404},{},[405,413,426],{"type":23,"tag":143,"props":406,"children":407},{},[408],{"type":23,"tag":54,"props":409,"children":410},{},[411],{"type":28,"value":412},"Drill",{"type":23,"tag":143,"props":414,"children":415},{},[416,418,424],{"type":28,"value":417},"a dark \"Drill D-0007\" tag on a delivery-log row; messages titled \"",{"type":23,"tag":419,"props":420,"children":421},"span",{},[422],{"type":28,"value":423},"Qpoint drill",{"type":28,"value":425},"\"",{"type":23,"tag":143,"props":427,"children":428},{},[429],{"type":28,"value":430},"a real delivery about a simulated cause",{"type":23,"tag":121,"props":432,"children":433},{},[434,442,463],{"type":23,"tag":143,"props":435,"children":436},{},[437],{"type":23,"tag":54,"props":438,"children":439},{},[440],{"type":28,"value":441},"The tour",{"type":23,"tag":143,"props":443,"children":444},{},[445,447,453,455,461],{"type":28,"value":446},"dark grape (",{"type":23,"tag":31,"props":448,"children":450},{"className":449},[],[451],{"type":28,"value":452},"grape-900",{"type":28,"value":454},"), white type: the floating panel, numbered callouts, the 3 px top edge; the ring in ",{"type":23,"tag":31,"props":456,"children":458},{"className":457},[],[459],{"type":28,"value":460},"grape-500",{"type":28,"value":462}," with a soft glow",{"type":23,"tag":143,"props":464,"children":465},{},[466],{"type":28,"value":467},"the narrator, never the product",{"type":23,"tag":24,"props":469,"children":470},{},[471],{"type":28,"value":472},"When an Example covers the target, the step draws no ring: the dashed frame already shows where to look.",{"type":23,"tag":24,"props":474,"children":475},{},[476,481],{"type":23,"tag":54,"props":477,"children":478},{},[479],{"type":28,"value":480},"Two switches the lab compares",{"type":28,"value":482}," (Mark, 2026-10-27), in the panel header at every step and remembered for the visit:",{"type":23,"tag":484,"props":485,"children":486},"ul",{},[487,530],{"type":23,"tag":488,"props":489,"children":490},"li",{},[491,496,498,504,506,512,514,520,522,528],{"type":23,"tag":54,"props":492,"children":493},{},[494],{"type":28,"value":495},"Panel: Float · Split.",{"type":28,"value":497}," Float is the panel floating over the page, which picks a side. Split docks the panel as a 420 px full-height column, and the dashboard narrows beside it. The host reserves the column with ",{"type":23,"tag":31,"props":499,"children":501},{"className":500},[],[502],{"type":28,"value":503},"padding-right",{"type":28,"value":505}," on ",{"type":23,"tag":31,"props":507,"children":509},{"className":508},[],[510],{"type":28,"value":511},"\u003Chtml>",{"type":28,"value":513}," and publishes the width as ",{"type":23,"tag":31,"props":515,"children":517},{"className":516},[],[518],{"type":28,"value":519},"--qp-dock-right",{"type":28,"value":521},". Anything the app fixes to the right edge adds that variable to its offset, the way it would a safe-area inset. In the lab that's only the PublishTray. That variable is the one convention split asks of a dashboard. ",{"type":23,"tag":31,"props":523,"children":525},{"className":524},[],[526],{"type":28,"value":527},"?tourLayout=split",{"type":28,"value":529}," opens a tour that way.",{"type":23,"tag":488,"props":531,"children":532},{},[533,538,605,609],{"type":23,"tag":54,"props":534,"children":535},{},[536],{"type":28,"value":537},"Focus: Ring · Dim · Fade.",{"type":23,"tag":484,"props":539,"children":540},{},[541,551,561,587],{"type":23,"tag":488,"props":542,"children":543},{},[544,549],{"type":23,"tag":54,"props":545,"children":546},{},[547],{"type":28,"value":548},"Ring:",{"type":28,"value":550}," the ring and its glow.",{"type":23,"tag":488,"props":552,"children":553},{},[554,559],{"type":23,"tag":54,"props":555,"children":556},{},[557],{"type":28,"value":558},"Dim:",{"type":28,"value":560}," one scrim over the viewport with holes cut for the focused regions and Example frames, so everything else darkens. The ring stays, quieter. The scrim never takes a click.",{"type":23,"tag":488,"props":562,"children":563},{},[564,569,571,577,579,585],{"type":23,"tag":54,"props":565,"children":566},{},[567],{"type":28,"value":568},"Fade",{"type":28,"value":570}," (Mark's follow-up: dim every other element, not the page): the tour layer walks up from each focused element and, at every level, sets ",{"type":23,"tag":31,"props":572,"children":574},{"className":573},[],[575],{"type":28,"value":576},"opacity",{"type":28,"value":578}," on the siblings that don't contain a focused element. The focused elements, their ancestors and the page background keep full strength, so the page washes toward its own background with no dark layer. The styles are set at run time and restored on exit or a switch (",{"type":23,"tag":31,"props":580,"children":582},{"className":581},[],[583],{"type":28,"value":584},"composables\u002FuseTourFade.ts",{"type":28,"value":586},").",{"type":23,"tag":488,"props":588,"children":589},{},[590,595,597,603],{"type":23,"tag":54,"props":591,"children":592},{},[593],{"type":28,"value":594},"Fade's trade-off:",{"type":28,"value":596}," context fades too, such as a table's header row when the focus is some of its rows. If Fade wins, a step may want a ",{"type":23,"tag":31,"props":598,"children":600},{"className":599},[],[601],{"type":28,"value":602},"keep",{"type":28,"value":604}," list of regions that stay at full strength.",{"type":23,"tag":606,"props":607,"children":608},"br",{},[],{"type":28,"value":610},"Swapping the dashboard's background colour would have needed the page to cooperate, and wouldn't dim its content.",{"type":23,"tag":24,"props":612,"children":613},{},[614,619],{"type":23,"tag":54,"props":615,"children":616},{},[617],{"type":28,"value":618},"Focus only what's specific",{"type":28,"value":620}," (Mark, 2026-10-29: \"I don't know that we gain anything by highlighting the whole page\"). A step rings the one region that answers its question, not every region it mentions. The opening rings nothing; stop 1 Tune rings the impact card only; stop 2 Tune rings the two new controls only. Dim and Fade also fall back to the ring when the focus covers more than about half the viewport, since past that they darken almost nothing.",{"type":23,"tag":107,"props":622,"children":624},{"id":623},"_3-drills",[625],{"type":28,"value":15},{"type":23,"tag":24,"props":627,"children":628},{},[629,631,636,638,643],{"type":28,"value":630},"A drill runs a ",{"type":23,"tag":279,"props":632,"children":633},{},[634],{"type":28,"value":635},"simulated cause",{"type":28,"value":637}," through the ",{"type":23,"tag":279,"props":639,"children":640},{},[641],{"type":28,"value":642},"real",{"type":28,"value":644}," alert path:",{"type":23,"tag":646,"props":647,"children":648},"ol",{},[649,659,689],{"type":23,"tag":488,"props":650,"children":651},{},[652,657],{"type":23,"tag":54,"props":653,"children":654},{},[655],{"type":28,"value":656},"Before:",{"type":28,"value":658}," the panel shows what Qpoint would send (the signals: severity, title, policy), the customer's settings today (each policy's live mode and what it does, and where each severity is routed, with \"not connected\" called out), and one sentence on what would happen today, worked out from those settings (\"the call goes through, two findings are raised, Slack posts twice, your webhook gets one POST, and nobody is paged\"). Examples show the cards that would light up.",{"type":23,"tag":488,"props":660,"children":661},{},[662,666,668,674,676],{"type":23,"tag":54,"props":663,"children":664},{},[665],{"type":28,"value":58},{"type":28,"value":667}," sends one message per signal to each connected channel that takes its severity. Every message is titled ",{"type":23,"tag":31,"props":669,"children":671},{"className":670},[],[672],{"type":28,"value":673},"[Qpoint drill]",{"type":28,"value":675},", carries the drill id, and says \"Simulated from the tour by ",{"type":23,"tag":677,"props":678,"children":679},"person",{},[680,682,688],{"type":28,"value":681}," · no agent did this\". Webhook payloads carry ",{"type":23,"tag":31,"props":683,"children":685},{"className":684},[],[686],{"type":28,"value":687},"\"drill\": true, \"drill_id\"",{"type":28,"value":105},{"type":23,"tag":488,"props":690,"children":691},{},[692,697],{"type":23,"tag":54,"props":693,"children":694},{},[695],{"type":28,"value":696},"After:",{"type":28,"value":698}," receipts per channel (delivered \u002F 200 OK \u002F not connected, nothing sent), a preview of the Slack message and the webhook payload, and the delivery log with the drill's rows tagged. The tour then points at what to fix, such as connecting PagerDuty and running it again.",{"type":23,"tag":24,"props":700,"children":701},{},[702],{"type":23,"tag":54,"props":703,"children":704},{},[705],{"type":28,"value":706},"Rules:",{"type":23,"tag":484,"props":708,"children":709},{},[710,715,732],{"type":23,"tag":488,"props":711,"children":712},{},[713],{"type":28,"value":714},"A drill never creates a finding and never enters evidence, framework detail or the evidence export. It lives in the delivery log, which is where \"when was the alert path last tested?\" gets answered.",{"type":23,"tag":488,"props":716,"children":717},{},[718,722,724,730],{"type":23,"tag":279,"props":719,"children":720},{},[721],{"type":28,"value":300},{"type":28,"value":723}," PagerDuty and other paging channels need an explicit tick per run, and should open the incident and resolve it automatically (dedup key ",{"type":23,"tag":31,"props":725,"children":727},{"className":726},[],[728],{"type":28,"value":729},"qpoint-drill-\u003Cid>",{"type":28,"value":731},"). Also a rate limit (one drill per minute per org), and admins only.",{"type":23,"tag":488,"props":733,"children":734},{},[735,737,743],{"type":28,"value":736},"In the lab, nothing is sent: ",{"type":23,"tag":31,"props":738,"children":740},{"className":739},[],[741],{"type":28,"value":742},"useNotificationsMock().runDrill()",{"type":28,"value":744}," simulates the deliveries.",{"type":23,"tag":107,"props":746,"children":748},{"id":747},"_4-content-as-data",[749],{"type":28,"value":16},{"type":23,"tag":24,"props":751,"children":752},{},[753,755,761,763,769],{"type":28,"value":754},"A tour is ",{"type":23,"tag":31,"props":756,"children":758},{"className":757},[],[759],{"type":28,"value":760},"data\u002Ftours\u002F\u003Cid>.ts",{"type":28,"value":762}," (types in ",{"type":23,"tag":31,"props":764,"children":766},{"className":765},[],[767],{"type":28,"value":768},"data\u002Ftours\u002Ftypes.ts",{"type":28,"value":770},"): stops, then steps. A step has:",{"type":23,"tag":484,"props":772,"children":773},{},[774,779,784,796],{"type":23,"tag":488,"props":775,"children":776},{},[777],{"type":28,"value":778},"a route and a beat;",{"type":23,"tag":488,"props":780,"children":781},{},[782],{"type":28,"value":783},"the targets to ring, its callouts and its Examples;",{"type":23,"tag":488,"props":785,"children":786},{},[787,789,794],{"type":28,"value":788},"the panel's ",{"type":23,"tag":54,"props":790,"children":791},{},[792],{"type":28,"value":793},"blocks",{"type":28,"value":795},": lede, ask, numbers, mitigations, list, signals, settings, expect, receipts, route, yours, note;",{"type":23,"tag":488,"props":797,"children":798},{},[799,801,807,809,815],{"type":28,"value":800},"at most one action: ",{"type":23,"tag":31,"props":802,"children":804},{"className":803},[],[805],{"type":28,"value":806},"stage",{"type":28,"value":808}," writes changes to the draft, ",{"type":23,"tag":31,"props":810,"children":812},{"className":811},[],[813],{"type":28,"value":814},"drill",{"type":28,"value":816}," runs a scenario.",{"type":23,"tag":24,"props":818,"children":819},{},[820,822,827],{"type":28,"value":821},"Numbers and settings are functions of a ",{"type":23,"tag":54,"props":823,"children":824},{},[825],{"type":28,"value":826},"context",{"type":28,"value":828}," the app supplies; they never come from the page's text. Because content is data, the MCP guide (objective 7) can read every block without a browser.",{"type":23,"tag":24,"props":830,"children":831},{},[832,837,838,844,846,852,854,860],{"type":23,"tag":54,"props":833,"children":834},{},[835],{"type":28,"value":836},"The adapter is the seam.",{"type":28,"value":89},{"type":23,"tag":31,"props":839,"children":841},{"className":840},[],[842],{"type":28,"value":843},"composables\u002FuseTourAdapter.ts",{"type":28,"value":845}," is the only file that knows both the tour and the app. It supplies the context (the same data the pages read) and two verbs: ",{"type":23,"tag":31,"props":847,"children":849},{"className":848},[],[850],{"type":28,"value":851},"stage(changes)",{"type":28,"value":853}," and ",{"type":23,"tag":31,"props":855,"children":857},{"className":856},[],[858],{"type":28,"value":859},"drill(scenario)",{"type":28,"value":861},". In qdash, that file sits on the data interface. The tour components don't change.",{"type":23,"tag":107,"props":863,"children":865},{"id":864},"_5-where-to-pick-it-up-work-packages",[866],{"type":28,"value":17},{"type":23,"tag":24,"props":868,"children":869},{},[870],{"type":28,"value":871},"Each package states its inputs, its files, and when it is done. Packages W1–W4 are c125's; W5–W6 are c123's.",{"type":23,"tag":113,"props":873,"children":874},{},[875,901],{"type":23,"tag":117,"props":876,"children":877},{},[878],{"type":23,"tag":121,"props":879,"children":880},{},[881,886,891,896],{"type":23,"tag":125,"props":882,"children":883},{},[884],{"type":28,"value":885},"#",{"type":23,"tag":125,"props":887,"children":888},{},[889],{"type":28,"value":890},"Package",{"type":23,"tag":125,"props":892,"children":893},{},[894],{"type":28,"value":895},"Starts from",{"type":23,"tag":125,"props":897,"children":898},{},[899],{"type":28,"value":900},"Done when",{"type":23,"tag":136,"props":902,"children":903},{},[904,960,1003,1070,1125,1181,1212],{"type":23,"tag":121,"props":905,"children":906},{},[907,915,925,949],{"type":23,"tag":143,"props":908,"children":909},{},[910],{"type":23,"tag":54,"props":911,"children":912},{},[913],{"type":28,"value":914},"W1",{"type":23,"tag":143,"props":916,"children":917},{},[918,923],{"type":23,"tag":54,"props":919,"children":920},{},[921],{"type":28,"value":922},"ID protocol and registry.",{"type":28,"value":924}," Write down the naming rules, keep a registry of IDs per page, and add the build check that every tour's IDs exist. Fold in c125's help ids (objective 1): one attribute for help, markers and tours.",{"type":23,"tag":143,"props":926,"children":927},{},[928,930,935,936,942,944],{"type":28,"value":929},"§1; ",{"type":23,"tag":31,"props":931,"children":933},{"className":932},[],[934],{"type":28,"value":768},{"type":28,"value":89},{"type":23,"tag":31,"props":937,"children":939},{"className":938},[],[940],{"type":28,"value":941},"TourTarget",{"type":28,"value":943},"; the IDs listed on ",{"type":23,"tag":31,"props":945,"children":947},{"className":946},[],[948],{"type":28,"value":95},{"type":23,"tag":143,"props":950,"children":951},{},[952,958],{"type":23,"tag":31,"props":953,"children":955},{"className":954},[],[956],{"type":28,"value":957},"data-qp-id",{"type":28,"value":959}," is the only attach point. A test fails on an unknown ID.",{"type":23,"tag":121,"props":961,"children":962},{},[963,971,981,998],{"type":23,"tag":143,"props":964,"children":965},{},[966],{"type":23,"tag":54,"props":967,"children":968},{},[969],{"type":28,"value":970},"W2",{"type":23,"tag":143,"props":972,"children":973},{},[974,979],{"type":23,"tag":54,"props":975,"children":976},{},[977],{"type":28,"value":978},"Tour host: ring, callouts, floating panel, pill.",{"type":28,"value":980}," Harden the lab prototype: focus management, Esc to minimize, keyboard Next\u002FBack, reduced motion, phone width, and the panel avoiding its targets (it picks a side today).",{"type":23,"tag":143,"props":982,"children":983},{},[984,990,992],{"type":23,"tag":31,"props":985,"children":987},{"className":986},[],[988],{"type":28,"value":989},"components\u002Ftour\u002F{Host,Panel,Blocks,Ring,Callout}.vue",{"type":28,"value":991},", ",{"type":23,"tag":31,"props":993,"children":995},{"className":994},[],[996],{"type":28,"value":997},"composables\u002FuseTour.ts",{"type":23,"tag":143,"props":999,"children":1000},{},[1001],{"type":28,"value":1002},"It passes c125 objective 8's scenarios (empty, minimal, typical, overflow, error) on one lab page.",{"type":23,"tag":121,"props":1004,"children":1005},{},[1006,1014,1032,1057],{"type":23,"tag":143,"props":1007,"children":1008},{},[1009],{"type":23,"tag":54,"props":1010,"children":1011},{},[1012],{"type":28,"value":1013},"W3",{"type":23,"tag":143,"props":1015,"children":1016},{},[1017,1022,1024,1030],{"type":23,"tag":54,"props":1018,"children":1019},{},[1020],{"type":28,"value":1021},"Examples.",{"type":28,"value":1023}," Example instances of any layer component, positioned over an ID. Decide whether Examples stay as ",{"type":23,"tag":31,"props":1025,"children":1027},{"className":1026},[],[1028],{"type":28,"value":1029},"render()",{"type":28,"value":1031}," functions in tour data or become named presets (like a design-site demo), so a non-engineer can write one.",{"type":23,"tag":143,"props":1033,"children":1034},{},[1035,1041,1043,1049,1051],{"type":23,"tag":31,"props":1036,"children":1038},{"className":1037},[],[1039],{"type":28,"value":1040},"components\u002Ftour\u002FExample.vue",{"type":28,"value":1042},"; ",{"type":23,"tag":31,"props":1044,"children":1046},{"className":1045},[],[1047],{"type":28,"value":1048},"examples",{"type":28,"value":1050}," in ",{"type":23,"tag":31,"props":1052,"children":1054},{"className":1053},[],[1055],{"type":28,"value":1056},"data\u002Ftours\u002Fowasp-agentic.ts",{"type":23,"tag":143,"props":1058,"children":1059},{},[1060,1062,1068],{"type":28,"value":1061},"An error state of any ",{"type":23,"tag":31,"props":1063,"children":1065},{"className":1064},[],[1066],{"type":28,"value":1067},"DataMachine",{"type":28,"value":1069}," can be shown without touching the page.",{"type":23,"tag":121,"props":1071,"children":1072},{},[1073,1081,1099,1120],{"type":23,"tag":143,"props":1074,"children":1075},{},[1076],{"type":23,"tag":54,"props":1077,"children":1078},{},[1079],{"type":28,"value":1080},"W4",{"type":23,"tag":143,"props":1082,"children":1083},{},[1084,1089,1091,1097],{"type":23,"tag":54,"props":1085,"children":1086},{},[1087],{"type":28,"value":1088},"Drill runtime.",{"type":28,"value":1090}," A real ",{"type":23,"tag":31,"props":1092,"children":1094},{"className":1093},[],[1095],{"type":28,"value":1096},"POST \u002Fdrills",{"type":28,"value":1098}," that sends through the integrations' test path. Paging opt-in, auto-resolve, rate limit, admin-only. The delivery log's drill tag.",{"type":23,"tag":143,"props":1100,"children":1101},{},[1102,1104,1110,1112,1118],{"type":28,"value":1103},"§3; ",{"type":23,"tag":31,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":28,"value":1109},"composables\u002FuseNotificationsMock.ts",{"type":28,"value":1111},"; the integrations mock's \"Save and test\" (",{"type":23,"tag":31,"props":1113,"children":1115},{"className":1114},[],[1116],{"type":28,"value":1117},"pages\u002Fpages\u002Fintegrations-ideas-v11.vue",{"type":28,"value":1119},")",{"type":23,"tag":143,"props":1121,"children":1122},{},[1123],{"type":28,"value":1124},"One drill delivers to Slack, a webhook and a paging tool in a real environment, with receipts in the log.",{"type":23,"tag":121,"props":1126,"children":1127},{},[1128,1136,1146,1170],{"type":23,"tag":143,"props":1129,"children":1130},{},[1131],{"type":23,"tag":54,"props":1132,"children":1133},{},[1134],{"type":28,"value":1135},"W5",{"type":23,"tag":143,"props":1137,"children":1138},{},[1139,1144],{"type":23,"tag":54,"props":1140,"children":1141},{},[1142],{"type":28,"value":1143},"OWASP signal catalog",{"type":28,"value":1145}," (c123). For each stop, the signals Qpoint sends: trigger, policy, severity, the card it lights. Stops 1 and 2 are written.",{"type":23,"tag":143,"props":1147,"children":1148},{},[1149,1155,1157,1163,1164],{"type":23,"tag":31,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":28,"value":1154},"owasp-agentic-tour-v2.md",{"type":28,"value":1156}," § The Drill beat; ",{"type":23,"tag":31,"props":1158,"children":1160},{"className":1159},[],[1161],{"type":28,"value":1162},"data\u002Fowasp-tour-fixture.ts",{"type":28,"value":89},{"type":23,"tag":31,"props":1165,"children":1167},{"className":1166},[],[1168],{"type":28,"value":1169},"DRILLS",{"type":23,"tag":143,"props":1171,"children":1172},{},[1173,1175,1180],{"type":28,"value":1174},"Stops 3–5 have Watch, Tune and Drill steps in ",{"type":23,"tag":31,"props":1176,"children":1178},{"className":1177},[],[1179],{"type":28,"value":1056},{"type":28,"value":105},{"type":23,"tag":121,"props":1182,"children":1183},{},[1184,1192,1202,1207],{"type":23,"tag":143,"props":1185,"children":1186},{},[1187],{"type":23,"tag":54,"props":1188,"children":1189},{},[1190],{"type":28,"value":1191},"W6",{"type":23,"tag":143,"props":1193,"children":1194},{},[1195,1200],{"type":23,"tag":54,"props":1196,"children":1197},{},[1198],{"type":28,"value":1199},"Prove beat",{"type":28,"value":1201}," (c123 + c125). One shared evidence view (findings and config history filtered to the stop) or a board per stop.",{"type":23,"tag":143,"props":1203,"children":1204},{},[1205],{"type":28,"value":1206},"v2 spec, Open 5",{"type":23,"tag":143,"props":1208,"children":1209},{},[1210],{"type":28,"value":1211},"Each written stop has a Prove step.",{"type":23,"tag":121,"props":1213,"children":1214},{},[1215,1223,1265,1292],{"type":23,"tag":143,"props":1216,"children":1217},{},[1218],{"type":23,"tag":54,"props":1219,"children":1220},{},[1221],{"type":28,"value":1222},"W7",{"type":23,"tag":143,"props":1224,"children":1225},{},[1226,1231,1233,1239,1241,1247,1249,1255,1257,1263],{"type":23,"tag":54,"props":1227,"children":1228},{},[1229],{"type":28,"value":1230},"MCP tour guide",{"type":28,"value":1232}," (objective 7, Phase 4; thread ",{"type":23,"tag":31,"props":1234,"children":1236},{"className":1235},[],[1237],{"type":28,"value":1238},"mcp-guide",{"type":28,"value":1240},", 2026-10-29). First, a page API (",{"type":23,"tag":31,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":28,"value":1246},"window.qpTour",{"type":28,"value":1248},") over ",{"type":23,"tag":31,"props":1250,"children":1252},{"className":1251},[],[1253],{"type":28,"value":1254},"useTour()",{"type":28,"value":1256},". Then an MCP endpoint the dashboard hosts (",{"type":23,"tag":31,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":28,"value":1262},"\u002Fapi\u002Ftour\u002Fmcp",{"type":28,"value":1264},", Streamable HTTP), relayed to the open tab over SSE. The agent navigates, highlights and reads; only the person runs a drill or stages a change. Tested on a demo page and a seven-rung ladder before qdash.",{"type":23,"tag":143,"props":1266,"children":1267},{},[1268,1279,1280,1285,1286],{"type":23,"tag":1269,"props":1270,"children":1272},"a",{"href":1271},"\u002Fcycles\u002Fdesign\u002Fc125\u002Fdoc\u002Fmcp-guide-plan",[1273],{"type":23,"tag":31,"props":1274,"children":1276},{"className":1275},[],[1277],{"type":28,"value":1278},"mcp-guide-plan.md",{"type":28,"value":1042},{"type":23,"tag":31,"props":1281,"children":1283},{"className":1282},[],[1284],{"type":28,"value":997},{"type":28,"value":1042},{"type":23,"tag":31,"props":1287,"children":1289},{"className":1288},[],[1290],{"type":28,"value":1291},"components\u002Ftour\u002FHost.vue",{"type":23,"tag":143,"props":1293,"children":1294},{},[1295,1297,1303],{"type":28,"value":1296},"Claude Code walks the OWASP tour on ",{"type":23,"tag":31,"props":1298,"children":1300},{"className":1299},[],[1301],{"type":28,"value":1302},":3000",{"type":28,"value":1304}," from one prompt, recorded. The rung 1–4 script passes, and it runs unchanged against qdash after the port.",{"type":23,"tag":24,"props":1306,"children":1307},{},[1308],{"type":28,"value":1309},"Also open: the operations journey (J1–J7, objective 6) can reuse the whole layer. Its first stop, \"first signal arrived\", is a drill in reverse: wait for a real signal instead of sending a fake one.",{"type":23,"tag":107,"props":1311,"children":1313},{"id":1312},"_6-panel-iterations-2026-10-29",[1314],{"type":28,"value":18},{"type":23,"tag":24,"props":1316,"children":1317},{},[1318,1320,1326,1328,1332,1333,1339],{"type":28,"value":1319},"Mark's review of v1: the dark panel may not survive a theme change, and the panel is information overload that collides with its own controls. Prompt, verbatim: ",{"type":23,"tag":31,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":28,"value":1325},"tour-panel-iterations-prompt.md",{"type":28,"value":1327},". ",{"type":23,"tag":54,"props":1329,"children":1330},{},[1331],{"type":28,"value":87},{"type":28,"value":89},{"type":23,"tag":31,"props":1334,"children":1336},{"className":1335},[],[1337],{"type":28,"value":1338},"\u002Fpages\u002Fphase4\u002Ftour-iterations",{"type":28,"value":1340}," (each iteration opens on Source health · Watch; switch at any step from the mock bar's tour row).",{"type":23,"tag":24,"props":1342,"children":1343},{},[1344,1346,1352,1353,1358,1360,1366,1368,1374,1375,1381,1383,1388],{"type":28,"value":1345},"Nothing earlier is lost: an iteration is a value of the tour state (",{"type":23,"tag":31,"props":1347,"children":1349},{"className":1348},[],[1350],{"type":28,"value":1351},"TourVariant",{"type":28,"value":1050},{"type":23,"tag":31,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":28,"value":997},{"type":28,"value":1359},"), opened by link with ",{"type":23,"tag":31,"props":1361,"children":1363},{"className":1362},[],[1364],{"type":28,"value":1365},"?tourVariant=",{"type":28,"value":1367}," (with ",{"type":23,"tag":31,"props":1369,"children":1371},{"className":1370},[],[1372],{"type":28,"value":1373},"tourLayout",{"type":28,"value":853},{"type":23,"tag":31,"props":1376,"children":1378},{"className":1377},[],[1379],{"type":28,"value":1380},"tourFocus",{"type":28,"value":1382},"), and v1's files keep their v1 look. ",{"type":23,"tag":31,"props":1384,"children":1386},{"className":1385},[],[1387],{"type":28,"value":95},{"type":28,"value":1389}," still opens v1.",{"type":23,"tag":113,"props":1391,"children":1392},{},[1393,1422],{"type":23,"tag":117,"props":1394,"children":1395},{},[1396],{"type":23,"tag":121,"props":1397,"children":1398},{},[1399,1402,1407,1412,1417],{"type":23,"tag":125,"props":1400,"children":1401},{},[],{"type":23,"tag":125,"props":1403,"children":1404},{},[1405],{"type":28,"value":1406},"Panel",{"type":23,"tag":125,"props":1408,"children":1409},{},[1410],{"type":28,"value":1411},"Material",{"type":23,"tag":125,"props":1413,"children":1414},{},[1415],{"type":28,"value":1416},"Controls",{"type":23,"tag":125,"props":1418,"children":1419},{},[1420],{"type":28,"value":1421},"Opens with",{"type":23,"tag":136,"props":1423,"children":1424},{},[1425,1471,1515],{"type":23,"tag":121,"props":1426,"children":1427},{},[1428,1438,1456,1461,1466],{"type":23,"tag":143,"props":1429,"children":1430},{},[1431,1436],{"type":23,"tag":54,"props":1432,"children":1433},{},[1434],{"type":28,"value":1435},"v1 · Grape",{"type":28,"value":1437}," (2026-10-27)",{"type":23,"tag":143,"props":1439,"children":1440},{},[1441,1447,1448,1454],{"type":23,"tag":31,"props":1442,"children":1444},{"className":1443},[],[1445],{"type":28,"value":1446},"TourPanel",{"type":28,"value":236},{"type":23,"tag":31,"props":1449,"children":1451},{"className":1450},[],[1452],{"type":28,"value":1453},"TourBlocks",{"type":28,"value":1455},", unchanged",{"type":23,"tag":143,"props":1457,"children":1458},{},[1459],{"type":28,"value":1460},"dark grape, white type",{"type":23,"tag":143,"props":1462,"children":1463},{},[1464],{"type":28,"value":1465},"in the panel header",{"type":23,"tag":143,"props":1467,"children":1468},{},[1469],{"type":28,"value":1470},"Float · Ring",{"type":23,"tag":121,"props":1472,"children":1473},{},[1474,1482,1500,1505,1510],{"type":23,"tag":143,"props":1475,"children":1476},{},[1477],{"type":23,"tag":54,"props":1478,"children":1479},{},[1480],{"type":28,"value":1481},"v2 · Cyan",{"type":23,"tag":143,"props":1483,"children":1484},{},[1485,1491,1492,1498],{"type":23,"tag":31,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":28,"value":1490},"TourPanelCyan",{"type":28,"value":236},{"type":23,"tag":31,"props":1493,"children":1495},{"className":1494},[],[1496],{"type":28,"value":1497},"TourBlocksCyan",{"type":28,"value":1499}," (v1 recoloured, nothing else)",{"type":23,"tag":143,"props":1501,"children":1502},{},[1503],{"type":28,"value":1504},"the page's own surface; every word cyan, 600–800 (100–400 in dark mode)",{"type":23,"tag":143,"props":1506,"children":1507},{},[1508],{"type":28,"value":1509},"in the panel header, plus Ring + Dim",{"type":23,"tag":143,"props":1511,"children":1512},{},[1513],{"type":28,"value":1514},"Split · Ring + Dim",{"type":23,"tag":121,"props":1516,"children":1517},{},[1518,1526,1537,1542,1553],{"type":23,"tag":143,"props":1519,"children":1520},{},[1521],{"type":23,"tag":54,"props":1522,"children":1523},{},[1524],{"type":28,"value":1525},"v3 · Brief",{"type":23,"tag":143,"props":1527,"children":1528},{},[1529,1535],{"type":23,"tag":31,"props":1530,"children":1532},{"className":1531},[],[1533],{"type":28,"value":1534},"TourPanelBrief",{"type":28,"value":1536},": the stop's name, the question, the step's lede (a drill: its \"what if\" and what happens today), the one action, Back \u002F Next",{"type":23,"tag":143,"props":1538,"children":1539},{},[1540],{"type":28,"value":1541},"as v2",{"type":23,"tag":143,"props":1543,"children":1544},{},[1545,1551],{"type":23,"tag":31,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":28,"value":1550},"TourMetaBar",{"type":28,"value":1552},", a tour row in the mock bar: stop and its bar, beats, risk IDs, Panel, Focus, minimize, end",{"type":23,"tag":143,"props":1554,"children":1555},{},[1556],{"type":28,"value":1514},{"type":23,"tag":24,"props":1558,"children":1559},{},[1560],{"type":23,"tag":54,"props":1561,"children":1562},{},[1563],{"type":28,"value":1564},"Across v2 and v3:",{"type":23,"tag":484,"props":1566,"children":1567},{},[1568,1586,1604,1651,1677,1687,1760],{"type":23,"tag":488,"props":1569,"children":1570},{},[1571,1576,1578,1584],{"type":23,"tag":54,"props":1572,"children":1573},{},[1574],{"type":28,"value":1575},"Cyan is the tour's material.",{"type":28,"value":1577}," Ring, callouts, Example frames, the top edge and the pill take it from the host (",{"type":23,"tag":31,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":28,"value":1583},"material",{"type":28,"value":1585}," prop; grape is the default, so v1 is unchanged). Plain Tailwind cyan; no token yet (Mark: don't worry about tokens in this phase).",{"type":23,"tag":488,"props":1587,"children":1588},{},[1589,1594,1596,1602],{"type":23,"tag":54,"props":1590,"children":1591},{},[1592],{"type":28,"value":1593},"Ring + Dim",{"type":28,"value":1595}," (",{"type":23,"tag":31,"props":1597,"children":1599},{"className":1598},[],[1600],{"type":28,"value":1601},"focus: 'ringdim'",{"type":28,"value":1603},"): the scrim, with the ring at full strength (Dim alone keeps it quiet). On a dark page the scrim barely shows, so the ring carries the focus there.",{"type":23,"tag":488,"props":1605,"children":1606},{},[1607,1612,1613,1619,1620,1626,1628,1634,1636,1642,1644,1650],{"type":23,"tag":54,"props":1608,"children":1609},{},[1610],{"type":28,"value":1611},"A slow scroll",{"type":28,"value":1595},{"type":23,"tag":31,"props":1614,"children":1616},{"className":1615},[],[1617],{"type":28,"value":1618},"glide",{"type":28,"value":1050},{"type":23,"tag":31,"props":1621,"children":1623},{"className":1622},[],[1624],{"type":28,"value":1625},"TourHost",{"type":28,"value":1627},"): an eased glide (ease-in-out quint, 2026-10-29; each frame scrolls with ",{"type":23,"tag":31,"props":1629,"children":1631},{"className":1630},[],[1632],{"type":28,"value":1633},"behavior: 'instant'",{"type":28,"value":1635},", or the layer's ",{"type":23,"tag":31,"props":1637,"children":1639},{"className":1638},[],[1640],{"type":28,"value":1641},"scroll-behavior: smooth",{"type":28,"value":1643}," adds a lag of its own), 0.7–1.6 s by distance, that centres the step's first region under the sticky band (or puts its top just under the band when it's taller than the room). It stays put when the region is already in comfortable view, and a wheel or touch stops it. v1 keeps its quick ",{"type":23,"tag":31,"props":1645,"children":1647},{"className":1646},[],[1648],{"type":28,"value":1649},"scrollIntoView",{"type":28,"value":105},{"type":23,"tag":488,"props":1652,"children":1653},{},[1654,1659,1661,1667,1669,1675],{"type":23,"tag":54,"props":1655,"children":1656},{},[1657],{"type":28,"value":1658},"The dim reaches the page's floating chrome",{"type":28,"value":1660}," (Mark, same day: the sticky band and the Policy Config tray \"float above the darkened layer\"). The scrim sits under the band (z 15) so the band still covers what scrolls beneath it; ",{"type":23,"tag":31,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":28,"value":1666},"useTourChromeDim",{"type":28,"value":1668}," darkens the sticky and fixed elements stacked above the scrim (z 16–59) with a ",{"type":23,"tag":31,"props":1670,"children":1672},{"className":1671},[],[1673],{"type":28,"value":1674},"brightness(0.58)",{"type":28,"value":1676}," filter, the scrim's own strength (the v2\u002Fv3 scrim is plain black at 0.42, which is exactly that filter over any colour, so the two match; a tinted scrim didn't), while Dim or Ring + Dim is on. Nothing moves in the stack. Set at run time and restored, like Fade.",{"type":23,"tag":488,"props":1678,"children":1679},{},[1680,1685],{"type":23,"tag":54,"props":1681,"children":1682},{},[1683],{"type":28,"value":1684},"v3 drops the cyan frame",{"type":28,"value":1686}," (Mark: \"we don't need to highlight the whole page with a cyan ring\"): no 3 px top edge, and the panel's edge is a faint hairline. The ring stays on the step's region only.",{"type":23,"tag":488,"props":1688,"children":1689},{},[1690,1695,1697,1702,1704,1710,1712,1718,1720,1726,1728,1734,1736,1742,1744,1750,1752,1758],{"type":23,"tag":54,"props":1691,"children":1692},{},[1693],{"type":28,"value":1694},"Pure cyan, on white or black",{"type":28,"value":1696}," (Mark: Tailwind's cyan \"looks more green than cyan\"; the tour's ground \"white (black in dark mode) instead of a tint\"). The tour's material is CSS variables in ",{"type":23,"tag":31,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":28,"value":1625},{"type":28,"value":1703},"'s ",{"type":23,"tag":31,"props":1705,"children":1707},{"className":1706},[],[1708],{"type":28,"value":1709},"\u003Cstyle>",{"type":28,"value":1711}," with ",{"type":23,"tag":31,"props":1713,"children":1715},{"className":1714},[],[1716],{"type":28,"value":1717},"tour-*",{"type":28,"value":1719}," classes: accent ",{"type":23,"tag":31,"props":1721,"children":1723},{"className":1722},[],[1724],{"type":28,"value":1725},"#00FFFF",{"type":28,"value":1727}," (ring, glow, fills, stop bar, TOUR chip, numbered badges), type deep cyan ",{"type":23,"tag":31,"props":1729,"children":1731},{"className":1730},[],[1732],{"type":28,"value":1733},"rgb(0 104 116)",{"type":28,"value":1735}," \u002F titles ",{"type":23,"tag":31,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":28,"value":1741},"rgb(0 74 84)",{"type":28,"value":1743}," in light mode (pure cyan is ~1.25:1 on white, unreadable as text) and pure cyan itself in dark mode, ground ",{"type":23,"tag":31,"props":1745,"children":1747},{"className":1746},[],[1748],{"type":28,"value":1749},"#FFF",{"type":28,"value":1751}," \u002F ",{"type":23,"tag":31,"props":1753,"children":1755},{"className":1754},[],[1756],{"type":28,"value":1757},"#000",{"type":28,"value":1759},". Used by v3's panel, the tour row and the cyan marks; v2's panel keeps its Tailwind cyan as recorded.",{"type":23,"tag":488,"props":1761,"children":1762},{},[1763,1768,1770,1776],{"type":23,"tag":54,"props":1764,"children":1765},{},[1766],{"type":28,"value":1767},"The mock bar's beats",{"type":28,"value":1769}," ask the host for a step (",{"type":23,"tag":31,"props":1771,"children":1773},{"className":1772},[],[1774],{"type":28,"value":1775},"useTour().goTo",{"type":28,"value":1777},"), so routing and the glide are the host's, as for its own Next.",{"type":23,"tag":24,"props":1779,"children":1780},{},[1781,1786,1788,1794],{"type":23,"tag":54,"props":1782,"children":1783},{},[1784],{"type":28,"value":1785},"v4 · Tuned",{"type":28,"value":1787}," (same day): Mark redrew v3 in Illustrator (",{"type":23,"tag":31,"props":1789,"children":1791},{"className":1790},[],[1792],{"type":28,"value":1793},"illustrator\u002Fc125-tour-panel-v3*.ai",{"type":28,"value":1795},", exported for him to tune), and v4 is that drawing. v3 stays as it was.",{"type":23,"tag":484,"props":1797,"children":1798},{},[1799,1831,1870,1896,1906,1916,1932,1965,2002,2019,2037],{"type":23,"tag":488,"props":1800,"children":1801},{},[1802,1807,1808,1814,1816,1822,1824,1829],{"type":23,"tag":54,"props":1803,"children":1804},{},[1805],{"type":28,"value":1806},"Colour:",{"type":28,"value":89},{"type":23,"tag":31,"props":1809,"children":1811},{"className":1810},[],[1812],{"type":28,"value":1813},"#0099ff",{"type":28,"value":1815}," for every word and fill, white type on fills, neutral hairlines, Back outlined in the accent. The variables sit under ",{"type":23,"tag":31,"props":1817,"children":1819},{"className":1818},[],[1820],{"type":28,"value":1821},":root.qp-tour-v4",{"type":28,"value":1823},", a class the host puts on ",{"type":23,"tag":31,"props":1825,"children":1827},{"className":1826},[],[1828],{"type":28,"value":511},{"type":28,"value":1830}," while v4 runs, so the mock bar's tour row picks them up too.",{"type":23,"tag":488,"props":1832,"children":1833},{},[1834,1839,1840,1846,1848,1854,1856,1862,1863,1868],{"type":23,"tag":54,"props":1835,"children":1836},{},[1837],{"type":28,"value":1838},"Overlay:",{"type":28,"value":89},{"type":23,"tag":31,"props":1841,"children":1843},{"className":1842},[],[1844],{"type":28,"value":1845},"#73858f",{"type":28,"value":1847}," at 60% (Mark's first pick was ",{"type":23,"tag":31,"props":1849,"children":1851},{"className":1850},[],[1852],{"type":28,"value":1853},"#1f4e66",{"type":28,"value":1855},"). No ring with Dim: the cut-out is the highlight, with 12 px more room around the content than v3 (",{"type":23,"tag":31,"props":1857,"children":1859},{"className":1858},[],[1860],{"type":28,"value":1861},"ROOM",{"type":28,"value":1050},{"type":23,"tag":31,"props":1864,"children":1866},{"className":1865},[],[1867],{"type":28,"value":1625},{"type":28,"value":1869},"; Mark: \"a bit tight\"), and the callout 28 px off it. Ring and Ring + Dim still draw one.",{"type":23,"tag":488,"props":1871,"children":1872},{},[1873,1878,1880,1886,1888,1894],{"type":23,"tag":54,"props":1874,"children":1875},{},[1876],{"type":28,"value":1877},"Chrome under the overlay:",{"type":28,"value":1879}," a brightness filter can't match a tinted scrim, so ",{"type":23,"tag":31,"props":1881,"children":1883},{"className":1882},[],[1884],{"type":28,"value":1885},"TourChromeScrim",{"type":28,"value":1887}," lays the same tint over the boxes of the sticky and fixed chrome above the page scrim (",{"type":23,"tag":31,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":28,"value":1893},"useTourChromeBoxes",{"type":28,"value":1895},", measured every frame). One group carries the opacity, so overlapping pieces are tinted once. Only chrome with its own background is covered; tinting a see-through one (the page title before the band pins) tinted the page twice. A pill's radius is capped at half its height, as CSS does, so the collapsed tray isn't covered by an ellipse. The trade-off: before the band pins, the page title's text stays at full strength.",{"type":23,"tag":488,"props":1897,"children":1898},{},[1899,1904],{"type":23,"tag":54,"props":1900,"children":1901},{},[1902],{"type":28,"value":1903},"Callout:",{"type":28,"value":1905}," a white card (black in dark mode), no border, soft shadow, a 32 px numbered disc, the sentence at 13 px semibold in the accent, and a pointer toward the region.",{"type":23,"tag":488,"props":1907,"children":1908},{},[1909,1914],{"type":23,"tag":54,"props":1910,"children":1911},{},[1912],{"type":28,"value":1913},"A way out on the panel:",{"type":28,"value":1915}," a ✕ in its top-right corner, and End tour on the last step (v3 ends only from the mock bar's ✕, which scrolls away with the bar).",{"type":23,"tag":488,"props":1917,"children":1918},{},[1919,1924,1926],{"type":23,"tag":54,"props":1920,"children":1921},{},[1922],{"type":28,"value":1923},"Header and stop bar",{"type":28,"value":1925}," (Mark's second drawing): \"Tour : ",{"type":23,"tag":1927,"props":1928,"children":1929},"name",{},[1930],{"type":28,"value":1931}," ▾\" and a bold ✕ above a hairline; under it one segment per stop (the current one solid, the rest at 20%) and \"n of N\" counted from the tour's stops (OWASP has seven, so Source health is 2 of 7), then the stop's name, the question and the description.",{"type":23,"tag":488,"props":1933,"children":1934},{},[1935,1940,1942,1948,1949,1955,1957,1963],{"type":23,"tag":54,"props":1936,"children":1937},{},[1938],{"type":28,"value":1939},"Tour menu:",{"type":28,"value":1941}," the panel's top row carries the tour's name as a menu (▾) beside the ✕. It lists ",{"type":23,"tag":31,"props":1943,"children":1945},{"className":1944},[],[1946],{"type":28,"value":1947},"TOUR_CATALOG",{"type":28,"value":1595},{"type":23,"tag":31,"props":1950,"children":1952},{"className":1951},[],[1953],{"type":28,"value":1954},"data\u002Ftours\u002Findex.ts",{"type":28,"value":1956},"): written tours start where they begin, keeping Panel, Focus and iteration; the rest are named and marked \"Not written yet\". The catalog is c123's (its tours thread owns ",{"type":23,"tag":31,"props":1958,"children":1960},{"className":1959},[],[1961],{"type":28,"value":1962},"data\u002Ftours\u002F*.ts",{"type":28,"value":1964},"): five tours in the order a customer meets them, Start here, Common AI risks, Observe then enforce, AI spend, OWASP® Agentic Top 10. It closes on a pick, a click outside or Esc.",{"type":23,"tag":488,"props":1966,"children":1967},{},[1968,1973,1975,1979,1981],{"type":23,"tag":54,"props":1969,"children":1970},{},[1971],{"type":28,"value":1972},"Examples",{"type":28,"value":1974}," (Mark, on Common AI risks: the tab \"looks awkward and broken\", and \"your live value is 7\" didn't say what it meant). Each example gets the tour's pointer callout above its live card, with a ",{"type":23,"tag":54,"props":1976,"children":1977},{},[1978],{"type":28,"value":58},{"type":28,"value":1980}," box in it. Unticked: the live card shows, uncovered and highlighted, and the callout reads \"Your card today\". Ticked: the example covers the card in a dashed outline, and the callout reads \"An example, not your data \u002F Your card shows 7 today.\" (the tour data's \"your live value is N\", reworded in the component; the data is c123's). Each box unticks on a new step. While unticked the frame takes no clicks, so the live card stays usable.\n",{"type":23,"tag":484,"props":1982,"children":1983},{},[1984,1997],{"type":23,"tag":488,"props":1985,"children":1986},{},[1987,1989,1995],{"type":28,"value":1988},"Tried first, the same afternoon: the example under the step's text in the panel (an \"examples: On page · In panel\" switch). Mark moved the choice onto the card instead; capture ",{"type":23,"tag":31,"props":1990,"children":1992},{"className":1991},[],[1993],{"type":28,"value":1994},"c125-tour-panel-v4-examples-panel.png",{"type":28,"value":1996}," keeps it.",{"type":23,"tag":488,"props":1998,"children":1999},{},[2000],{"type":28,"value":2001},"Note: the step's own drill button is also labelled \"Simulate violation\", and it does something different (it runs the drill through the alert path).",{"type":23,"tag":488,"props":2003,"children":2004},{},[2005,2010,2012,2017],{"type":23,"tag":54,"props":2006,"children":2007},{},[2008],{"type":28,"value":2009},"Callouts above unpinned chrome.",{"type":28,"value":2011}," Callouts and Examples sat at z 17–18, under the page title's sticky layer, so \"Overview\" and its rule drew across them. ",{"type":23,"tag":31,"props":2013,"children":2015},{"className":2014},[],[2016],{"type":28,"value":1893},{"type":28,"value":2018}," now also reports whether any sticky chrome is pinned (its top at its sticky offset); while nothing is, v4's callouts and Examples sit at z 50, above the chrome, and once the band pins they drop back under it, so it still covers what scrolls beneath.",{"type":23,"tag":488,"props":2020,"children":2021},{},[2022,2027,2029,2035],{"type":23,"tag":54,"props":2023,"children":2024},{},[2025],{"type":28,"value":2026},"Shadow:",{"type":28,"value":2028}," docked, the panel casts the sticky band's shadow turned on its side: a 7 px contact shadow at 0.11 and a 28 px falloff at 0.08, black fading leftward (the layer's StickyBand ",{"type":23,"tag":31,"props":2030,"children":2032},{"className":2031},[],[2033],{"type":28,"value":2034},"._strip",{"type":28,"value":2036}," values).",{"type":23,"tag":488,"props":2038,"children":2039},{},[2040,2042,2048,2050,2056],{"type":28,"value":2041},"Opens with Split · Dim. Capture: ",{"type":23,"tag":31,"props":2043,"children":2045},{"className":2044},[],[2046],{"type":28,"value":2047},"c125-tour-panel-v4-tuned.png",{"type":28,"value":2049},", variant ",{"type":23,"tag":31,"props":2051,"children":2053},{"className":2052},[],[2054],{"type":28,"value":2055},"v4-tuned",{"type":28,"value":105},{"type":23,"tag":24,"props":2058,"children":2059},{},[2060,2065,2067,2073,2075,2080,2082,2088,2090,2096],{"type":23,"tag":54,"props":2061,"children":2062},{},[2063],{"type":28,"value":2064},"v5 · Panel",{"type":28,"value":2066}," (same day, from Mark's third drawing): v4 with an Example's controls in the panel. The card on the page keeps only its numbered disc. Under the step's text the panel lists each Example: the number, the card's name (the example component's own ",{"type":23,"tag":31,"props":2068,"children":2070},{"className":2069},[],[2071],{"type":28,"value":2072},"title",{"type":28,"value":2074},"), a ",{"type":23,"tag":54,"props":2076,"children":2077},{},[2078],{"type":28,"value":2079},"Simulate",{"type":28,"value":2081}," box and a scenario ",{"type":23,"tag":31,"props":2083,"children":2085},{"className":2084},[],[2086],{"type":28,"value":2087},"\u003Cselect>",{"type":28,"value":2089}," of the lab's five drills (each drill's short ",{"type":23,"tag":31,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":28,"value":2095},"label",{"type":28,"value":2097},", c123; the step's own drill is the default). Ticking, or picking a scenario, shows the example on its card. Each pick resets on a new step.",{"type":23,"tag":484,"props":2099,"children":2100},{},[2101,2158],{"type":23,"tag":488,"props":2102,"children":2103},{},[2104,2106,2112,2114,2120,2121,2126,2128,2134,2135,2141,2142,2148,2150,2156],{"type":28,"value":2105},"How the pick reaches the card: an Example's render reads its drill from ",{"type":23,"tag":31,"props":2107,"children":2109},{"className":2108},[],[2110],{"type":28,"value":2111},"ctx.drills[\u003Cits drill id>]",{"type":28,"value":2113},", so the host hands it a context where every drill id resolves to the chosen scenario (",{"type":23,"tag":31,"props":2115,"children":2117},{"className":2116},[],[2118],{"type":28,"value":2119},"scenarioCtx",{"type":28,"value":1050},{"type":23,"tag":31,"props":2122,"children":2124},{"className":2123},[],[2125],{"type":28,"value":1625},{"type":28,"value":2127},"). Every Example card is now computed from its drill (c123 replaced the fixed ones the same afternoon: ",{"type":23,"tag":31,"props":2129,"children":2131},{"className":2130},[],[2132],{"type":28,"value":2133},"findingsExample",{"type":28,"value":991},{"type":23,"tag":31,"props":2136,"children":2138},{"className":2137},[],[2139],{"type":28,"value":2140},"sensitiveExample",{"type":28,"value":991},{"type":23,"tag":31,"props":2143,"children":2145},{"className":2144},[],[2146],{"type":28,"value":2147},"sourcesExample",{"type":28,"value":2149}," on a shared ",{"type":23,"tag":31,"props":2151,"children":2153},{"className":2152},[],[2154],{"type":28,"value":2155},"cardExample",{"type":28,"value":2157},"), so each follows the pick; a scenario that raises nothing on a card leaves it at its base value with \"nothing this scenario would raise here\".",{"type":23,"tag":488,"props":2159,"children":2160},{},[2161,2163,2169,2170,2176],{"type":28,"value":2162},"Capture: ",{"type":23,"tag":31,"props":2164,"children":2166},{"className":2165},[],[2167],{"type":28,"value":2168},"c125-tour-panel-v5-panel.png",{"type":28,"value":2049},{"type":23,"tag":31,"props":2171,"children":2173},{"className":2172},[],[2174],{"type":28,"value":2175},"v5-panel",{"type":28,"value":105},{"type":23,"tag":24,"props":2178,"children":2179},{},[2180,2185,2187,2193,2194,2200,2202,2208,2209,2214,2215,2221,2222,2228,2230,2236,2238,2244,2246,2252,2254,2259,2261,2267,2269,2275,2277,2283,2285,2290],{"type":23,"tag":54,"props":2181,"children":2182},{},[2183],{"type":28,"value":2184},"The callout, one component",{"type":28,"value":2186}," (same day, from Mark's callout sheet): ",{"type":23,"tag":31,"props":2188,"children":2190},{"className":2189},[],[2191],{"type":28,"value":2192},"TourMarker",{"type":28,"value":1595},{"type":23,"tag":31,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":28,"value":2199},"components\u002Ftour\u002FMarker.vue",{"type":28,"value":2201},") draws every callout v4 and v5 show. Props: ",{"type":23,"tag":31,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":28,"value":2207},"n",{"type":28,"value":991},{"type":23,"tag":31,"props":2210,"children":2212},{"className":2211},[],[2213],{"type":28,"value":2072},{"type":28,"value":991},{"type":23,"tag":31,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":28,"value":2220},"description",{"type":28,"value":991},{"type":23,"tag":31,"props":2223,"children":2225},{"className":2224},[],[2226],{"type":28,"value":2227},"size",{"type":28,"value":2229}," (lg, sm), ",{"type":23,"tag":31,"props":2231,"children":2233},{"className":2232},[],[2234],{"type":28,"value":2235},"pointer",{"type":28,"value":2237}," (left, center, none) and ",{"type":23,"tag":31,"props":2239,"children":2241},{"className":2240},[],[2242],{"type":28,"value":2243},"pointerSide",{"type":28,"value":2245}," (bottom when it sits above what it marks, top when below). With neither title nor description it's a pin: a teardrop with the disc upright inside. Extra content goes in its slot (v4's Simulate box). It's presentational: ",{"type":23,"tag":31,"props":2247,"children":2249},{"className":2248},[],[2250],{"type":28,"value":2251},"TourCallout",{"type":28,"value":2253}," positions it over a region (data's ",{"type":23,"tag":31,"props":2255,"children":2257},{"className":2256},[],[2258],{"type":28,"value":28},{"type":28,"value":2260}," is its description; a title and size are optional props), ",{"type":23,"tag":31,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":28,"value":2266},"TourExample",{"type":28,"value":2268}," over a card. The tour's material moved to ",{"type":23,"tag":31,"props":2270,"children":2272},{"className":2271},[],[2273],{"type":28,"value":2274},"components\u002Ftour\u002Ftour-material.css",{"type":28,"value":2276}," so the gallery can load it without running a tour; ",{"type":23,"tag":31,"props":2278,"children":2280},{"className":2279},[],[2281],{"type":28,"value":2282},".qp-tour-v4-scope",{"type":28,"value":2284}," gives v4's colours to one element's subtree. Gallery: \"The callout: TourMarker\" on ",{"type":23,"tag":31,"props":2286,"children":2288},{"className":2287},[],[2289],{"type":28,"value":1338},{"type":28,"value":105},{"type":23,"tag":24,"props":2292,"children":2293},{},[2294,2299,2301,2307,2308,2314,2316,2322],{"type":23,"tag":54,"props":2295,"children":2296},{},[2297],{"type":28,"value":2298},"Where a callout goes",{"type":28,"value":2300}," (same day; Mark, on Start here's \"Add endpoints\" callout running under the docked panel and over the mock bar's controls). ",{"type":23,"tag":31,"props":2302,"children":2304},{"className":2303},[],[2305],{"type":28,"value":2306},"TourFloat",{"type":28,"value":1595},{"type":23,"tag":31,"props":2309,"children":2311},{"className":2310},[],[2312],{"type":28,"value":2313},"components\u002Ftour\u002FFloat.vue",{"type":28,"value":2315},") places every v4\u002Fv5 marker with Floating UI (",{"type":23,"tag":31,"props":2317,"children":2319},{"className":2318},[],[2320],{"type":28,"value":2321},"@floating-ui\u002Fdom",{"type":28,"value":2323},", added to design for this):",{"type":23,"tag":646,"props":2325,"children":2326},{},[2327,2359,2393,2424,2449],{"type":23,"tag":488,"props":2328,"children":2329},{},[2330,2335,2336,2342,2344,2349,2351,2357],{"type":23,"tag":54,"props":2331,"children":2332},{},[2333],{"type":28,"value":2334},"Safe area",{"type":28,"value":1595},{"type":23,"tag":31,"props":2337,"children":2339},{"className":2338},[],[2340],{"type":28,"value":2341},"tourSafeArea",{"type":28,"value":2343},", provided by ",{"type":23,"tag":31,"props":2345,"children":2347},{"className":2346},[],[2348],{"type":28,"value":1625},{"type":28,"value":2350},", viewport coordinates): below the lab's own chrome (anything marked ",{"type":23,"tag":31,"props":2352,"children":2354},{"className":2353},[],[2355],{"type":28,"value":2356},"data-qp-tour-avoid",{"type":28,"value":2358},": the mock bar) and below chrome pinned at the top (the band); 16 px short of the tour panel on whichever side it sits; 8 px off the window's edges.",{"type":23,"tag":488,"props":2360,"children":2361},{},[2362,2367,2369,2375,2377,2383,2385,2391],{"type":23,"tag":54,"props":2363,"children":2364},{},[2365],{"type":28,"value":2366},"Sides in order:",{"type":28,"value":2368}," the preferred placement (default ",{"type":23,"tag":31,"props":2370,"children":2372},{"className":2371},[],[2373],{"type":28,"value":2374},"top-start",{"type":28,"value":2376},"; pins ",{"type":23,"tag":31,"props":2378,"children":2380},{"className":2379},[],[2381],{"type":28,"value":2382},"top",{"type":28,"value":2384},"), then top, bottom, right, left; the first that fits, else the one with the most room (",{"type":23,"tag":31,"props":2386,"children":2388},{"className":2387},[],[2389],{"type":28,"value":2390},"flip",{"type":28,"value":2392},", best fit).",{"type":23,"tag":488,"props":2394,"children":2395},{},[2396,2401,2402,2408,2410,2415,2416,2422],{"type":23,"tag":54,"props":2397,"children":2398},{},[2399],{"type":28,"value":2400},"Slide, keep pointing:",{"type":28,"value":89},{"type":23,"tag":31,"props":2403,"children":2405},{"className":2404},[],[2406],{"type":28,"value":2407},"shift",{"type":28,"value":2409}," keeps it inside; the pointer (TourMarker ",{"type":23,"tag":31,"props":2411,"children":2413},{"className":2412},[],[2414],{"type":28,"value":2243},{"type":28,"value":1751},{"type":23,"tag":31,"props":2417,"children":2419},{"className":2418},[],[2420],{"type":28,"value":2421},"pointerAt",{"type":28,"value":2423},", now on any edge at any offset) aims at the target's start: a row's name, not the middle of a wide row.",{"type":23,"tag":488,"props":2425,"children":2426},{},[2427,2432,2434,2440,2442,2447],{"type":23,"tag":54,"props":2428,"children":2429},{},[2430],{"type":28,"value":2431},"Author hint:",{"type":28,"value":2433}," a callout in tour data may carry ",{"type":23,"tag":31,"props":2435,"children":2437},{"className":2436},[],[2438],{"type":28,"value":2439},"placement",{"type":28,"value":2441}," (Floating UI's names); it's a first choice, not an order. The field is c123's to add to ",{"type":23,"tag":31,"props":2443,"children":2445},{"className":2444},[],[2446],{"type":28,"value":2251},{"type":28,"value":2448},"; the host already passes it through.",{"type":23,"tag":488,"props":2450,"children":2451},{},[2452,2457,2459,2465,2467,2472,2474,2480],{"type":23,"tag":54,"props":2453,"children":2454},{},[2455],{"type":28,"value":2456},"Don't cover what the step highlights",{"type":28,"value":2458}," (Mark, same day, after the installer token callout sat over the Download buttons): the host provides ",{"type":23,"tag":31,"props":2460,"children":2462},{"className":2461},[],[2463],{"type":28,"value":2464},"tourObstacles",{"type":28,"value":2466}," (the step's ring regions, Example frames and every callout's target, page coordinates). Floating UI has no obstacles, so ",{"type":23,"tag":31,"props":2468,"children":2470},{"className":2469},[],[2471],{"type":28,"value":2306},{"type":28,"value":2473}," tries each side in turn (offset + shift) and scores it: area outside the safe area plus area over any obstacle. The first clear side wins, else the least covered. Checked on Start here · installer with the step's ",{"type":23,"tag":31,"props":2475,"children":2477},{"className":2476},[],[2478],{"type":28,"value":2479},"bottom-start",{"type":28,"value":2481}," hint ignored: the rule alone puts the callout below the Download area, over none of its buttons.",{"type":23,"tag":484,"props":2483,"children":2484},{},[2485],{"type":23,"tag":488,"props":2486,"children":2487},{},[2488,2490,2496],{"type":28,"value":2489},"Checked: Start here · open now puts the callout left of \"Add endpoints\", clear of the mock bar and the panel (",{"type":23,"tag":31,"props":2491,"children":2493},{"className":2492},[],[2494],{"type":28,"value":2495},"c125-tour-v4-start-here-open.png",{"type":28,"value":2497},"); the Sources row callout, v4's example callouts and v5's pins still sit above their targets.",{"type":23,"tag":24,"props":2499,"children":2500},{},[2501,2506],{"type":23,"tag":54,"props":2502,"children":2503},{},[2504],{"type":28,"value":2505},"Minimize",{"type":28,"value":2507}," (same day): v4 and v5's panel has a minimize button beside the ✕. Minimized, the overlay, the marks and the split column go, and the tour shrinks to a 48 px circle in the tour's blue at the bottom right (a placeholder route icon; the icon is to be designed). The circle reopens the tour on the same step. v1–v3 keep their pill.",{"type":23,"tag":24,"props":2509,"children":2510},{},[2511],{"type":23,"tag":54,"props":2512,"children":2513},{},[2514],{"type":28,"value":2515},"Open:",{"type":23,"tag":484,"props":2517,"children":2518},{},[2519,2524,2529,2548],{"type":23,"tag":488,"props":2520,"children":2521},{},[2522],{"type":28,"value":2523},"The tour row scrolls away with the mock bar; a sticky one would sit over the band. Back \u002F Next stay in the panel.",{"type":23,"tag":488,"props":2525,"children":2526},{},[2527],{"type":28,"value":2528},"v3 hides the numbers, mitigations and lists. They're still in the tour data (for v1, v2 and the MCP guide). Where they come back, if at all, is the manual design pass.",{"type":23,"tag":488,"props":2530,"children":2531},{},[2532,2534,2540,2541,2546],{"type":28,"value":2533},"In Split, a wide table (Sources) still runs under the docked panel. Its ring and the dim's hole stop 16 px short of the panel (",{"type":23,"tag":31,"props":2535,"children":2537},{"className":2536},[],[2538],{"type":28,"value":2539},"clearOfDock",{"type":28,"value":1050},{"type":23,"tag":31,"props":2542,"children":2544},{"className":2543},[],[2545],{"type":28,"value":1625},{"type":28,"value":2547},", v2 and v3), so the highlight never butts against the tour's column.",{"type":23,"tag":488,"props":2549,"children":2550},{},[2551,2553,2559,2561,2567],{"type":28,"value":2552},"Captures: ",{"type":23,"tag":31,"props":2554,"children":2556},{"className":2555},[],[2557],{"type":28,"value":2558},"public\u002Fcycles\u002Fdesign\u002Fc125-tour-panel-{v1-grape,v2-cyan,v3-brief}.png",{"type":28,"value":2560},", subject ",{"type":23,"tag":31,"props":2562,"children":2564},{"className":2563},[],[2565],{"type":28,"value":2566},"page\u002Fphase4-tour-panel",{"type":28,"value":2568}," (one variant lane each), on Source health · Watch.",1794599454040]