/* Hallmark, macrostructure: Narrative Workflow, tone: utilitarian, anchor hue: cyan
 * Nova Wizard project page. Tokens are lifted verbatim from the wizard's own
 * static/index.html so the page and the tool read as one product. Self-contained:
 * no CDN, no remote images, no network at all. The typeface is Vazirmatn,
 * self-hosted below from the same subset files the Nova panel ships.
 * House rule from the panel: the brand gradient is for the Nova mark only.
 * Actions are solid accent, never gradient.
 */

/* ---- typeface ----
 * Vazirmatn, variable, 400 to 800 in one file per script. Paths are relative
 * to THIS stylesheet, so both /index.html and /fa/index.html resolve them to
 * docs/fonts/ without either page needing its own copy of the rule.
 * The unicode-range split means an English reader never downloads the 46 KB
 * Arabic file, and a Farsi reader downloads the Latin one only when the page
 * actually shows Latin (it does: Cloudflare, Python, the commands).
 */
@font-face{font-family:'Vazirmatn';src:url('fonts/Vazirmatn-arabic.woff2') format('woff2');font-weight:400 800;font-style:normal;font-display:swap;unicode-range:U+0600-06FF,U+0750-077F,U+08A0-08FF,U+FB50-FDFF,U+FE70-FEFF}
@font-face{font-family:'Vazirmatn';src:url('fonts/Vazirmatn-latin.woff2') format('woff2');font-weight:400 800;font-style:normal;font-display:swap;unicode-range:U+0000-00FF}
@font-face{font-family:'Vazirmatn';src:url('fonts/Vazirmatn-latin-ext.woff2') format('woff2');font-weight:400 800;font-style:normal;font-display:swap;unicode-range:U+0100-024F}

