/* join-live.css: the parts of /join that build themselves (docs/join-redesign/spec.md 4, 5.5, 9).
   The device and the ticket (join-preview.js), the rail and the building mark (join-build.js), the build
   log, the QR hang tag and the stamp. Only transform, opacity, clip-path, stroke-dashoffset and the
   registered --cut ever animate; nothing moves over the film; every element's finished state is plain
   CSS, so a script that fails still shows a finished drawing. One reduced-motion block, at the end.

   Ink on the dark device (--dark-1, navy): --on-enc 15.31:1, --accent-bright 7.04:1, the
   soft line (on-enc at .66) 7.2:1. The device's words are decoration (aria-hidden): the screen reader
   hears #jnPreviewSr instead. */

@property --cut { syntax: '<percentage>'; inherits: false; initial-value: 100%; }
@property --t { syntax: '<number>'; inherits: false; initial-value: 0; }

/* ---------------------------------------------------------------- the rail */
.jn-rail { display: flex; align-items: center; gap: 12px; }
.jn-rail-track { position: relative; flex: 1; min-width: 0; height: 40px; }
.jn-rail-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.jn-rail-svg path { fill: none; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.jn-travel { stroke: var(--tx3); stroke-width: 1.5; stroke-dasharray: 2 5; opacity: .5; }
.jn-purge { stroke: var(--pri); stroke-width: 3; }
.jn-bead { stroke: var(--pri); stroke-width: 3; opacity: 0; }
.jn-bead.is-on { opacity: 1; filter: drop-shadow(0 1.5px 0 rgba(var(--accent-rgb), .45)); }
.jn-node { position: absolute; top: 50%; inset-inline-start: calc(var(--t) * 100%); width: 12px; height: 12px; margin: -6px; margin-inline-start: -6px;
  border-radius: 50%; background: var(--card); border: 2px solid var(--tx3); box-sizing: border-box; }
.jn-node.is-done { background: var(--pri); border-color: var(--pri); box-shadow: 0 0 0 2px var(--card); }
.jn-node.is-now { border-color: var(--pri); box-shadow: 0 0 0 6px rgba(var(--accent-rgb), .16); }
.jn-node-l { display: none; }
@media (min-width: 600px) {
  .jn-rail-track { height: 52px; }
  .jn-rail-svg { height: 40px; }
  .jn-node { top: 20px; }
  .jn-node-l { display: block; position: absolute; top: 16px; inset-inline-start: 50%; transform: translateX(calc(50% * var(--dir) * -1)); white-space: nowrap;
    font-size: 0.875rem; color: var(--tx3); }
  .jn-node.is-now .jn-node-l { color: var(--pri-sh); font-weight: 600; }
  .jn-node.is-done .jn-node-l { color: var(--tx2); }
}
.jn-nozzle { position: absolute; top: calc(50% - 18px + var(--dy, 0px)); inset-inline-start: calc(var(--t) * 100%); margin-inline-start: -6px; color: var(--tx); line-height: 0; }
@media (min-width: 600px) { .jn-nozzle { top: calc(2px + var(--dy, 0px)); } }
.jn-nozzle.is-travel { transition: --t .3s var(--ease); }
.jn-rail .jn-mark { flex: none; }

/* ---------------------------------------------------------------- the building mark */
.jn-mark { position: relative; display: inline-block; width: var(--mk); height: var(--mk); flex: none; }
.jn-mark > span { position: absolute; inset: 0; line-height: 0; }
.jn-mark svg { display: block; width: 100%; height: 100%; }
.jn-mark-ghost { opacity: .22; filter: grayscale(1); }
.jn-mark-ghost svg path { stroke-dasharray: 2 2.2; }
.jn-mark-print { clip-path: inset(var(--cut) 0 0 0); }
.jn-mark-print::after { content: ""; position: absolute; inset-inline: 6%; top: var(--cut); height: 2px; margin-top: -1px; background: var(--pri); border-radius: 2px; opacity: 0; }
.jn-mark.is-printing .jn-mark-print { transition: --cut .6s steps(6, end); }
.jn-mark.is-printing .jn-mark-print::after { opacity: 1; transition: --cut .6s steps(6, end); }
.jn-mark.is-solid .jn-mark-ghost { opacity: 0; }
.jn-mark .jn-mark-print, .jn-mark .jn-mark-print::after { --cut: inherit; }
.jn-rail .jn-mark, .jn-tk-mk .jn-mark { border-radius: 12px; box-shadow: 0 0 0 1px rgba(5, 40, 72, .1), 0 8px 18px -10px rgba(5, 40, 72, .45); }

/* ---------------------------------------------------------------- the phone's ticket */
.jn-ticket { position: relative; margin-bottom: 14px; border-radius: 22px; background: var(--enc); color: var(--on-enc); overflow: hidden;
  box-shadow: 0 0 0 1px rgba(var(--powder-rgb), .1), 0 18px 34px -18px rgba(0, 0, 0, .6); }
.jn-ticket:not(.is-open) { position: sticky; top: 8px; z-index: 30;
  /* paper over the 8px above it, so no half letter of the page shows through the gap */
  box-shadow: 0 -8px 0 var(--g), 0 0 0 1px rgba(var(--powder-rgb), .1), 0 18px 34px -18px rgba(0, 0, 0, .6); }
@media (min-width: 900px) { .jn-ticket { display: none; } }
.jn-tk-row { position: relative; display: flex; align-items: center; gap: 12px; height: 72px; padding: 0 12px; }
.jn-tk-cover { position: absolute; inset: 0; z-index: 0; }
/* the photo is a tint under the words, never their ground: the scrim sits ABOVE it (::after) and is dark
   under the whole text column. Measured against the lightest pixel of every cover-*-800.webp, the
   soft URL line reads at least 4.9:1 and the name 8.9:1 at the lightest stop, photo at .55 */
.jn-tk-cover .jn-cov, .jn-tk-cover .jn-cov.is-front { opacity: .55; }
.jn-tk-cover .jn-cov.is-in { opacity: 0; }
.jn-tk-cover::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(var(--dark-1-rgb), .68), rgba(var(--dark-1-rgb), .8) 45%, rgba(var(--dark-1-rgb), .8)); }
html[dir=ltr] .jn-tk-cover::after { background: linear-gradient(270deg, rgba(var(--dark-1-rgb), .68), rgba(var(--dark-1-rgb), .8) 45%, rgba(var(--dark-1-rgb), .8)); }
.jn-tk-av, .jn-tk-txt, .jn-tk-mk { position: relative; z-index: 1; }
.jn-tk-av { flex: none; width: 48px; height: 48px; border-radius: 50%; box-shadow: 0 0 0 2.5px var(--on-enc); }
.jn-tk-av img { width: 100%; height: 100%; border-radius: 50%; }
.jn-tk-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.jn-tk-name { font-family: var(--font-display); font-weight: 400; font-size: 1.1875rem; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jn-tk-name.is-ghost { color: var(--on-enc-soft); }
.jn-tk-url { font-family: var(--font-mono); font-size: 0.875rem; color: var(--on-enc-soft); white-space: nowrap; overflow: hidden; text-align: end; }
.jn-tk-url b { color: var(--on-enc); font-weight: 600; }
@media (max-width: 359px) { .jn-tk-url .jn-pfx { display: none; } }
.jn-grab { position: absolute; z-index: 2; inset-inline: 0; top: 0; height: 72px; border: 0; background: transparent; color: var(--on-enc); cursor: pointer; }
.jn-grab > span[data-copy] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.jn-grab .chev { position: absolute; bottom: 1px; inset-inline-start: 50%; transform: translateX(calc(50% * var(--dir) * -1)); line-height: 0; opacity: .75; }
.jn-grab svg { width: 16px; height: 16px; transition: transform .2s; }
.jn-grab[aria-expanded="true"] svg { transform: rotate(180deg); }
.jn-grab:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -3px; border-radius: 22px; }
.jn-tk-full { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .24s var(--ease); }
.jn-tk-full > div { overflow: hidden; min-height: 0; }
.jn-ticket.is-open .jn-tk-full { grid-template-rows: 1fr; }
.jn-tk-full .jn-screen { position: relative; height: 420px; margin: 0 10px 10px; border-radius: 22px; overflow: hidden; }
.jn-tk-full .jn-foot { margin: 0 14px 14px; font-size: 0.875rem; color: var(--on-enc-soft); }
.jn-tk-av.is-offer { box-shadow: 0 0 0 2.5px var(--accent-bright); }
.jn-tk-av .jn-offer-tag { position: absolute; bottom: -6px; inset-inline-start: 50%; transform: translateX(calc(50% * var(--dir) * -1)); }
.jn-offer-tag { display: none; background: var(--accent-bright); color: var(--tx); font-size: 0.875rem; font-weight: 700; padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.is-offer .jn-offer-tag { display: inline-block; }

/* ---------------------------------------------------------------- the desktop device on its bed */
.jn-pv-label { display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.9375rem; color: var(--tx2); margin-bottom: 14px; }
.jn-pv-label b { color: var(--tx); font-weight: 600; }
.jn-pv-label .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 4px rgba(31, 162, 148, .18); }
.jn-dev-wrap { position: relative; }
.jn-device { position: relative; width: 318px; height: 648px; max-width: 100%; margin: 0 auto; border-radius: 44px; padding: 10px;
  background: linear-gradient(150deg, var(--jn-dev-1), var(--jn-dev-2) 45%, var(--jn-dev-3));
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .07) inset, 0 0 0 1px var(--jn-dev-edge), 0 50px 100px -36px rgba(0, 0, 0, .6); }
.jn-device::before { content: ""; position: absolute; z-index: 5; top: 20px; inset-inline-start: 50%; width: 88px; height: 24px; margin-inline-start: -44px; border-radius: 999px; background: var(--jn-dev-notch); }
.jn-device .jn-screen { position: relative; height: 100%; border-radius: 36px; overflow: hidden; background: var(--enc); }
@media (min-width: 900px) and (max-width: 1099px) { .jn-dev-wrap { transform: scale(.88); transform-origin: top center; margin-bottom: -76px; } }
.jn-bed { position: relative; width: 300px; max-width: 100%; height: 14px; margin: 18px auto 0; border-radius: 6px;
  background: repeating-linear-gradient(90deg, rgba(var(--powder-rgb), .08) 0 1px, transparent 1px 10px), linear-gradient(180deg, var(--jn-bed-1), var(--jn-bed-2));
  box-shadow: 0 20px 30px -12px rgba(60, 36, 18, .5); }
