/* ===========================================================================
   tour.css — the forty-five second tour, as a thing that plays itself

   WHY THIS EXISTS. The home page could already show every piece of the
   product, but only as five separate pieces: a terminal here, a packet
   crossing a diagram there, a capture window filling further down. A visitor
   who has never heard the name has to assemble the story themselves, and the
   question they actually arrived with — "what is it like to use this?" — was
   never answered in one go.

   This is that answer, as five scenes that play in order: drop three devices
   on a canvas, start one, configure it, ping across it and read the frames,
   and then the price. It is a video in every way that matters to a reader
   and in no way that matters to a server: there is no file to download, it
   is a few kilobytes of CSS, it follows whichever theme and skin they are
   in, and it is as sharp on a 4K monitor as on a phone.

   HOW IT IS BUILT, and the one rule that matters. Every animation here is
   declared under `.sc.on`. Nothing animates until tour.js puts `on` on a
   scene, and taking `on` off resets it — which is what makes the scenes
   replayable, and why the chapter buttons can jump anywhere without the
   animations drifting out of step. assets/tour.js owns the timing; this file
   owns what a scene looks like while its turn lasts.

   Three states have to look deliberate, not broken:

     * no script          — `.tour` never gets `ready`, and the fourth scene
                            is left visible as a finished still.
     * reduced motion     — `.still`: every animation off, every element in
                            its final state, the packets hidden rather than
                            parked at the left edge.
     * paused, or off the  — `.paused` freezes the CSS as well as the timer,
       screen / tab          because a frozen timer over a running animation
                             is how a scene ends up half-drawn.

   Added as a layer: this stylesheet is loaded after theme.css and themes.css
   and every rule in it is scoped to `.tour`, so deleting the file and the
   block in index.html removes the tour and changes nothing else.
   =========================================================================== */

/* ------------------------------------------------------------ the player */
.tour{margin:0;position:relative}
.tour .tv{border:1px solid var(--line2);border-radius:var(--r-lg);background:var(--panel);
          box-shadow:var(--shadow-l);overflow:hidden}

/* the window chrome, so this reads as the product and not as an advert */
.tour .tvbar{display:flex;align-items:center;gap:7px;padding:10px 13px;
             background:var(--panel2);border-bottom:1px solid var(--line)}