/* ---- tokens: dark is the base, exactly as the wizard ships it ---- */
:root{
  color-scheme:dark;
  --bg:#070809; --panel:#0c0e12; --card:#101319; --card2:#0b0d11; --field:#0b0d11;
  --bd:#1c2027; --bd2:#262b34;
  --tx:#e9edf4; --tx2:#aeb6c4; --mu:#7b8494;
  --ac:#22d3ee; --ac2:#a855f7; --ok:#34d399; --dg:#f87171; --wn:#f5b042;
  --ac-fill:#22d3ee; --ac-fill-h:#3fdcf3; --ac-ink:#04121a; --link:#22d3ee;
  --ac-soft:rgba(34,211,238,.12); --ac-line:rgba(34,211,238,.34); --ac-deep:#22d3ee;
  --v-soft:rgba(168,85,247,.10);  --v-line:rgba(168,85,247,.32); --v-ink:#bd8af8;
  --ok-soft:rgba(52,211,153,.10); --ok-line:rgba(52,211,153,.30);
  --dg-soft:rgba(248,113,113,.10);--dg-line:rgba(248,113,113,.32);
  --ring:rgba(34,211,238,.35);
  /* the focus ring is a non-text UI component: it needs 3:1 against the
     surface it sits on, which --ac does not reach on the light paper. */
  --focus:#22d3ee;
  --shadow:0 1px 0 rgba(255,255,255,.02),0 12px 30px rgba(0,0,0,.45);
  --nav:rgba(7,8,9,.82);
  --mark:linear-gradient(80deg,#9d4efb 0%,#02cdf3 100%);
  --radius:12px; --r-sm:9px; --r-lg:16px; --sp:14px;
  /* Code sits ON the page, not in a card, so it is pitched one notch away
     from the page rather than borrowing a card surface. */
  --code-bg:#0c0f14; --code-bd:#1f242c; --inline-bg:#11151b;
  --img-shadow:0 10px 30px rgba(0,0,0,.45);

  --font:'Vazirmatn',system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --font-fa:'Vazirmatn','Segoe UI',Tahoma,system-ui,Arial,sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,'Liberation Mono',monospace;
  --ease:cubic-bezier(.23,1,.32,1);

  /* ---- type scale ----
   * Five text sizes, not ten. Hierarchy is carried by weight and colour as
   * much as by size, which is the point of a 400-to-800 variable face.
   * 12 meta / 13.5 support / 15 body / 16 heading / 20 section / display.
   */
  --t-meta:12px; --t-sm:13.5px; --t-body:15px; --t-h3:16px; --t-h2:20px;
  --t-h1:clamp(1.85rem,5.4vw,2.3rem);
  --t-code:13px; --t-term:12.5px;

  /* Latin line heights and tracking. The Farsi root below replaces every one
     of these, so no RTL text ever inherits a value chosen for Latin. */
  --lh-body:1.62; --lh-sm:1.65; --lh-lead:1.7;
  --lh-h1:1.14; --lh-h2:1.3; --lh-h3:1.36; --lh-code:1.75;
  --ls-h1:-.024em; --ls-h2:-.015em; --ls-h3:-.01em; --ls-ui:-.005em;

  /* ---- geometry ----
   * The column is the measure. At 15px Vazirmatn a 500px content width runs
   * about 75 characters, which is where a runbook stays comfortable. Two
   * things genuinely need more room than that and step out of it by --bleed
   * on a wide screen: the route fork, which has to hold two cards side by
   * side to read as a fork at all, and the screenshot. Code blocks stay in
   * the column and scroll, so that every caption and heading still lines up
   * with the block it belongs to.
   */
  --col:548px; --gutter:clamp(16px,5vw,24px);
  --gap-sec:clamp(34px,6vw,52px);
  --bleed:84px;
}
/* ---- Farsi ----
 * Vazirmatn is a Persian typeface first. Persian words carry more detail per
 * em than Latin (dots, hooks, the joined baseline), so the script wants a
 * fraction more size, noticeably more leading, and no negative tracking at
 * all: tightening a joined script pulls letters into each other.
 */
html[lang='fa']{
  --t-meta:12.5px; --t-sm:14px; --t-body:15.5px; --t-h3:16.5px; --t-h2:20.5px;
  --lh-body:1.85; --lh-sm:1.9; --lh-lead:1.9;
  --lh-h1:1.5; --lh-h2:1.55; --lh-h3:1.62;
  --ls-h1:normal; --ls-h2:normal; --ls-h3:normal; --ls-ui:normal;
}
/* The light set is written once. The inline script in each page stamps
   data-theme on <html> from the saved choice, or from the operating system
   when there is no saved choice. With scripting off the page stays dark,
   which is the wizard's own default. */
:root[data-theme='light']{
  color-scheme:light;
  /* The paper is a shade deeper than it was, so white cards read as raised
     instead of dissolving, and the borders are a step stronger so structure
     survives on a bright screen. */
  --bg:#f1f4f9; --panel:#ffffff; --card:#ffffff; --card2:#f7f9fc; --field:#f7f9fc;
  --bd:#dee4ee; --bd2:#ccd4e1;
  --tx:#0d1320; --tx2:#3d4a60; --mu:#5a6678;
  --ac:#0891b2; --ac2:#7c3aed; --ok:#047857; --dg:#b91c1c; --wn:#b45309;
  --ac-fill:#0e7490; --ac-fill-h:#0b6274; --ac-ink:#ffffff; --link:#0e7490;
  --ac-soft:rgba(8,145,178,.10); --ac-line:rgba(8,145,178,.40); --ac-deep:#0b5f73;
  --v-soft:rgba(124,58,237,.07);  --v-line:rgba(124,58,237,.26); --v-ink:#7c3aed;
  --ok-soft:rgba(4,120,87,.08);   --ok-line:rgba(4,120,87,.26);
  --dg-soft:rgba(185,28,28,.07);  --dg-line:rgba(185,28,28,.26);
  --ring:rgba(8,145,178,.28);
  --focus:#0b5f73;
  --shadow:0 1px 2px rgba(20,40,80,.05),0 10px 26px rgba(30,50,95,.09);
  --nav:rgba(241,244,249,.86);
  --mark:linear-gradient(80deg,#7c3aed 0%,#0891b2 100%);
  --code-bg:#e9eef6; --code-bd:#d5dde9; --inline-bg:#e9eef6;
  --img-shadow:0 10px 28px rgba(30,50,95,.14);
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;overflow-x:clip}
body{
  background:var(--bg);color:var(--tx);font-family:var(--font);
  font-size:var(--t-body);line-height:var(--lh-body);min-height:100vh;
  font-optical-sizing:auto;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
html[lang='fa'] body{font-family:var(--font-fa)}
a,button{touch-action:manipulation}
a{color:var(--link);text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}
button{font:inherit;color:inherit}
img{max-width:100%}
p{text-wrap:pretty}
/* A long host name or path inside a sentence must not push the page sideways
   on a 390px screen. Commands live in .term and .code, which scroll instead. */
p,dd,li,.note div,figcaption{overflow-wrap:break-word}

.skip{
  position:absolute;inset-inline-start:-9999px;top:8px;z-index:60;
  background:var(--card);border:1px solid var(--bd2);border-radius:var(--r-sm);
  padding:9px 14px;font-size:var(--t-sm);font-weight:600;color:var(--tx);
}
.skip:focus{inset-inline-start:12px;text-decoration:none}

/* ---- top bar, same geometry as the wizard ---- */
.bar{
  position:sticky;top:0;z-index:20;display:flex;align-items:center;
  justify-content:space-between;gap:14px;
  padding:11px clamp(16px,5vw,28px);
  padding-inline-start:max(clamp(16px,5vw,28px),env(safe-area-inset-left));
  padding-inline-end:max(clamp(16px,5vw,28px),env(safe-area-inset-right));
  background:var(--nav);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--bd);
}
.logo{
  display:flex;align-items:center;gap:9px;min-height:26px;
  font-size:var(--t-sm);font-weight:600;letter-spacing:var(--ls-h3);color:var(--tx);
}
.logo:hover{text-decoration:none}
.logo svg{width:22px;height:22px;display:block;flex:0 0 auto}
.controls{display:inline-flex;align-items:center;gap:8px}
.pill{
  display:inline-flex;align-items:center;justify-content:center;height:36px;padding:0 13px;
  border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--card);
  color:var(--tx2);font-size:var(--t-meta);font-weight:600;letter-spacing:var(--ls-ui);
  transition:color .13s var(--ease),border-color .13s var(--ease);
}
.pill:hover{color:var(--tx);border-color:var(--bd2);text-decoration:none}
.theme{
  display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:var(--r-sm);border:1px solid var(--bd);background:var(--card);
  color:var(--tx2);cursor:pointer;font-size:14px;line-height:1;
  transition:color .13s var(--ease),border-color .13s var(--ease);
}
.theme:hover{color:var(--tx);border-color:var(--bd2)}
.theme:active{transform:scale(.96)}

/* ---- page column ---- */
.wrap{
  max-width:var(--col);margin:0 auto;
  padding:clamp(30px,6vw,52px) var(--gutter) calc(56px + env(safe-area-inset-bottom));
  padding-inline-start:max(var(--gutter),env(safe-area-inset-left));
  padding-inline-end:max(var(--gutter),env(safe-area-inset-right));
}
section{margin-top:var(--gap-sec);scroll-margin-top:74px}
section>h2{
  font-size:var(--t-h2);font-weight:700;letter-spacing:var(--ls-h2);
  line-height:var(--lh-h2);margin:0 0 9px;
  padding-top:var(--gap-sec);border-top:1px solid var(--bd);
}
section:first-of-type>h2{border-top:0;padding-top:0}
section>h3{
  font-size:var(--t-h3);font-weight:600;letter-spacing:var(--ls-h3);
  line-height:var(--lh-h3);margin:30px 0 10px;color:var(--tx);
}
.lead{color:var(--tx2);margin:0 0 20px;line-height:var(--lh-lead)}
p{margin:0 0 14px}
p:last-child{margin-bottom:0}

/* ---- opening ---- */
.hero{padding-bottom:4px}
.eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  font-size:var(--t-meta);font-weight:600;color:var(--tx2);letter-spacing:var(--ls-ui);
  padding:4px 11px 4px 9px;border-radius:999px;
  border:1px solid var(--bd2);background:var(--card2);
}
.eyebrow::before{
  content:'';width:6px;height:6px;border-radius:50%;background:var(--ac);
  box-shadow:0 0 0 3px var(--ac-soft);flex:0 0 auto;
}
[dir='rtl'] .eyebrow{padding:4px 9px 4px 11px}
h1{
  font-size:var(--t-h1);font-weight:800;letter-spacing:var(--ls-h1);
  line-height:var(--lh-h1);margin:16px 0 12px;text-wrap:balance;
  overflow-wrap:anywhere;min-width:0;
}
.grad{background:var(--mark);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p{color:var(--tx2);margin:0;font-size:var(--t-h3);line-height:var(--lh-lead)}

.actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:24px}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:44px;padding:0 20px;border-radius:var(--r-sm);
  font-size:var(--t-sm);font-weight:600;letter-spacing:var(--ls-ui);
  background:var(--ac-fill);color:var(--ac-ink);border:1px solid transparent;
  cursor:pointer;white-space:nowrap;
  transition:background .13s var(--ease),transform .13s var(--ease),border-color .13s var(--ease),color .13s var(--ease);
}
.btn:hover{background:var(--ac-fill-h);text-decoration:none}
.btn:active{transform:scale(.985)}
.btn-ghost{background:var(--card2);border-color:var(--bd2);color:var(--tx)}
.btn-ghost:hover{background:var(--card2);border-color:var(--mu);color:var(--tx)}