.jn-bed::before { content: ""; position: absolute; top: -3px; inset-inline: 24px; height: 3px; border-radius: 3px; background: linear-gradient(90deg, transparent, var(--accent-bright) 40%, transparent); opacity: .8; }
.jn-cap { margin-top: 14px; text-align: center; font-size: 0.9375rem; color: var(--tx2); min-height: 3em; }
.jn-foot { margin-top: 6px; text-align: center; font-size: 0.875rem; color: var(--tx3); }
/* once the store exists the trust line ("nothing is saved yet") and the screen captions are no longer true */
body.is-joined .jn-foot, body.is-joined .jn-cap { display: none; }

/* the store inside (the same bones as /s/<slug>: the cover is the backdrop) */
.jn-st { position: absolute; inset: 0; color: var(--on-enc); font-size: 0.9375rem; }
.jn-st-cover { position: absolute; inset: 0 0 auto; height: 54%; background: var(--enc-2); }
.jn-st-cover.is-empty { background: repeating-linear-gradient(0deg, rgba(var(--powder-rgb), .05) 0 1px, transparent 1px 22px), repeating-linear-gradient(90deg, rgba(var(--powder-rgb), .05) 0 1px, transparent 1px 22px), var(--enc-2); }
.jn-cov { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.jn-cov.is-in { opacity: 0; }
.jn-cov.is-front { opacity: 1; transition: opacity .28s ease; }
.jn-st-shade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(var(--dark-1-rgb), .2) 0%, rgba(var(--dark-1-rgb), .1) 24%, rgba(var(--dark-1-rgb), .5) 42%, var(--enc) 62%); }
.jn-st-top { position: absolute; top: 52px; inset-inline: 14px; }
.jn-st-url { display: flex; align-items: center; justify-content: center; gap: 2px; height: 32px; padding: 0 12px; border-radius: 999px;
  background: rgba(var(--dark-1-rgb), .6); border: 1px dashed rgba(var(--powder-rgb), .3); font-family: var(--font-mono); font-size: 0.8125rem; color: var(--on-enc-soft); white-space: nowrap; overflow: hidden; }
