/* mehditmimi.com — the code playgrounds stage: the block that opens the Tools section, on the home page and on /tools/.
   One component for both pages (js/playgrounds-stage.js tells the stories). It brings its own tokens and type stacks,
   so it reads the same under css/home.css and under the tools' site-theme.css; like the TMIMI Explains card and the
   films, it is dark in both themes. Where Playfair, Inter and JetBrains Mono are not loaded (/tools/), it falls back to
   Georgia, the system face and the system monospace.

   The stage: a slow aurora in the tools scene's blues and violets, a faint dot grid, light that follows the pointer.
   Two glass windows float on it at slightly different depths and lean a few degrees toward the pointer. Each is a
   miniature of its playground drawn in HTML and CSS (decorative: aria-hidden), with a thin rim in the brand wire, and
   each tells its tool's story once when it scrolls into view, then rests on its last frame:
   - the HTML CSS JS Playground: HTML types in and the heading appears as it is typed; CSS pads the page, colours the
     heading (a sweep of light) and rounds the button; then a click handler, and the button answers a click with a
     ring of dots. That code, pasted into the playground, does exactly this;
   - the Node.js Playground: an Express server types in; Run; "Server ready on port 3000"; the playground's own preview
     asks GET /todos along a thread to the route's line, the console logs it, 200 OK comes back, the JSON appears.
   The two playgrounds never talk to each other: nothing travels between the windows.

   Every size inside a window is a share of its width (cqi), so a window scales as one picture, and the Node window's
   thread (an SVG on the same 1000 × 625 grid) always lands on the route's line.

   States (data-state on each window): none (no script) and "done" are the last frame; "play" is the story, which
   starts from an empty editor and adds .is-on to what has appeared. When motion is on, the page starts from the empty
   frame even before the script runs, so the last frame never flashes first.
   Motion follows the header's switch (data-motion) or, on a page without one, prefers-reduced-motion. Off: the last
   frame, still, and the ambient loops (the aurora, the rim's glint) freeze. Nothing moves while the stage is off
   screen (.is-off). */