/* ---- the fork: two routes, and only one of them is a door ----
 * The copy says most people should take the bot. So the bot card is the one
 * that is raised and has a link in it; the card you are already standing in
 * is recessed and marked, not decorated. A tint on the current card would
 * pull the eye to the route the page itself says is the harder one.
 */
.fork{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));gap:12px}
.route{
  display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--bd);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:18px;
}
.route h3{
  font-size:var(--t-h3);font-weight:600;letter-spacing:var(--ls-h3);
  line-height:var(--lh-h3);margin:0 0 7px;
}
.route p{color:var(--tx2);font-size:var(--t-sm);line-height:var(--lh-sm);margin:0 0 16px}
.route .go{
  margin-top:auto;align-self:flex-start;
  display:inline-flex;align-items:center;min-height:26px;
  font-size:var(--t-sm);font-weight:600;letter-spacing:var(--ls-ui);
}
.route.here{
  background:var(--card2);border-color:var(--bd);box-shadow:none;
  position:relative;overflow:hidden;
}
.route.here::before{
  content:'';position:absolute;inset-block:0;inset-inline-start:0;width:2px;
  background:var(--ac-line);
}
.route.here .go{color:var(--mu);font-weight:500;gap:7px}
.route.here .go::before{
  content:'';width:5px;height:5px;border-radius:50%;background:var(--ac);flex:0 0 auto;
}