.jn-st-url b { color: var(--on-enc); font-weight: 600; }
.jn-caret { display: inline-block; width: 2px; height: 1em; background: var(--accent-bright); margin-inline-start: 1px; }
.jn-ok { display: inline-grid; place-items: center; width: 16px; height: 16px; margin-inline-start: 6px; border-radius: 50%; background: var(--ok-deep); color: var(--on-pri); }
.jn-ok svg { width: 10px; height: 10px; }
.jn-ok.is-pop { animation: jn-pop .18s ease-out; }
.jn-st-map { position: absolute; top: 96px; inset-inline-start: 16px; display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  background: var(--ok-deep); color: var(--on-pri); font-size: 0.8125rem; font-weight: 600; }
.jn-st-map i { width: 7px; height: 7px; border-radius: 50%; background: var(--pop-mint); }
.jn-st-map.is-pop { animation: jn-pop .18s ease-out .3s both; }
.jn-st-body { position: absolute; inset-inline: 16px; top: 34%; }
.jn-st-av { position: relative; width: 88px; height: 88px; border-radius: 50%; box-shadow: 0 0 0 3px var(--mark-tile), 0 12px 24px -10px rgba(0, 0, 0, .7); background: var(--enc-2); }
.jn-st-av img { width: 100%; height: 100%; border-radius: 50%; }
.jn-st-av .jn-av-blank { display: grid; place-items: center; width: 100%; height: 100%; }
.jn-st-av.is-offer { box-shadow: 0 0 0 3px var(--accent-bright), 0 0 0 7px color-mix(in srgb, var(--accent-bright) 25%, transparent); outline: 2px dashed var(--accent-bright); outline-offset: 5px; }
.jn-st-av .jn-offer-tag { position: absolute; bottom: -6px; inset-inline-start: -4px; }
.jn-st-name { margin-top: 12px; font-family: var(--font-display); font-weight: 400; font-size: 1.625rem; line-height: 1.1; overflow-wrap: anywhere; }
.jn-st-name.is-ghost { display: inline-block; color: var(--on-enc-soft); border-bottom: 2px dashed rgba(var(--powder-rgb), .35); }
.jn-st-tag { margin: 6px 0 0; font-size: 0.8125rem; line-height: 1.4; color: var(--on-enc-soft); }
.jn-st-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; color: var(--on-enc-soft); font-size: 0.8125rem; }
.jn-st-meta .pv-city { margin: 0; color: var(--on-enc); font-size: 0.875rem; }
.jn-st-city.is-ghost .pv-city { color: var(--on-enc-soft); border-bottom: 1px dashed rgba(var(--powder-rgb), .35); }
.jn-st-pin svg { width: 14px; height: 14px; }
.jn-st-kind { font-size: 0.75rem; font-weight: 600; padding: 1px 7px; border-radius: 6px; border: 1px solid rgba(var(--powder-rgb), .4); color: var(--on-enc); }
.jn-st-chips { display: flex; flex-wrap: nowrap; overflow: hidden; gap: 6px; margin-top: 10px; }
.jn-st-chips .chip.static { flex: none; min-height: 30px; padding: 3px 10px; font-size: 0.8125rem; background: rgba(var(--powder-rgb), .12); border-color: rgba(var(--powder-rgb), .22); color: var(--on-enc); }
.jn-chip-ghost { border: 1px dashed rgba(var(--powder-rgb), .35); border-radius: 999px; padding: 4px 10px; color: var(--on-enc-soft); font-size: 0.8125rem; }
.jn-st-works { margin-top: 12px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.jn-st-wh { grid-column: 1 / -1; font-size: 0.8125rem; color: var(--on-enc-soft); }
.jn-st-works i { aspect-ratio: 4 / 3; border-radius: 10px; border: 1.5px dashed rgba(var(--powder-rgb), .25); background: rgba(var(--powder-rgb), .04); }
.jn-st-bar { position: absolute; inset-inline: 10px; bottom: 12px; display: flex; align-items: center; gap: 8px; padding: 8px; border-radius: 20px; background: rgba(var(--dark-1-rgb), .8); border: 1px solid rgba(var(--powder-rgb), .14); }
.jn-st-req { flex: 1; height: 44px; border-radius: 14px; background: var(--st-accent, var(--pri)); color: var(--on-pri); font-weight: 600; font-size: 0.9375rem; display: grid; place-items: center; }
.jn-st-wa { width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; flex: none; transition: opacity .15s; }
.jn-st-wa svg { width: 22px; height: 22px; }
.jn-st[data-wa="unset"] .jn-st-wa { border: 1.5px dashed rgba(var(--powder-rgb), .45); color: var(--on-enc-soft); }
.jn-st[data-wa="show"] .jn-st-wa { background: var(--wa); color: var(--jn-wa-ink); }
.jn-st[data-wa="hide"] .jn-st-wa { background: rgba(var(--powder-rgb), .1); color: var(--on-enc); border: 1px dashed rgba(var(--powder-rgb), .4); }
.jn-st-wa.is-ghosting { opacity: .6; }
.jn-q { font-size: 1.25rem; font-weight: 600; }
.jn-wa-tip { display: none; position: absolute; bottom: calc(100% + 10px); inset-inline-end: 0; background: var(--card); color: var(--tx); border-radius: 12px; padding: 6px 10px; font-size: 0.8125rem; font-weight: 500; white-space: nowrap; box-shadow: 0 12px 26px -12px rgba(0, 0, 0, .7); }
.on-reach .jn-st[data-wa="unset"] .jn-wa-tip { display: block; }
.jn-st-badge { position: absolute; top: 12px; inset-inline-end: 16px; }
.jn-st-badge .jn-mark { border-radius: 8px; }
/* live: the ghosts go solid */
.jn-st.is-live .jn-st-url { border-style: solid; }
.jn-st.is-live .jn-caret, .jn-st.is-live .jn-offer-tag { display: none; }
/* the works: the dashed placeholders fade out and one solid plate says where the first works will go */
.jn-st-works { position: relative; }
.jn-st-works i { transition: opacity .3s ease; }
.jn-st-first { position: absolute; inset-inline: 0; bottom: 0; display: grid; place-items: center; aspect-ratio: 12 / 3; padding: 0 12px;
  border-radius: 10px; background: rgba(var(--powder-rgb), .1); border: 1px solid rgba(var(--powder-rgb), .22);
  font-size: 0.8125rem; color: var(--on-enc); text-align: center; opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s .3s; }
.jn-st.is-live .jn-st-works i { opacity: 0; }
.jn-st.is-live .jn-st-first { opacity: 1; visibility: visible; transition: opacity .3s ease .1s; }

/* ---------------------------------------------------------------- the build moment */
.jn-build { text-align: center; padding: 12px 0 4px; }
.jn-build[hidden] { display: none; }
.jn-build .jn-mark { margin: 6px auto 0; }
.jn-build h2 { margin: 16px 0 12px; }
.jn-log { list-style: none; display: grid; gap: 10px; max-width: 360px; margin: 0 auto; padding: 0; text-align: start; }
.jn-log-row { display: flex; align-items: center; gap: 10px; min-height: 36px; font-size: 1rem; color: var(--tx2); }
.jn-log-row svg { flex: none; width: 22px; height: 22px; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.jn-ring circle { stroke: var(--jn-edge); }
.jn-ring path { stroke: var(--on-pri); stroke-width: 2.6; stroke-dasharray: 1; stroke-dashoffset: 1; }
.jn-clock { display: none; stroke: var(--tx2); }
.jn-log-row.is-done { color: var(--tx); }
.jn-log-row.is-done .jn-ring circle { fill: var(--jn-ok-text); stroke: var(--jn-ok-text); }
.jn-log-row.is-done .jn-ring path { stroke-dashoffset: 0; transition: stroke-dashoffset .2s ease-out; }
.jn-log-row.is-wait .jn-ring { display: none; }
.jn-log-row.is-wait .jn-clock { display: block; }
.jn-log-row bdi { font-family: var(--font-mono); font-size: 0.9375rem; white-space: nowrap; }

/* ---------------------------------------------------------------- the finish: stamp, QR tag */
.jn-stamp { display: inline-grid; justify-items: center; gap: 2px; padding: 6px 12px; border: 2px solid var(--pri-sh); border-radius: 10px;
  box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--pri-sh); color: var(--pri-sh); transform: rotate(-8deg); font-family: var(--font-display); font-size: 1.25rem; line-height: 1.1; }
.jn-stamp small { font-family: var(--font-mono); font-size: 0.8125rem; direction: ltr; unicode-bidi: isolate; }
.jn-stamp.is-land { animation: jn-stamp .24s cubic-bezier(.2, .8, .2, 1.2) .66s both; }
.jn-qrtag { position: absolute; z-index: 6; width: 150px; padding: 16px 12px 12px; border-radius: 18px; background: var(--card); color: var(--tx); border: 0; cursor: pointer;
  box-shadow: 0 30px 60px -24px rgba(0, 0, 0, .6), 0 0 0 1px rgba(var(--graphite-rgb), .08); text-align: center; font: inherit; }
.jn-qrtag::before { content: ""; position: absolute; top: 8px; inset-inline-start: 50%; width: 12px; height: 12px; margin-inline-start: -6px; border-radius: 50%; background: var(--sunk); box-shadow: inset 0 2px 3px rgba(0, 0, 0, .35); }
.jn-qrtag canvas { display: block; width: 120px; height: 120px; margin: 12px auto 0; }
.jn-qrtag .s { display: block; margin-top: 8px; font-weight: 600; font-size: 0.875rem; }
.jn-qrtag .u { display: block; margin-top: 2px; font-family: var(--font-mono); font-size: 0.875rem; line-height: 1.3; color: var(--tx2); direction: ltr; unicode-bidi: isolate; overflow-wrap: anywhere; }
.jn-qrtag:focus-visible { outline: 2px solid var(--pri-sh); outline-offset: 3px; }
.jn-dev-wrap .jn-qrtag { top: 150px; inset-inline-start: calc(100% - 50px); transform: rotate(-4deg); }
/* on a phone the tag hangs on the live card's edge, over the cover, never in a band of its own */
.jn-tk-full > div { position: relative; }
.jn-ticket .jn-qrtag { position: absolute; top: 58px; inset-inline-end: 18px; width: 128px; padding: 14px 10px 10px; transform: rotate(-4deg); }
.jn-ticket .jn-qrtag canvas { width: 96px; height: 96px; margin-top: 10px; }
/* the finish: the card is the store now, so its 72px row (the same name, face and address) goes, and
   its screen is shorter so the confirmation below it starts on the first screen */
body.is-joined .jn-ticket #jnTicketRow, body.is-joined .jn-ticket .jn-grab { display: none; }
body.is-joined .jn-ticket .jn-tk-full .jn-screen { margin-top: 10px; }
@media (max-height: 899px) { body.is-joined .jn-tk-full .jn-screen { height: 360px; } }
.jn-qrtag[hidden] { display: none; }
.jn-qrtag.is-out { animation: jn-tag .36s cubic-bezier(.2, .8, .2, 1) .3s both; }

@keyframes jn-pop { from { transform: scale(.8); } to { transform: none; } }
@keyframes jn-stamp { 0% { transform: scale(1.3) rotate(-12deg); opacity: 0; } 70% { transform: scale(.96) rotate(-8deg); opacity: 1; } 100% { transform: rotate(-8deg); } }
@keyframes jn-tag { from { transform: translateX(calc(40px * var(--dir))) rotate(0deg); opacity: 0; } to { transform: rotate(-4deg); opacity: 1; } }
@keyframes jn-in { from { opacity: 0; transform: translateX(calc(24px * var(--dir))); } to { opacity: 1; transform: none; } }
@keyframes jn-in-back { from { opacity: 0; transform: translateX(calc(-24px * var(--dir))); } to { opacity: 1; transform: none; } }
@keyframes jn-fade { from { opacity: 0; } to { opacity: 1; } }
.step.is-in { animation: jn-in .22s cubic-bezier(.2, .8, .2, 1) both; }
.step.is-in-back { animation: jn-in-back .22s cubic-bezier(.2, .8, .2, 1) both; }
.jn-st.is-live .jn-st-name, .jn-st.is-live .jn-st-url { animation: jn-fade .3s ease both; }

@media (prefers-reduced-motion: reduce) {
  .jn-nozzle.is-travel, .jn-tk-full, .jn-cov.is-front, .jn-st-wa, .jn-grab svg { transition: none; }
  .jn-st-works i, .jn-st-first, .jn-st.is-live .jn-st-first { transition: opacity .15s ease; }
  .jn-mark.is-printing .jn-mark-print, .jn-mark.is-printing .jn-mark-print::after { transition: none; }
  .jn-mark.is-fading .jn-mark-print { animation: jn-fade .15s ease both; }
  .jn-ok.is-pop, .jn-st-map.is-pop, .jn-stamp.is-land, .jn-qrtag.is-out { animation: none; }
  .jn-log-row.is-done .jn-ring path { transition: none; }
  .step.is-in, .step.is-in-back { animation: jn-fade .12s ease both; }
  .jn-st.is-live .jn-st-name, .jn-st.is-live .jn-st-url { animation: jn-fade .2s ease both; }
}