/* ---------- Tokens ---------- */
.pgs {
  --pgs-ink: #ecebf3;
  --pgs-ink-2: #c3c3d1;
  --pgs-kicker: #9a9aad;
  --pgs-focus: #c9c6ff;
  --pgs-wire: linear-gradient(90deg, #ff3d8b 0%, #7a5cff 55%, #2f7dff 100%);
  --pgs-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --pgs-text: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --pgs-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --pgs-ease: cubic-bezier(.2, .7, .2, 1);
  --pgs-ease-io: cubic-bezier(.65, 0, .35, 1);
  /* How the dark panel sits on the page: a soft drop on a light page, a hairline and a violet breath on a dark one. */
  --pgs-border: #262939;
  --pgs-drop: 0 1px 2px rgba(15, 16, 23, .22), 0 46px 90px -52px rgba(15, 16, 23, .95);
  /* The pointer, from -.5 to .5 across the stage (the script); 0 is the resting composition. */
  --px: 0;
  --py: 0;
}
:root[data-theme="dark"] .pgs {
  --pgs-border: #2c2f42;
  --pgs-drop: 0 40px 90px -50px rgba(0, 0, 0, .9), 0 0 110px -60px rgba(122, 92, 255, .5);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .pgs {
    --pgs-border: #2c2f42;
    --pgs-drop: 0 40px 90px -50px rgba(0, 0, 0, .9), 0 0 110px -60px rgba(122, 92, 255, .5);
  }
}

/* ---------- The stage ---------- */
.pgs, .pgs *, .pgs *::before, .pgs *::after { box-sizing: border-box; }
.pgs {
  position: relative; isolation: isolate; overflow: hidden;
  /* The headline follows the stage's own width (it is narrower on /tools/ than on the home page). */
  container: pgs / inline-size;
  margin: 0 0 clamp(44px, 3vw + 24px, 72px);
  padding: clamp(24px, 2.6vw + 10px, 56px);
  border-radius: 28px;
  background: #0f1017;
  border: 1px solid var(--pgs-border);
  box-shadow: var(--pgs-drop);
  color: var(--pgs-ink);
  font: 400 1rem/1.6 var(--pgs-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.pgs__art { position: absolute; inset: 0; z-index: -1; overflow: hidden; border-radius: inherit; pointer-events: none; }
/* The aurora: three soft lights that drift (transforms only, so the compositor carries them). */
.pgs__glow {
  position: absolute; aspect-ratio: 1; border-radius: 50%;
  animation: 46s var(--pgs-ease-io) infinite alternate paused;
  will-change: transform;
}
.pgs__glow--1 { width: 72%; left: -20%; top: -34%; background: radial-gradient(closest-side, rgba(122, 92, 255, .3), rgba(122, 92, 255, .08) 55%, transparent 74%); animation-name: pgs-drift-1; }
.pgs__glow--2 { width: 66%; right: -18%; bottom: -30%; background: radial-gradient(closest-side, rgba(47, 125, 255, .28), rgba(47, 125, 255, .07) 55%, transparent 74%); animation-name: pgs-drift-2; animation-duration: 54s; }
.pgs__glow--3 { width: 44%; left: 30%; top: 26%; background: radial-gradient(closest-side, rgba(56, 152, 236, .13), transparent 72%); animation-name: pgs-drift-3; animation-duration: 40s; }
@keyframes pgs-drift-1 { to { transform: translate3d(14%, 10%, 0) scale(1.1); } }
@keyframes pgs-drift-2 { to { transform: translate3d(-12%, -8%, 0) scale(.92); } }
@keyframes pgs-drift-3 { to { transform: translate3d(-18%, 12%, 0) scale(1.18); } }
.pgs__grid {
  position: absolute; inset: 0;
  background: radial-gradient(rgba(255, 255, 255, .085) 1px, transparent 1.5px) 0 0 / 24px 24px;
  -webkit-mask-image: radial-gradient(115% 85% at 50% 42%, #000 18%, transparent 82%);
  mask-image: radial-gradient(115% 85% at 50% 42%, #000 18%, transparent 82%);
}
/* Light that follows the pointer (the script moves it; a mouse only). */
.pgs__light {
  position: absolute; left: 0; top: 0; width: 760px; height: 760px; margin: -380px 0 0 -380px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(168, 163, 255, .15), rgba(122, 92, 255, .05) 55%, transparent 74%);
  opacity: 0; transform: translate3d(var(--lx, 0px), var(--ly, 0px), 0);
  transition: opacity .7s ease;
}
.pgs.is-lit .pgs__light { opacity: 1; }

/* ---------- Headline ---------- */
.pgs__head {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); align-items: end;
  column-gap: clamp(28px, 5vw, 80px);
  margin: 0 0 clamp(30px, 2.6vw + 12px, 52px);
}
.pgs__kicker {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 0 0 16px;
  font: 600 .75rem/1 var(--pgs-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--pgs-kicker);
}
.pgs__badge {
  padding: 6px 10px 5px; border-radius: 999px; letter-spacing: .12em; color: #fff;
  background: linear-gradient(90deg, #d6246e, #5b3fe0 55%, #1d5fd6);
}
.pgs__title {
  grid-column: 1; margin: 0 0 10px;
  font: 600 clamp(2.1rem, 1.35rem + 2.5vw, 3.3rem)/1.04 var(--pgs-display);
  letter-spacing: -.016em; color: var(--pgs-ink); font-variant-numeric: lining-nums;
}
.pgs__title em {
  font-style: italic; padding-right: .08em;
  background: linear-gradient(90deg, #ff6aa9, #b04dff 38%, #8f7bff 60%, #6ea8ff);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.pgs__tagline { grid-column: 1; margin: 0; font: italic 500 clamp(1.1rem, 1rem + .4vw, 1.32rem)/1.4 var(--pgs-display); color: var(--pgs-ink); }
.pgs__lede { grid-column: 2; grid-row: 2 / span 2; align-self: end; margin: 0; max-width: 42ch; color: var(--pgs-ink-2); font-size: 1rem; line-height: 1.6; }

/* ---------- The two tools ---------- */
.pgs__tools {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(40px, 3vw + 20px, 64px) clamp(28px, 4vw, 64px);
  margin: 0; padding: 0; list-style: none;
}
/* Depth: the web window a little nearer and turned toward the middle, the Node window a little further and higher. */
.pgs-tool { position: relative; display: flex; flex-direction: column; min-width: 0; --z: 22px; --ry: 3deg; --lift: 0px; --hz: 0px; }
.pgs-tool--node { --z: -22px; --ry: -3deg; --lift: -12px; }

/* The window: a glass pane that leans toward the pointer. The lean is a CSS transition, so it eases on its own. */
.pgs-win {
  position: relative; z-index: 1;
  container: pgs-win / inline-size;
  aspect-ratio: 16 / 10;
  margin: 0 0 clamp(22px, 1.4vw + 14px, 32px);
  border-radius: 16px;
  transform: perspective(1600px) translate3d(0, var(--lift), calc(var(--z) + var(--hz)))
             rotateX(calc(var(--py) * -6deg)) rotateY(calc(var(--ry) + var(--px) * 8deg));
  transition: transform 1.2s var(--pgs-ease);
}
.pgs-win__glass {
  position: absolute; inset: 0; overflow: hidden; border-radius: inherit;
  display: grid; grid-template-rows: 6.2cqi minmax(0, 1fr) 4.2cqi;
  background: linear-gradient(180deg, rgba(27, 29, 44, .95), rgba(15, 16, 25, .97));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 44px 80px -40px rgba(0, 0, 0, .95), 0 0 80px -30px rgba(122, 92, 255, .55);
  /* Type sizes, as shares of the window's width; a small window gets larger ones (the container query below). */
  --fs-code: 2.05cqi; --fs-ui: 1.55cqi; --fs-small: 1.4cqi; --fs-json: 1.8cqi; --fs-con: 1.7cqi;
  font: 400 var(--fs-code)/1 var(--pgs-mono);
  /* No ligatures: the playgrounds' editor (Monaco) shows => as two characters. */
  font-variant-ligatures: none; font-feature-settings: "calt" 0, "liga" 0;
  color: #dcdbe8; text-align: left; white-space: nowrap;
}
.pgs-tool--node .pgs-win__glass { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 34px 64px -36px rgba(0, 0, 0, .9), 0 0 70px -30px rgba(47, 125, 255, .5); }
/* The rim: 1 px of the brand wire, and a glint that goes round it very slowly. */
.pgs-win__rim {
  position: absolute; inset: 0; z-index: 2; overflow: hidden; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(135deg, rgba(255, 61, 139, .85), rgba(122, 92, 255, .7) 48%, rgba(47, 125, 255, .85));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.pgs-win__glint {
  position: absolute; left: 50%; top: 50%; width: 160%; aspect-ratio: 1; margin: -80% 0 0 -80%;
  background: conic-gradient(from 0deg, transparent 0 292deg, rgba(255, 255, 255, .95) 330deg, transparent 360deg);
  opacity: .8;
  animation: pgs-spin 18s linear infinite paused;
  will-change: transform;
}
@keyframes pgs-spin { to { transform: rotate(1turn); } }

/* The ambient loops run only with motion on, and only while the stage is on screen. */
:root[data-motion="on"] .pgs__glow, :root[data-motion="on"] .pgs-win__glint { animation-play-state: running; }
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion]) .pgs__glow, :root:not([data-motion]) .pgs-win__glint { animation-play-state: running; }
}
.pgs.is-off .pgs__glow, .pgs.is-off .pgs-win__glint { animation-play-state: paused; }

/* ---------- Inside a window ---------- */
.pgs-bar {
  display: flex; align-items: center; gap: 1.6cqi; min-width: 0; padding: 0 2cqi;
  border-bottom: 1px solid rgba(255, 255, 255, .07); background: rgba(255, 255, 255, .025);
  font: 600 var(--fs-ui)/1 var(--pgs-text); color: #b9bbce;
}
.pgs-bar__dots { display: flex; gap: .8cqi; }
.pgs-bar__dots i { width: 1.2cqi; height: 1.2cqi; border-radius: 50%; background: #ff3d8b; }
.pgs-bar__dots i:nth-child(2) { background: #7a5cff; }
.pgs-bar__dots i:nth-child(3) { background: #2f7dff; }
.pgs-bar__app {
  font: 600 1.95cqi/1.2 var(--pgs-display); letter-spacing: -.005em;
  background: linear-gradient(90deg, #ff8fc0, #b9a6ff 55%, #8fbaff); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pgs-bar__run {
  margin-left: auto; display: inline-flex; align-items: center; gap: .8cqi; height: 3.6cqi; padding: 0 1.7cqi 0 1.4cqi;
  border-radius: 99px; background: linear-gradient(90deg, #5b3fe0, #7c3aed); color: #fff;
}
.pgs-bar__run::before { content: ""; width: 1.05cqi; height: 1.25cqi; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.pgs-bar__auto { display: inline-flex; align-items: center; gap: .8cqi; }
.pgs-bar__auto::before {
  content: ""; width: 3.2cqi; height: 1.8cqi; border-radius: 99px;
  background: radial-gradient(circle at 72% 50%, #fff 0 .62cqi, transparent .72cqi) #7a5cff;
}

.pgs-split { display: grid; grid-template-columns: 56cqi minmax(0, 1fr); min-height: 0; }
.pgs-win--node .pgs-split { grid-template-columns: 57cqi minmax(0, 1fr); }
.pgs-col { display: grid; grid-template-rows: 32cqi minmax(0, 1fr); min-width: 0; border-left: 1px solid rgba(255, 255, 255, .07); }
.pgs-win--node .pgs-col { grid-template-rows: 29.4cqi minmax(0, 1fr); }
.pgs-status {
  display: flex; align-items: center; gap: 1.6cqi; padding: 0 2cqi;
  border-top: 1px solid rgba(255, 255, 255, .06); background: rgba(255, 255, 255, .02);
  font: 500 var(--fs-small)/1 var(--pgs-text); color: #9ea2b8;
}
.pgs-status__ok::before { content: ""; display: inline-block; width: 1.1cqi; height: .6cqi; margin-right: .8cqi; border: solid #5fd3a0; border-width: 0 0 .25cqi .25cqi; transform: translateY(-.25cqi) rotate(-45deg); }
.pgs-status__srv::before { content: ""; display: inline-block; width: 1cqi; height: 1cqi; margin-right: .8cqi; border-radius: 50%; background: #5fd3a0; box-shadow: 0 0 1cqi rgba(95, 211, 160, .8); }

/* The editor */
.pgs-ed { position: relative; min-width: 0; background: rgba(6, 7, 12, .32); }
.pgs-tabs { display: flex; height: 5.2cqi; border-bottom: 1px solid rgba(255, 255, 255, .06); font: 500 var(--fs-ui)/1 var(--pgs-text); }
.pgs-tab {
  position: relative; display: flex; align-items: center; gap: .8cqi; padding: 0 1.8cqi;
  border-right: 1px solid rgba(255, 255, 255, .05); color: #8f93a8;
}
.pgs-tab::before { content: ""; width: 1.1cqi; height: 1.1cqi; border-radius: .25cqi; background: #f7df1e; }
.pgs-tab[data-for="html"]::before { background: #e44d26; }
.pgs-tab[data-for="css"]::before { background: #2f7dff; }
.pgs-tab::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--pgs-wire); transform: scaleX(0); transform-origin: 0 50%;
}
.pgs-tab.is-cur,
.pgs-ed[data-file="html"] .pgs-tab[data-for="html"],
.pgs-ed[data-file="css"] .pgs-tab[data-for="css"],
.pgs-ed[data-file="js"] .pgs-tab[data-for="js"] { color: #ecebf3; background: rgba(255, 255, 255, .04); }
.pgs-tab.is-cur::after,
.pgs-ed[data-file="html"] .pgs-tab[data-for="html"]::after,
.pgs-ed[data-file="css"] .pgs-tab[data-for="css"]::after,
.pgs-ed[data-file="js"] .pgs-tab[data-for="js"]::after { transform: scaleX(1); }
.pgs-code { position: absolute; inset: 5.2cqi 0 0 0; padding-top: 1.4cqi; }
.pgs-code[data-file] { visibility: hidden; }
.pgs-ed[data-file="html"] .pgs-code[data-file="html"],
.pgs-ed[data-file="css"] .pgs-code[data-file="css"],
.pgs-ed[data-file="js"] .pgs-code[data-file="js"] { visibility: visible; }
.pgs-ln { position: relative; isolation: isolate; display: flex; height: 3.55cqi; line-height: 3.55cqi; white-space: pre; }
.pgs-ln > i { flex: none; width: 5.2cqi; padding-right: 1.5cqi; text-align: right; font-style: normal; font-size: .9em; color: #8a8fa8; }
.pgs-ln__t { display: inline-block; }
/* Syntax colours (all above 5:1 on the glass). */
.k-p { color: #8f95ad; }   /* punctuation, tag brackets */
.k-t { color: #ff8fbf; }   /* tags, selectors */
.k-a { color: #7dd3fc; }   /* properties, keys */
.k-s { color: #8ee6b8; }   /* strings */
.k-n { color: #f5b97f; }   /* numbers, colours */
.k-k { color: #c4b5fd; }   /* keywords, => */
.k-f { color: #93c5fd; }   /* functions */
/* The caret (the story moves it; ch is the code font's advance). */
.pgs-caret {
  position: absolute; left: 5.2cqi; top: 6.6cqi; width: max(1.5px, .24cqi); height: 3.55cqi;
  background: #c9c6ff; border-radius: 1px; opacity: 0;
  transform: translate3d(calc(var(--cx, 0) * 1ch), calc(var(--cy, 0) * 3.55cqi), 0);
}
/* The route that answers: lit when the request reaches it, and it keeps a soft light. */
.pgs-ln--route::before, .pgs-ln--route::after {
  content: ""; position: absolute; z-index: -1; inset: 0 0 0 4.4cqi; border-radius: .4cqi 0 0 .4cqi;
}
.pgs-ln--route::before {
  background: linear-gradient(90deg, rgba(122, 92, 255, .26), rgba(122, 92, 255, .08) 72%, transparent);
  box-shadow: inset .35cqi 0 0 #a08bff;
  opacity: var(--hit, .85);
}
/* The flash when the request arrives. */
.pgs-ln--route::after {
  background: linear-gradient(90deg, rgba(201, 198, 255, .42), rgba(122, 92, 255, .12) 60%, transparent);
  opacity: var(--flash, 0);
}

/* Panes on the right: preview, console */
.pgs-pv { display: grid; grid-template-rows: 5.2cqi minmax(0, 1fr); min-height: 0; }
.pgs-pane-head {
  display: flex; align-items: center; gap: 1cqi; padding: 0 1.8cqi; min-width: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .06);
  font: 500 var(--fs-ui)/1 var(--pgs-text); color: #a8abc0;
}
.pgs-pane-head__eye { flex: none; width: 1.9cqi; height: 1.2cqi; border: .22cqi solid currentColor; border-radius: 50% / 60%; background: radial-gradient(circle, currentColor 0 .3cqi, transparent .38cqi); }
.pgs-con { display: grid; grid-template-rows: 4.6cqi minmax(0, 1fr); min-height: 0; border-top: 1px solid rgba(255, 255, 255, .07); background: rgba(6, 7, 12, .28); }
.pgs-con .pgs-pane-head { gap: 0; padding: 0 .6cqi; font-size: var(--fs-small); }
.pgs-con .pgs-pane-head span { position: relative; display: flex; align-items: center; height: 100%; padding: 0 1.2cqi; }
.pgs-con .pgs-pane-head span:first-child { color: #ecebf3; }
.pgs-con .pgs-pane-head span:first-child::after { content: ""; position: absolute; left: 1.2cqi; right: 1.2cqi; bottom: -1px; height: 2px; background: var(--pgs-wire); }
.pgs-con__lines { padding: 1.3cqi 1.8cqi; font: 400 var(--fs-con)/3.2cqi var(--pgs-mono); }
.pgs-con__lines > span { display: block; }
.pgs-con__hint { color: #9ea2b8; font-family: var(--pgs-text); }
.pgs-con__cmd { color: #ecebf3; font-weight: 600; }
.pgs-con__cmd::before { content: ""; display: inline-block; width: 1cqi; height: 1.2cqi; margin-right: 1cqi; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.pgs-con__ok { color: #5fd3a0; }

/* The web preview: the page itself, as the browser draws it with no styles, then with the CSS. */
.pgs-page {
  position: relative; overflow: hidden;
  background: #fbfaf7; color: #000;
  font: 400 2.6cqi/1.15 'Times New Roman', Times, serif;
}
.pgs-page__in { position: absolute; left: 0; top: 0; transform: translate(1em, 1em); }
.pgs-page__h1 { position: relative; display: block; min-height: 1.15em; font-size: 2em; font-weight: 700; line-height: 1.15; color: #d6246e; }
.pgs-page__b { position: relative; display: inline-block; vertical-align: top; }
/* A default button under the playground's reset (no padding): the label sits close to its ends. Its box does not
   depend on its label (top-aligned, one line high even while empty), so typing the label never moves it. */
.pgs-page__btn {
  display: inline-block; vertical-align: top; min-height: calc(1.33em + 2px);
  padding: .04em .2em; border: 1px solid #767676; border-radius: 1em;
  background: #efefef; color: #000;
  font: 400 .8333em/1.25 Arial, 'Helvetica Neue', Helvetica, sans-serif;
}
.pgs-cursor {
  position: absolute; z-index: 2; left: 50%; top: 50%; width: 1.05em; height: 1.4em; margin: -.1em 0 0 -.1em;
  filter: drop-shadow(0 .08em .12em rgba(0, 0, 0, .35));
  transform-origin: .1em .1em; transform: translate(.8em, .55em);
}
.pgs-cursor svg { display: block; width: 100%; height: 100%; }

/* The Node preview: the address, then the JSON the server answers (Chrome pretty-prints it). */
.pgs-addr {
  flex: 1; min-width: 0; height: 2.9cqi; display: flex; align-items: center; padding: 0 1.2cqi; overflow: hidden;
  border-radius: 99px; background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .09);
  font: 400 var(--fs-small)/1 var(--pgs-mono); color: #c3c3d1;
}
.pgs-addr__path { color: #ecebf3; }
.pgs-pv__body { position: relative; min-height: 0; }
.pgs-json { position: absolute; left: 6.4cqi; top: 1.4cqi; font: 400 var(--fs-json)/3.1cqi var(--pgs-mono); color: #dcdbe8; }
.pgs-json > span { display: block; white-space: pre; }
.pgs-pv__empty {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 1.2cqi;
  font: 500 var(--fs-small)/1.3 var(--pgs-text); color: #9ea2b8; opacity: 0;
}
.pgs-pv__empty::before { content: ""; width: 3.2cqi; height: 2cqi; border: .3cqi solid #8a8fa8; border-radius: 50% / 60%; background: radial-gradient(circle, #8a8fa8 0 .5cqi, transparent .6cqi); }

/* The thread, from the preview to the route, and the two pulses that travel it. */
.pgs-thread { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.pgs-thread path { fill: none; stroke-linecap: round; stroke-dasharray: 1 1; stroke-dashoffset: 0; }
.pgs-thread__glow { stroke: rgba(122, 92, 255, .2); stroke-width: 9; }
.pgs-thread__line { stroke-width: 2.4; opacity: .75; }
.pgs-pkt {
  position: absolute; left: 0; top: 0; z-index: 3;
  display: inline-flex; align-items: center; gap: .8cqi;
  margin: calc(-1.3cqi - 1px) 0 0 calc(-1.3cqi - 1px);
  padding: .5cqi 1.1cqi .5cqi .7cqi; border-radius: 1.3cqi;
  background: #12141d; border: 1px solid #30344a;
  font: 600 var(--fs-con)/1.1 var(--pgs-mono); color: #7dd3fc;
  opacity: 0; transform: translate3d(0, 0, 0);
}
.pgs-pkt::before { content: ""; width: 1.2cqi; height: 1.2cqi; border-radius: 50%; background: currentColor; box-shadow: 0 0 1.4cqi .2cqi currentColor; }
.pgs-pkt--back { color: #5fd3a0; }

/* ---------- The story: an empty editor that fills (data-state="play") ----------
   Everything that moves inside a window is drawn by the script, frame by frame, while the story plays: a CSS
   transition or animation in here would get its own compositor layer, and inside the window's perspective such a
   layer is rasterised at low resolution (blurred text on a phone). The story also pauses cleanly this way. */
.pgs-win[data-state="play"] .pgs-ln__t { clip-path: inset(-.6em max(0px, 100% - var(--n, 0) * 1ch) -.6em 0); }
.pgs-win[data-state="play"] .pgs-ln:not(.is-on) > i { opacity: 0; }
.pgs-win[data-state="play"] .pgs-caret.is-on { opacity: 1; }
.pgs-win[data-state="play"] .pgs-s:not(.is-on) { opacity: 0; }
.pgs-win[data-state="play"] .pgs-x:not(.is-gone) { opacity: 1; }
.pgs-win[data-state="play"] .pgs-ln--route:not(.is-hit) { --hit: 0; }
/* Not drawn yet: hidden outright (a round cap would still paint a dot where the dash ends). */
.pgs-win[data-state="play"] .pgs-thread:not(.is-on) { visibility: hidden; }
.pgs-win[data-state="play"] .pgs-thread:not(.is-on) path { stroke-dashoffset: 1; }
/* The web page before its CSS: no padding, a black heading, a square button. */
.pgs-win[data-state="play"] .pgs-page__in:not(.is-pad) { transform: none; }
.pgs-win[data-state="play"] .pgs-page__h1:not(.is-lit) { color: #000; }
.pgs-page__h1.is-lit {
  background: linear-gradient(100deg, #d6246e 0 40%, #ff5f9e 45.5%, #ffd3e6 49%, #ff5f9e 52.5%, #000 58% 100%) no-repeat;
  background-size: 300% 100%; background-position: var(--sweep, 100%) 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pgs-page__h1.is-lit::after {
  content: ""; position: absolute; top: -.35em; bottom: -.35em; left: 0; width: 1.6em;
  background: radial-gradient(closest-side, rgba(255, 95, 158, .38), transparent);
  transform: translateX(var(--glint, -2em)); opacity: var(--glint-o, 0);
}
.pgs-win[data-state="play"] .pgs-page__btn:not(.is-round) { border-radius: 2px; }
.pgs-win[data-state="play"] .pgs-cursor:not(.is-on) { opacity: 0; }

/* Before the script runs, a page that will play the story shows the empty frame already. Should the script never
   come, the last frame shows after 4 s (a one-off, delayed, zero-length animation). */
:root.js[data-motion="on"] .pgs-win:not([data-state]) :is(.pgs-ln__t, .pgs-ln > i, .pgs-page__in, .pgs-cursor, .pgs-s, .pgs-thread, .pgs-addr__path) { visibility: hidden; animation: pgs-unhide 0s 4s forwards; }
@media (prefers-reduced-motion: no-preference) {
  :root.js:not([data-motion]) .pgs-win:not([data-state]) :is(.pgs-ln__t, .pgs-ln > i, .pgs-page__in, .pgs-cursor, .pgs-s, .pgs-thread, .pgs-addr__path) { visibility: hidden; animation: pgs-unhide 0s 4s forwards; }
}
@keyframes pgs-unhide { to { visibility: visible; } }

/* ---------- Beneath each window: the name, the promise, the features, the way in ---------- */
.pgs-tool__text { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; flex: 1; padding: 0 4px; }
.pgs-tool__name { margin: 0; font: 600 clamp(1.4rem, 1.22rem + .55vw, 1.7rem)/1.18 var(--pgs-display); letter-spacing: -.008em; font-variant-numeric: lining-nums; }
/* The name's link covers the tool, window included: one target, one tab stop, named by the tool. */
.pgs-tool__link { color: var(--pgs-ink); text-decoration: none; }
.pgs-tool__link:hover { color: #fff; }
.pgs-tool__link::after { content: ""; position: absolute; inset: -10px; z-index: 4; border-radius: 22px; }
.pgs-tool__link:focus-visible { outline: none; }
.pgs-tool__link:focus-visible::after { outline: 2px solid var(--pgs-focus); outline-offset: 2px; }
.pgs-tool__promise { margin: 0; max-width: 46ch; color: var(--pgs-ink-2); font-size: 1rem; line-height: 1.55; }
.pgs-tool__tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 10px; padding: 0; list-style: none; }
.pgs-tool__tags li {
  padding: 5px 11px; border-radius: 999px;
  border: 1px solid rgba(168, 163, 255, .26); background: rgba(168, 163, 255, .07);
  color: #cfccff; font: 500 .76rem/1.3 var(--pgs-mono);
}
/* The button: a pill with a gradient-wire border that glows when the tool is hovered or focused. */
.pgs-tool__cta {
  position: relative; isolation: isolate; margin-top: auto;
  display: inline-flex; align-items: center; gap: 10px; min-height: 46px; padding: 0 22px; border-radius: 999px;
  background: rgba(18, 20, 31, .85); color: var(--pgs-ink); font: 600 .95rem/1 var(--pgs-text);
  box-shadow: 0 12px 30px -18px rgba(122, 92, 255, .9);
  transition: box-shadow .35s ease, background-color .35s ease, color .35s ease;
}
.pgs-tool__cta::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; padding: 1.5px;
  background: var(--pgs-wire);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.pgs-tool__cta::after {
  content: ""; position: absolute; inset: -2px; z-index: -2; border-radius: inherit;
  background: var(--pgs-wire); filter: blur(12px); opacity: 0; transition: opacity .4s ease;
}
.pgs-tool__cta svg { width: 17px; height: 17px; flex: none; transition: transform .35s var(--pgs-ease); }
.pgs-tool:hover .pgs-tool__cta, .pgs-tool:focus-within .pgs-tool__cta { color: #fff; background: rgba(27, 29, 46, .95); box-shadow: 0 16px 36px -16px rgba(122, 92, 255, 1); }
.pgs-tool:hover .pgs-tool__cta::after, .pgs-tool:focus-within .pgs-tool__cta::after { opacity: .6; }
.pgs-tool:hover .pgs-tool__cta svg, .pgs-tool:focus-within .pgs-tool__cta svg { transform: translateX(4px); }
/* The window comes a little closer when its tool is hovered (motion on). */
:root[data-motion="on"] .pgs-tool:hover { --hz: 26px; }
@media (prefers-reduced-motion: no-preference) { :root:not([data-motion]) .pgs-tool:hover { --hz: 26px; } }

/* ---------- Motion off: the last frame, at rest ---------- */
:root[data-motion="off"] .pgs-win { transform: perspective(1600px) translate3d(0, var(--lift), var(--z)) rotateY(var(--ry)); transition: none; }
:root[data-motion="off"] .pgs__light { display: none; }
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion]) .pgs-win { transform: perspective(1600px) translate3d(0, var(--lift), var(--z)) rotateY(var(--ry)); transition: none; }
  :root:not([data-motion]) .pgs__light { display: none; }
  :root:not([data-motion]) .pgs-tool__cta, :root:not([data-motion]) .pgs-tool__cta svg { transition: none; }
}

/* ---------- Responsive ---------- */
/* Small windows: the text keeps a readable size and the gutters give it the room. */
@container pgs-win (max-width: 460px) {
  .pgs-win__glass { --fs-code: 2.3cqi; --fs-ui: 1.85cqi; --fs-small: 1.7cqi; --fs-json: 2.1cqi; --fs-con: 2cqi; }
  .pgs-ln > i { width: 4.4cqi; padding-right: 1.2cqi; }
  .pgs-caret { left: 4.4cqi; }
  .pgs-ln--route::before, .pgs-ln--route::after { left: 3.8cqi; }
  .pgs-bar__auto { font-size: 0; gap: 0; }
}
@container pgs (max-width: 920px) {
  .pgs__head { grid-template-columns: minmax(0, 1fr); }
  .pgs__lede { grid-column: 1; grid-row: auto; margin-top: 16px; }
}
@media (max-width: 899px) {
  /* One tool above the other, each window at a size where its code stays legible. */
  .pgs__tools { grid-template-columns: minmax(0, 1fr); max-width: 640px; margin-inline: auto; }
  .pgs-tool { --z: 0px; --lift: 0px; --ry: 2.5deg; }
  .pgs-tool--node { --ry: -2.5deg; }
}
@media (max-width: 639px) {
  .pgs { padding: 26px 16px 30px; border-radius: 24px; }
  .pgs-win { border-radius: 12px; }
  .pgs-tool { --ry: 1.5deg; }
  .pgs-tool--node { --ry: -1.5deg; }
  .pgs-tool__text { padding: 0 2px; }
}

/* ---------- Print and forced colours ---------- */
@media print {
  .pgs { box-shadow: none; }
  .pgs__art, .pgs-win__rim, .pgs-thread, .pgs-pkt { display: none; }
  .pgs-win { transform: none; }
}
@media (forced-colors: active) {
  .pgs { border: 1px solid CanvasText; }
  .pgs__art, .pgs-win__rim, .pgs-tool__cta::after { display: none; }
  .pgs__title em, .pgs-bar__app { background: none; color: CanvasText; -webkit-text-fill-color: CanvasText; }
  .pgs-win__glass { border: 1px solid CanvasText; }
  .pgs-tool__cta { border: 1px solid ButtonText; }
  .pgs-tool__cta::before { display: none; }
  .pgs-tool__link:focus-visible::after { outline: 3px solid Highlight; }
}