/* ---- notes, same voice as the wizard ---- */
.note{
  display:flex;gap:11px;align-items:flex-start;
  padding:13px 15px;margin-top:18px;border-radius:var(--r-sm);
  font-size:var(--t-sm);line-height:var(--lh-sm);
  border:1px solid var(--bd);background:var(--card2);color:var(--tx2);
}
.note svg{width:16px;height:16px;flex:0 0 auto;margin-top:3px;color:var(--mu)}
.note b{color:var(--tx);font-weight:600}
.note p{margin:0 0 9px}
.note p:last-child{margin-bottom:0}
.note.iran{background:var(--v-soft);border-color:var(--v-line)}
.note.iran svg{color:var(--v-ink)}
.note.iran b{color:var(--v-ink)}

/* ---- the stage rail: the wizard's own step chips, laid out vertically ---- */
.rail{list-style:none;margin:0;padding:0}
.rail li{position:relative;display:flex;gap:15px;padding-bottom:22px}
.rail li:last-child{padding-bottom:0}
.rail li::before{
  content:'';position:absolute;top:32px;bottom:4px;width:1px;background:var(--bd2);
  inset-inline-start:13.5px;
}
.rail li:last-child::before{display:none}
.num{
  position:relative;z-index:1;flex:0 0 auto;
  width:28px;height:28px;border-radius:50%;margin-top:0;
  display:flex;align-items:center;justify-content:center;
  font-size:var(--t-meta);font-weight:600;line-height:1;
  font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1;
  letter-spacing:var(--ls-ui);
  background:var(--ac-soft);border:1px solid var(--ac-line);color:var(--ac-deep);
}
.rail h3{
  font-size:var(--t-h3);font-weight:600;margin:0 0 5px;
  letter-spacing:var(--ls-h3);line-height:var(--lh-h3);
}
.rail p{color:var(--tx2);font-size:var(--t-sm);line-height:var(--lh-sm);margin:0}
.rail .body{min-width:0;padding-top:3px}
html[lang='fa'] .rail .body{padding-top:1px}