.tour .tvbar .dot{width:10px;height:10px;border-radius:50%;background:var(--line2);flex:0 0 auto}
.tour .tvbar .dot.r{background:#f87171} .tour .tvbar .dot.y{background:#fbbf24}
.tour .tvbar .dot.g{background:#34d399}
.tour .tvbar .addr{flex:1;margin-left:10px;font:11.5px/1.6 var(--mono);color:var(--ink3);
             background:var(--panel);border:1px solid var(--line);border-radius:6px;
             padding:3px 10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tour .tvbar .len{font:600 10.5px var(--sans);color:var(--ink4);white-space:nowrap;
             display:inline-flex;align-items:center;gap:6px}
.tour .tvbar .len::before{content:'';width:7px;height:7px;border-radius:50%;
             background:var(--ok);animation:tlive 2.4s ease-in-out infinite}
@keyframes tlive{0%,100%{opacity:1}50%{opacity:.35}}

/* The stage keeps its own shape whatever is inside it. Scenes are stacked on
   top of each other and cross-faded, so a scene that happens to be shorter
   than the one before cannot make the page jump as it arrives. */
.tour .stage{position:relative;aspect-ratio:16/9;min-height:280px;overflow:hidden;
    background:
      radial-gradient(760px 320px at 18% -10%, var(--tint-accent), transparent 64%),
      linear-gradient(var(--line) 1px, transparent 1px) 0 0/44px 44px,
      linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0/44px 44px,
      var(--panel)}
/* 16:9 is the shape, up to a point: on a wide monitor the ratio alone would
   give a stage six hundred pixels tall with the drawing swimming in it. */
.tour .stage{max-height:470px}
@media(max-width:760px){.tour .stage{aspect-ratio:auto;max-height:none;min-height:0;height:360px}}

.tour .sc{position:absolute;inset:0;padding:16px 18px 18px;opacity:0;visibility:hidden;
          pointer-events:none;transition:opacity .4s ease,visibility 0s linear .4s}
.tour .sc.on{opacity:1;visibility:visible;pointer-events:auto;
             transition:opacity .4s ease,visibility 0s}
/* With no script nothing is ever switched on, so one scene is left showing. */
.tour:not(.ready) .sc.lead{opacity:1;visibility:visible}

/* the chapter name, printed on the scene the way a chapter title would be */
.tour .sct{position:absolute;left:18px;top:14px;z-index:3;
    font:600 11px/1 var(--sans);letter-spacing:.3px;text-transform:uppercase;
    color:var(--accent);background:var(--panel);border:1px solid var(--edge-accent);
    border-radius:999px;padding:6px 11px}
.tour .sc.on .sct{animation:tchip .5s ease both}
@keyframes tchip{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* the line of prose under the picture, which changes with the scene */
.tour .scs{position:absolute;left:18px;right:18px;bottom:14px;z-index:3;margin:0;
    font:13px/1.6 var(--sans);color:var(--ink2)}
.tour .scs b{color:var(--ink);font-weight:600}
.tour .sc.on .scs{animation:tup .6s ease .25s both}
@keyframes tup{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ------------------------------------------------------- the controls row */
.tour .foot{display:flex;align-items:center;gap:14px;padding:11px 13px;
            border-top:1px solid var(--line);background:var(--panel2)}
.tour .pp{flex:0 0 auto;width:30px;height:30px;border-radius:50%;cursor:pointer;
    display:grid;place-items:center;color:var(--accent);
    background:var(--panel);border:1px solid var(--edge-accent)}
.tour .pp:hover{background:var(--tint-accent)}
.tour .pp svg{width:12px;height:12px;fill:currentColor}
.tour .pp .ipause{display:none}
.tour.paused .pp .ipause,.tour.still .pp .ipause{display:block}
.tour.paused .pp .iplay,.tour.still .pp .iplay{display:none}

.tour .chap{display:flex;gap:9px;flex:1;list-style:none;margin:0;padding:0;min-width:0}
.tour .chap li{flex:1;min-width:0}
.tour .chap button{display:block;width:100%;padding:0;margin:0;border:0;background:none;
                   cursor:pointer;text-align:left}
.tour .chap .bar{display:block;height:3px;border-radius:2px;background:var(--line2);
                 overflow:hidden}
.tour .chap .bar i{display:block;height:100%;width:0;border-radius:2px;
                   background:linear-gradient(90deg,var(--accent),var(--accent2))}
.tour .chap li.done .bar i{width:100%}
.tour .chap li.now .bar i{animation:tfill var(--d,9s) linear both}
@keyframes tfill{from{width:0}to{width:100%}}
.tour.paused .chap li.now .bar i{animation-play-state:paused}
.tour .chap .lb{display:block;margin-top:7px;font:600 11px/1.3 var(--sans);color:var(--ink4);
                white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tour .chap li.now .lb{color:var(--ink)}
.tour .chap button:hover .lb{color:var(--accent)}
.tour .chap button:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
@media(max-width:640px){.tour .chap .lb{display:none}}

.tour figcaption{margin:12px 2px 0;font-size:11.5px;color:var(--ink4);line-height:1.65}

/* ====================================================== the shared drawing

   Scenes one, two and four are the same three devices in the same places, so
   they share one set of classes. The positions are user units in a
   640 x 300 viewBox and the labels are the real interface names. */
.tour svg.top{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.tour .wire{stroke:var(--line2);stroke-width:2.5;stroke-linecap:round;fill:none}
.tour .box{fill:var(--panel2);stroke:var(--line2);stroke-width:1.2}
.tour .tag{fill:var(--ink);font:600 12px var(--mono);text-anchor:middle}
.tour .nm{fill:var(--ink4);font:10.5px var(--sans);text-anchor:middle}
.tour .ifl{fill:var(--ink4);font:9.5px var(--mono);text-anchor:middle}
.tour .ring{fill:none;stroke-width:2;transform-box:fill-box;transform-origin:center}

/* --------------------------------------------------- 1 · build the lab
   The devices arrive one at a time and the cables draw themselves between
   them, because that is the order it happens in on the canvas. */
.tour .sc.on .nd{animation:tpop .55s cubic-bezier(.2,.9,.3,1.3) both}
@keyframes tpop{from{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:none}}
.tour .nd{transform-box:fill-box;transform-origin:center}
.tour .sc.on .ln1{animation:tdraw .7s ease 1.9s both}
.tour .sc.on .ln2{animation:tdraw .7s ease 2.6s both}
.tour .ln1,.tour .ln2{stroke-dasharray:180;stroke-dashoffset:180}
@keyframes tdraw{from{stroke-dashoffset:180}to{stroke-dashoffset:0}}
.tour .sc.on .ifl{animation:tfade .5s ease 3.2s both}
@keyframes tfade{from{opacity:0}to{opacity:1}}

/* the toast that confirms the canvas saved itself */
.tour .toast i{font-style:normal}
.tour .toast{position:absolute;right:18px;top:14px;z-index:3;
    display:inline-flex;align-items:center;gap:8px;font:600 11.5px var(--sans);
    color:var(--ok);background:var(--tint-ok);border:1px solid var(--edge-ok);
    border-radius:999px;padding:7px 12px}
.tour .sc.on .toast{animation:tslide .6s ease 4.4s both}
@keyframes tslide{from{opacity:0;transform:translateX(14px)}to{opacity:1;transform:none}}

/* ------------------------------------------------------ 2 · start a device
   One device starts, not the lab: that is how the product works and it is
   how the scene plays. The bar is honest about the wait — most of the fifty
   seconds is IOS asleep inside the image, not the server thinking. */
.tour .panel{position:absolute;left:18px;right:18px;bottom:64px;z-index:2;
    background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
    padding:12px 14px}
.tour .panel .hd{display:flex;align-items:center;gap:9px;margin-bottom:9px}
.tour .panel .hd b{font:600 12.5px var(--sans);color:var(--ink)}
.tour .pill{margin-left:auto;font:600 10.5px var(--sans);border-radius:999px;padding:4px 10px;
            border:1px solid var(--edge-warn);color:var(--warn);background:var(--tint-warn)}
.tour .pill.ok{border-color:var(--edge-ok);color:var(--ok);background:var(--tint-ok);
               position:absolute;right:14px;top:12px}
.tour .sc.on .pill.ok{animation:tfade .4s ease 7.3s both}
.tour .sc.on .pill.go{animation:tgone .4s ease 7.3s both}
@keyframes tgone{to{opacity:0}}
.tour .prog{height:5px;border-radius:3px;background:var(--line2);overflow:hidden}
.tour .prog i{display:block;height:100%;width:0;border-radius:3px;
              background:linear-gradient(90deg,var(--accent),var(--ok))}
.tour .sc.on .prog i{animation:tfill 7s linear .4s both}
.tour .boot{margin:9px 0 0;font:11.5px/1.75 var(--mono);color:var(--ink3);
            white-space:pre;overflow:hidden}
.tour .boot span{display:block}
.tour .boot span.v{color:var(--ok)}
.tour .sc.on .boot span{animation:tline .45s ease both;animation-delay:var(--d,0s)}
@keyframes tline{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
/* the device being started takes the accent and keeps a ring around it */
.tour .sc.on .ring{animation:tping 2.2s ease-out infinite}
@keyframes tping{0%{opacity:.75;transform:scale(1)}100%{opacity:0;transform:scale(1.5)}}

/* ------------------------------------------------------- 3 · the console
   A terminal typing real commands in the product's own monospace face. Each
   line carries its own character count and start time, so the typing has the
   rhythm of somebody typing rather than of text being revealed. */
.tour .sc.term3{padding:0}
.tour .cons{position:absolute;inset:0;background:var(--term-bg);color:var(--term-ink);
    font:12.5px/1.85 var(--mono);padding:44px 18px 46px;overflow:hidden}
.tour .cons .l{display:block;white-space:pre;overflow:hidden;width:0}
.tour .sc.on .cons .l{animation:ttype var(--t,.75s) steps(var(--n,20),end) var(--d,0s) both}
@keyframes ttype{from{width:0}to{width:calc(var(--n,20) * 1ch)}}
.tour .cons .p{color:var(--accent2)}      /* the prompt */
.tour .cons .c{color:#e6edf7}             /* what was typed */
.tour .cons .v{color:#34d399}             /* the adjacency coming up */
.tour .cons .cur{display:inline-block;width:8px;height:14px;vertical-align:-2px;
                 background:var(--term-ink)}
.tour .sc.on .cons .cur{animation:tfade .2s linear 9.6s both,nbblink 1.1s step-end 9.6s infinite}
@keyframes nbblink{0%,100%{opacity:1}50%{opacity:0}}

/* --------------------------------------------------- 4 · ping, and capture
   The payoff: one packet crosses the topology, the reply comes back, and the
   same frames appear in a capture list underneath — which is the whole
   argument the page is making, in one picture. */
.tour .pkt{transform-box:view-box;transform-origin:0 0}
.tour .pkt rect{fill:var(--accent)}
.tour .pkt text{fill:#fff;font:600 8.5px var(--sans);text-anchor:middle}
.tour .pkt.back rect{fill:var(--ok)}
.tour .sc.on .pkt.go{animation:tgo 2s cubic-bezier(.4,0,.6,1) 1s both}
.tour .sc.on .pkt.back{animation:tback 2s cubic-bezier(.4,0,.6,1) 3.3s both}
@keyframes tgo  {0%{opacity:0;transform:translateX(0)}8%{opacity:1}
                 92%{opacity:1}100%{opacity:0;transform:translateX(340px)}}
@keyframes tback{0%{opacity:0;transform:translateX(340px)}8%{opacity:1}
                 92%{opacity:1}100%{opacity:0;transform:translateX(0)}}

.tour .caps{position:absolute;left:18px;right:18px;bottom:64px;z-index:2;
    background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
    overflow:hidden}
.tour .caps .ch{display:flex;align-items:center;gap:8px;padding:7px 11px;
    background:var(--panel2);border-bottom:1px solid var(--line);
    font:600 11px var(--sans);color:var(--ink2)}
.tour .caps .ch .dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:0 0 auto}
.tour .caps .ch .sp{margin-left:auto;font:10px var(--mono);color:var(--ink4)}
.tour .caps .r{display:grid;grid-template-columns:34px 54px 1fr 1fr 44px;gap:8px;
    padding:4px 11px;font:11px/1.7 var(--mono);color:var(--ink3);
    border-top:1px solid var(--line)}
.tour .caps .r:first-of-type{border-top:0}
.tour .caps .r b{font-weight:600;color:var(--ink2)}
.tour .caps .r.hit b{color:var(--ok)}
.tour .sc.on .caps .r{animation:tline .4s ease both;animation-delay:var(--d,0s)}
.tour .caps .cf{display:flex;align-items:center;gap:8px;padding:6px 11px;
    border-top:1px solid var(--line);background:var(--panel2);
    font:10.5px var(--mono);color:var(--ink4)}
.tour .sc.on .caps .cf{animation:tfade .45s ease 6.2s both}
.tour .caps .cf em{font-style:normal;color:var(--ok);font-weight:600}
@media(max-width:760px){.tour .caps .r{grid-template-columns:30px 1fr 1fr 40px;font-size:10px}
                        .tour .caps .r span:nth-child(2){display:none}}

/* ------------------------------------------------------------ on a phone
   The drawing and the panel under it are stacked rather than overlaid: the
   topography takes the top of the stage and everything that was floating
   near the bottom edge moves up out of the caption's way. */
@media(max-width:760px){
  .tour svg.top{height:46%}
  .tour .panel,.tour .caps{bottom:58px;left:12px;right:12px}
  .tour .boot{font-size:10px}
  .tour .cons{font-size:9.5px;padding:40px 12px 42px}
  .tour .scs{font-size:12px;left:12px;right:12px}
  .tour .sct{left:12px}
  .tour .toast{right:12px}
}

/* ---------------------------------------------------------- 5 · the price
   The last frame is the only one with links in it, because a tour that ends
   without telling you where to go has wasted the forty-five seconds. */
.tour .end{position:absolute;inset:0;display:grid;place-content:center;gap:16px;
    text-align:center;padding:30px 24px;
    background:radial-gradient(620px 300px at 50% 0,var(--tint-accent),transparent 70%)}
.tour .end h3{margin:0;font:700 clamp(21px,3.2vw,30px)/1.15 var(--sans);
              letter-spacing:-.8px;color:var(--ink)}
.tour .end h3 em{font-style:normal;color:var(--accent)}
.tour .end p{margin:0 auto;max-width:48ch;font:14px/1.7 var(--sans);color:var(--ink2)}
.tour .end .row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.tour .end .chips{display:flex;gap:7px;justify-content:center;flex-wrap:wrap;
                  font:600 11px var(--sans);color:var(--ink3)}
.tour .end .chips span{border:1px solid var(--line);border-radius:999px;padding:5px 11px;
                       background:var(--panel)}
.tour .sc.on .end > *{animation:tup .6s ease both;animation-delay:var(--d,0s)}

/* ====================================================== the quiet versions

   Paused, hidden or scrolled away: freeze the drawing as well as the timer.
   Reduced motion: no animation at all, and every element in the state it
   would have finished in — except the packets, which have nowhere sensible
   to sit still, so they are taken out rather than parked. */
.tour.paused .sc *{animation-play-state:paused!important}

.tour.still .sc *,.tour.still .tvbar .len::before{animation:none!important}
.tour.still .sc{transition:none}
.tour.still .nd,.tour.still .ifl,.tour.still .toast,.tour.still .boot span,
.tour.still .caps .r,.tour.still .caps .cf,.tour.still .end > *,
.tour.still .pill.ok,.tour.still .cons .cur{opacity:1;transform:none}
.tour.still .ln1,.tour.still .ln2{stroke-dashoffset:0}
.tour.still .cons .l{width:auto}
.tour.still .prog i,.tour.still .chap li.now .bar i{width:100%}
.tour.still .pkt,.tour.still .ring,.tour.still .pill.go,
.tour:not(.ready) .pkt{display:none}
.tour.still .note{display:block}
.tour .note{display:none;margin-left:auto;font:600 10.5px var(--sans);color:var(--ink4)}