/* ---- requirement rows ---- */
.reqs{margin:0;padding:0}
.reqs div{
  display:grid;grid-template-columns:minmax(0,1fr);gap:5px;
  padding:16px 0;border-top:1px solid var(--bd);
}
.reqs div:first-child{border-top:0;padding-top:0}
.reqs dt{font-weight:600;font-size:var(--t-body);color:var(--tx);line-height:var(--lh-h3);letter-spacing:var(--ls-h3)}
.reqs dd{margin:0;color:var(--tx2);font-size:var(--t-body);line-height:var(--lh-body)}

/* ---- code ----
 * The bordered surface is .code and the scrolling box is the <pre> inside it,
 * inset far enough that a long command scrolls BESIDE the copy button instead
 * of underneath it. Padding on a scrolling box does not reserve space at its
 * visible right edge, so the reservation has to live one level out.
 */
.code{
  position:relative;margin:0 0 14px;
  background:var(--code-bg);border:1px solid var(--code-bd);border-radius:var(--r-sm);
  padding:15px 16px;padding-right:52px;
}
.code pre{
  margin:0;padding:0;overflow-x:auto;overscroll-behavior-x:contain;
  background:none;border:0;
  font-family:var(--font-mono);font-size:var(--t-code);line-height:var(--lh-code);color:var(--tx);
  direction:ltr;text-align:left;
}
.code pre code{font:inherit;color:inherit;background:none;border:0;padding:0}

/* The one command someone actually types WRAPS instead of scrolling.
 *
 * It is 89 characters, which measured 700px in a 430px box, so scrolling it
 * meant a reader could land mid-URL and not see where their own command began.
 * A shell line broken across visual lines is still one line when copied, so
 * wrapping costs nothing and showing the whole thing is the point. The terminal
 * transcript and the build commands keep scrolling: those are output and
 * reference, not something to read start to finish. */
#cmd-run{white-space:pre-wrap;overflow-wrap:anywhere;overflow-x:visible}
.copy{
  /* the code itself is always LTR, so the button is pinned to the physical
     right on both the English and the Farsi page. */
  position:absolute;top:7px;right:7px;
  width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:7px;border:1px solid var(--code-bd);background:var(--card);
  color:var(--mu);cursor:pointer;
  transition:color .13s var(--ease),border-color .13s var(--ease);
}
.copy:hover{color:var(--tx);border-color:var(--mu)}
.copy:active{transform:scale(.94)}
.copy svg{width:15px;height:15px;pointer-events:none}
.copy[data-done='1']{color:var(--ok);border-color:var(--ok-line)}
.cap{font-size:var(--t-meta);font-weight:500;color:var(--mu);margin:0 0 9px}
code{
  /* Deliberately not link-coloured: on this page teal text means "this is a
     link you can follow", and `python3 --version` is not one. */
  font-family:var(--font-mono);font-size:.86em;
  background:var(--inline-bg);border:1px solid var(--code-bd);border-radius:5px;
  padding:1px 6px;color:var(--tx);unicode-bidi:isolate;
}
a code{color:inherit}
[dir='rtl'] :is(a,code,strong,kbd){unicode-bidi:isolate}

/* ---- transcript: real terminal output, no fake window chrome ---- */
.term{
  margin:0 0 14px;overflow-x:auto;overscroll-behavior-x:contain;
  background:var(--code-bg);border:1px solid var(--code-bd);border-radius:var(--r-sm);
  padding:15px 16px;font-family:var(--font-mono);font-size:var(--t-term);
  line-height:var(--lh-code);color:var(--tx2);direction:ltr;text-align:left;
}
.term b{color:var(--tx);font-weight:600}

/* A command that runs off the edge should say so. macOS hides overlay
   scrollbars until you scroll, so these two get a real one, and only when
   there is genuinely something to scroll to. */
.code pre,.term{scrollbar-width:thin;scrollbar-color:var(--bd2) transparent}
.code pre::-webkit-scrollbar,.term::-webkit-scrollbar{height:9px}
.code pre::-webkit-scrollbar-track,.term::-webkit-scrollbar-track{background:transparent}
.code pre::-webkit-scrollbar-thumb,.term::-webkit-scrollbar-thumb{
  background:var(--bd2);border-radius:99px;border:3px solid transparent;background-clip:content-box;
}
.code pre:hover::-webkit-scrollbar-thumb,.term:hover::-webkit-scrollbar-thumb{background:var(--mu);background-clip:content-box}

/* ---- screenshot ----
 * A thin mat and a real shadow, so it reads as a captured window sitting on
 * the page rather than a PNG pasted into a box.
 */
figure{
  margin:24px 0 0;padding:clamp(7px,1.6vw,11px);
  background:var(--card2);border:1px solid var(--bd);border-radius:var(--r-lg);
}
figure img{
  display:block;width:100%;height:auto;
  border:1px solid var(--bd2);border-radius:10px;box-shadow:var(--img-shadow);
}
figcaption{
  font-size:var(--t-meta);font-weight:500;color:var(--mu);
  margin-top:12px;line-height:var(--lh-sm);padding-inline:2px;
}

/* ---- lists ---- */
.plain{margin:0 0 14px;padding-inline-start:20px;color:var(--tx2)}
.plain li{margin-bottom:8px}
.plain li:last-child{margin-bottom:0}
.plain b{color:var(--tx);font-weight:600}
.plain::marker,.plain li::marker{color:var(--mu)}

/* ---- footer ---- */
.foot{margin-top:var(--gap-sec);padding-top:28px;border-top:1px solid var(--bd);text-align:center}
.social{display:flex;justify-content:center;gap:4px;flex-wrap:wrap;margin-bottom:14px}
.social a{
  display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;
  border-radius:var(--r-sm);color:var(--mu);
  transition:color .13s var(--ease),background .13s var(--ease);
}
.social a:hover{color:var(--tx);background:var(--card2);text-decoration:none}
.social svg{width:18px;height:18px}
.foot-line{font-size:var(--t-meta);font-weight:500;color:var(--mu);margin:0}
.foot-line+.foot-line{margin-top:12px}
.foot-line a{color:var(--mu)}
.foot-line a:hover{color:var(--tx)}

/* ---- toast, same as the wizard ---- */
.toast{
  position:fixed;bottom:calc(22px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
  background:var(--tx);color:var(--bg);padding:8px 18px;border-radius:var(--r-sm);
  font-size:var(--t-meta);font-weight:600;opacity:0;transition:opacity .25s var(--ease);
  pointer-events:none;z-index:50;
}
.toast.show{opacity:1}

/* The breakout is fluid, not a breakpoint: each side takes whatever margin
   the viewport is actually leaving beside the column, up to --bleed, and
   nothing when there is none. A fixed threshold left the two route cards
   stacked on an 800px screen that had room for both. The 24px subtracted is
   headroom for a classic scrollbar, which 100vw counts and the layout does not.
*/
.fork,figure{
  --step:clamp(0px,(100vw - var(--col)) / 2 - 24px,var(--bleed));
  margin-inline:calc(var(--step) * -1);
}

@media (max-width:560px){
  .route{padding:16px}
  .btn{width:100%}
  .code pre,.term{font-size:12.5px}
  .rail li{gap:13px}
}
@media (prefers-reduced-motion:reduce){
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .btn:active,.copy:active,.theme:active{transform:none}
}
