/*
 * Paytrack product site (kirbyservice.net): Measure's component (round 3,
 * plan.md). One floating reports panel on the right, turned towards Db, who
 * stands on its left; its view changes as the story moves. Markup in
 * obj/part_measure.php, the counts, the views and Db's moves in
 * js/parts/measure.js, the runner in js/parts/part.js. Keep this file ASCII.
 *
 * Four steps, one page each: 0 jobs (by area, by technician, by month),
 * 1 job (job 1043's parts: cost, price, profit), 2 stock (belts on hand and
 * the forecast past the reorder level; Db's red alert), 3 map (today's areas
 * and the next one).
 *
 * The whole scene is sized in em: .pt-part-stage takes the unit from the
 * column's width (container units) and the screen's height, so every part
 * keeps its place at every size and no text drops below 10px (the smallest
 * text is .8em of at least 12.5px). Two compositions: wide (desktop and
 * tablet, 35 x 15.6 em: Db on the left with his line and the Auto order
 * button above him, the panel) and phones (25.6 x 14 em: Db small at the
 * left, the panel; his line and the button, only while step 2's chart
 * shows, sit over the empty top of the chart, a deliberate overlap: with
 * the layer's copy above, a short phone has about 185 px for the scene).
 * Motion is transform and opacity only; the steps are the pt-sN
 * classes and data-step (part.js), the beats inside a step are transition
 * delays and the mb-* classes (measure.js). Elements marked .ms-mv take the
 * quick and snap modes at the end of this file; every one-shot effect also
 * says :not(.ms-quick).
 *
 * Reports: the bars stand still while a band of light sweeps behind them
 * (Dimitar's rule for reports, as in Grow). Colours say what a thing is:
 * mist a report (Measure's tone: the panel's band, the bars, the stock),
 * sand ahead (the forecast, the next area), clay a limit (the reorder
 * level), sage done (the profit), the soft red of the site's alert bubble.
 *
 * Spacing (Dimitar, 02/10/2026, on Get paid: "things overlap"): the objects
 * never touch, with at least 8 px of air on desktop and 6 on phones, the
 * bobs, the hop and the lean towards the pointer included; every text fits
 * its box inside its padding. Checked with tools/browser/paytrack_overlap_check.js.
 */

/* ---------- the stage: the unit, the depth ------------------------------- */
.pt-part-measure { container-type: inline-size; }
.pt-part-measure .pt-part-stage { position: relative; font-size: 14px;
  font-size: max(12.5px, min(16px, calc(100cqw / 35), 2vh));
  perspective: 1100px; perspective-origin: 58% 42%; }
.pt-part-measure .pt-part-tilt { transform-style: preserve-3d; transition: transform .6s cubic-bezier(.2, .8, .3, 1); }
.pt-part-measure .ms-set { position: relative; width: 35em; height: 15.6em; margin: 0 auto; transform-style: preserve-3d; line-height: 1.3;
  --chart: 7.4em; --top: 6%; }
.pt-part-measure .ms-set i { display: block; font-style: normal; }

/* The light in the room: a mist pool under the panel, a sand one under Db.
   No surface edges anywhere. Pseudo-elements, so no check counts them as
   objects of the scene; the panel's shadow shrinks as it rises. */
.pt-part-measure .ms-set::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(36% 36% at 66% 82%, rgba(147, 183, 198, .10), rgba(147, 183, 198, 0) 72%),
    radial-gradient(18% 22% at 22% 90%, rgba(217, 197, 154, .10), rgba(217, 197, 154, 0) 72%);
  transform: translateZ(-3em); }
.pt-part-measure .ms-set::after { content: ""; position: absolute; left: 13.8em; width: 19.8em; top: 14.5em; height: 1.1em; pointer-events: none;
  background: radial-gradient(closest-side, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
  transform: translateZ(-.6em); animation: ms-shadow 6s ease-in-out infinite; }
@keyframes ms-shadow { 0%, 100% { opacity: 1; transform: translateZ(-.6em) scale(1); } 50% { opacity: .72; transform: translateZ(-.6em) scale(.9); } }

/* ---------- Db and his line --------------------------------------------------- */
/* He stands left of the panel, a little in front of it. His own bob is 6 px
   here (not site.css's 12), so his line above keeps its air. */
.pt-part-measure .ms-db { position: absolute; left: 4.9em; bottom: .5em; width: 6em; transform: translateZ(1.4em); pointer-events: none; }
.pt-part-measure .ms-db .pt-char { width: 100%; animation-name: ms-bob; }
@keyframes ms-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -6px; } }
.pt-part-measure .ms-db-in { transform-origin: 50% 100%; }
/* A hop when the next area lights up (measure.js; site.css also swells him with .is-hop). */
.pt-part-measure.mb-hop:not(.ms-quick) .ms-db-in { animation: ms-hop .62s cubic-bezier(.3, .7, .4, 1); }
@keyframes ms-hop { 0%, 62%, 100% { transform: translateY(0); } 35% { transform: translateY(-1em); } 78% { transform: translateY(-.22em); } }

/* His line, only in step 2: the site's alert bubble (soft red), above him,
   its tail down to his face, and just left of it, on the same line, the
   app's Auto order button (Dimitar, 02/10/2026: "button in the left of the
   order by friday speach bubble"), the warning and the action together.
   The left column is 12.5 em, so the line takes three short lines here:
   the button .2 to 5.64 em, .65 em of air (8 px at the smallest unit), the
   bubble to 11.87 em, 8 px clear of the panel; his middle is at 7.9 em. Air
   below it for his bob and his lean towards the pointer (up to 9 px up,
   js/stage.js). Both come in as the forecast crosses the reorder level
   (2.35 s) and go with the step. */
.pt-part-measure .ms-say { position: absolute; left: 6.29em; top: 1.2em; width: 5.58em; transform: translateZ(1em);
  opacity: 0; transition: opacity .3s ease; }
.pt-part-measure[data-step="2"] .ms-say { opacity: 1; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-say { transition-delay: 2.35s; }
.pt-part-measure .ms-say .pt-bubble { max-width: none; margin: 0; padding: .55em .7em; font-size: .8em; line-height: 1.4;
  border-radius: 1.2em 1.2em 1.2em .45em; transform-origin: 25% 100%; }
.pt-part-measure .ms-say .pt-bubble::before { left: calc(2em - 6px); right: auto; bottom: -6px; clip-path: polygon(100% 0, 100% 100%, 0 100%); }
/* Its pop: in from below, a little shake as a warning. */
.pt-part-measure .ms-say .pt-bubble { scale: .7; transition: opacity .4s ease .45s, transform .5s var(--pt-spring) .45s, scale .5s var(--pt-spring); }
.pt-part-measure[data-step="2"] .ms-say .pt-bubble { scale: 1; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-say .pt-bubble { transition-delay: .45s, .45s, 2.35s; animation: ms-warn .5s ease-in-out 2.75s; }
@keyframes ms-warn { 0%, 100% { rotate: 0deg; } 25% { rotate: -2.5deg; } 50% { rotate: 2deg; } 75% { rotate: -1deg; } }
html:not(.js) .pt-part-measure .pt-bubble { opacity: 1; transform: none; }

/* The Auto order button: sand, the action. It comes in just after the
   warning, then it is pressed with no pointer, as a touch on a phone: it
   squeezes, a filled circle shows at its middle and two rings spread from
   it and fade; the order list then fills in on the panel. */
.pt-part-measure .ms-auto { position: absolute; left: .2em; top: 2.4em; width: 5.44em; transform: translateZ(1em); pointer-events: none;
  opacity: 0; transition: opacity .3s ease; }
.pt-part-measure[data-step="2"] .ms-auto { opacity: 1; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-auto { transition-delay: 2.55s; }
.pt-part-measure .ms-btn { position: relative; display: flex; align-items: center; justify-content: center; padding: .55em .9em; border-radius: .75em;
  background: var(--pt-sand); color: var(--pt-night); box-shadow: 0 .6em 1.2em -.4em rgba(0, 0, 0, .6);
  font: 700 .8em/1.2 var(--pt-text); white-space: nowrap; transition: transform .5s var(--pt-spring); }
.pt-part-measure .ms-auto .ms-btn { transform: scale(.7); }
.pt-part-measure[data-step="2"] .ms-auto .ms-btn { transform: none; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-auto .ms-btn { transition-delay: 2.55s; animation: ms-press .42s ease-out 3.05s; }
.pt-part-measure .ms-btn > span { position: relative; }
.pt-part-measure .ms-tap,
.pt-part-measure .ms-ring { position: absolute; left: 50%; top: 50%; width: 2.6em; height: 2.6em; margin: -1.3em 0 0 -1.3em; border-radius: 50%; opacity: 0; pointer-events: none; }
.pt-part-measure .ms-tap { background: rgba(14, 19, 17, .28); }
.pt-part-measure .ms-ring { border: .14em solid var(--pt-sand); }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-auto .ms-tap { animation: ms-tap .6s ease-out 3.05s; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-auto .ms-ring1 { animation: ms-ripple .9s ease-out 3.1s; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-auto .ms-ring2 { animation: ms-ripple .9s ease-out 3.3s; }
@keyframes ms-press { 0%, 100% { transform: none; } 35% { transform: scale(.9); } }
@keyframes ms-tap { 0% { opacity: .95; transform: scale(.2); } 60% { opacity: .8; transform: scale(1); } 100% { opacity: 0; transform: scale(1.1); } }
@keyframes ms-ripple { 0% { opacity: .85; transform: scale(.4); } 100% { opacity: 0; transform: scale(2.6); } }

/* ---------- the panel: floats, turned towards Db -------------------------------- */
.pt-part-measure .ms-float { position: absolute; left: 12.5em; top: .3em; width: 22.3em; height: 14.4em; transform-style: preserve-3d;
  animation: ms-float 6s ease-in-out infinite; }
@keyframes ms-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-.35em); } }
/* The card: raised, a thin mist band along the top (Measure's tone), a soft
   static shadow. Flat inside: its pages turn in their own perspective. */
.pt-part-measure .ms-card { position: absolute; inset: 0; border-radius: .95em; color: var(--pt-bone);
  background:
    linear-gradient(var(--pt-mist), var(--pt-mist)) 0 0 / 100% .3em no-repeat,
    linear-gradient(180deg, rgba(236, 230, 218, .05), rgba(236, 230, 218, 0) 45%),
    var(--pt-raised);
  box-shadow: 0 1.8em 2.6em -1.2em rgba(0, 0, 0, .75), 0 .2em .5em rgba(0, 0, 0, .25), inset 0 0 0 1px rgba(236, 230, 218, .07);
  transform: rotateY(-9deg) rotateX(3deg); }
/* At every page turn the reports card swings a little (two names in turn). */
.pt-part-measure[data-step="0"]:not(.ms-quick) .ms-c1,
.pt-part-measure[data-step="2"]:not(.ms-quick) .ms-c1 { animation: ms-swing-a 1s ease-in-out; }
.pt-part-measure[data-step="1"]:not(.ms-quick) .ms-c1 { animation: ms-swing-b 1s ease-in-out; }
@keyframes ms-swing-a { 40% { transform: rotateY(-14deg) rotateX(4.5deg) translateZ(-.3em); } }
@keyframes ms-swing-b { 40% { transform: rotateY(-14deg) rotateX(4.5deg) translateZ(-.3em); } }
/* Then a new card for the expansion (Dimitar, 02/10/2026: "email to
   warehouse - animate card silde out and start with new graph sliding in"):
   at step 3 the reports card, the restock still on it, slides out to the
   left and back with a tilt, behind Db, as the map's card slides in from
   the right, turned, and settles into the same pose; its beats wait for it.
   Two cards, not a page change; the step and its pointer change together. */
/* In turn, so the two never lie on each other: the old one is out (.55 s)
   before the new one shows (from .5 s), which comes in near enough to stay
   on the screen once it can be seen, and settles by 1.3 s. */
.pt-part-measure .ms-c1 { transition: transform .65s cubic-bezier(.45, 0, .55, 1), opacity .4s ease .15s; }
.pt-part-measure.pt-s3 .ms-c1 { opacity: 0; transform: translate3d(-6em, .3em, -3em) rotateY(30deg) rotateX(3deg); }
.pt-part-measure .ms-c2 { opacity: 0; transform: translate3d(4.5em, 0, -2em) rotateY(-30deg) rotateX(3deg);
  transition: transform .9s var(--pt-spring), opacity .3s ease; }
.pt-part-measure.pt-s3 .ms-c2 { opacity: 1; transform: rotateY(-9deg) rotateX(3deg); }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-c2 { transition-delay: .4s, .5s; }

/* The pages, stacked in one cell: the one in play is up, the ones before it
   turned away above, the ones after it waiting below. */
.pt-part-measure .ms-pages { position: absolute; inset: 1.05em 1em .9em; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  perspective: 40em; transition: opacity .35s ease; }
.pt-part-measure .ms-page { grid-area: 1 / 1; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  opacity: 0; transform: translate3d(0, .9em, 0) rotateX(-20deg); transition: opacity .3s ease, transform .6s var(--pt-spring); }
.pt-part-measure[data-step="-1"] .ms-pg-jobs,
.pt-part-measure[data-step="0"] .ms-pg-jobs,
.pt-part-measure[data-step="1"] .ms-pg-job,
.pt-part-measure[data-step="2"] .ms-pg-stock,
.pt-part-measure[data-step="3"] .ms-pg-stock,
.pt-part-measure .ms-c2 .ms-pg-map { opacity: 1; transform: none; }
.pt-part-measure.pt-s1 .ms-pg-jobs,
.pt-part-measure.pt-s2 .ms-pg-job { transform: translate3d(0, -.7em, 0) rotateX(20deg); }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-pg-job,
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-pg-stock { transition-delay: .2s; }

/* Every page: a header line (its title, a note, a switch or a chip on the
   right), then its body. */
.pt-part-measure .ms-hd { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: .6em;
  height: 2.1em; padding-bottom: .5em; margin-bottom: .3em; box-shadow: 0 1px 0 rgba(236, 230, 218, .08); }
.pt-part-measure .ms-t { font: 500 .95em/1.2 var(--pt-head); letter-spacing: -.01em; color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-hd-note { font: 500 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-bd { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: center; }

/* ---------- the parts every page uses ------------------------------------------- */
.pt-part-measure .ms-chip { position: relative; flex: 0 0 auto; display: inline-flex; align-items: center; gap: .42em; padding: .34em .78em; border-radius: 999px;
  font: 600 .8em/1.2 var(--pt-text); white-space: nowrap; }
.pt-part-measure .ms-chip > span { position: relative; }
.pt-part-measure .ms-chip b { font-weight: 700; }
.pt-part-measure .ms-sand { background: rgba(217, 197, 154, .16); color: var(--pt-sand); }
.pt-part-measure .ms-pop::before { content: ""; position: absolute; inset: -.24em; border-radius: inherit; border: .12em solid currentColor;
  opacity: 0; pointer-events: none; }
.pt-part-measure .ms-shine { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.pt-part-measure .ms-shine::after { content: ""; position: absolute; top: -20%; bottom: -20%; left: 0; width: 45%;
  background: linear-gradient(105deg, rgba(236, 230, 218, 0), rgba(236, 230, 218, .42) 50%, rgba(236, 230, 218, 0));
  transform: translateX(-120%); }
@keyframes ms-ring { 0% { opacity: .85; transform: scale(.94); } 100% { opacity: 0; transform: scale(1.18, 1.6); } }
@keyframes ms-ring-sq { 0% { opacity: .85; transform: scale(.97); } 100% { opacity: 0; transform: scale(1.12, 1.3); } }
@keyframes ms-ring-o { 0% { opacity: .9; transform: scale(.6); } 100% { opacity: 0; transform: scale(2.2); } }
@keyframes ms-shine { 0% { transform: translateX(-120%); } 100% { transform: translateX(300%); } }
/* Reports: the bars stand still, a band of light sweeps behind them. */
.pt-part-measure .ms-sweep { position: absolute; inset: -.2em -.3em; border-radius: .7em; overflow: hidden; pointer-events: none; }
.pt-part-measure .ms-sweep i { position: absolute; top: 0; bottom: 0; left: 0; width: 35%;
  background: linear-gradient(100deg, rgba(147, 183, 198, 0), rgba(147, 183, 198, .12) 50%, rgba(147, 183, 198, 0)); transform: translateX(-110%); }
@keyframes ms-sweep { 0% { transform: translateX(-110%); } 55%, 100% { transform: translateX(300%); } }
.pt-part-measure[data-step="0"] .ms-sweep i { animation: ms-sweep 3.4s ease-in-out 1s infinite; }

/* ---------- step 0, page jobs: by area, technician and month ------------------ */
/* A switch in the header slides from Area to Technician to Month (measure.js:
   mb-area, then mb-tech, then neither); each view comes in from the right
   as the last goes out to the left, its counts rolling up. At rest (no JS,
   a jump) the month view. */
.pt-part-measure .ms-switch { position: relative; flex: 0 0 auto; display: grid; grid-template-columns: 1fr 1fr 1fr; padding: .2em; border-radius: 999px;
  background: rgba(236, 230, 218, .06); box-shadow: inset 0 0 0 1px rgba(236, 230, 218, .08); }
.pt-part-measure .ms-sw { position: relative; padding: .26em .55em .28em; text-align: center; font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-thumb { position: absolute; left: .2em; top: .2em; bottom: .2em; width: calc((100% - .4em) / 3); border-radius: 999px;
  background: rgba(147, 183, 198, .2); box-shadow: inset 0 0 0 1px rgba(147, 183, 198, .4);
  transform: translateX(200%); transition: transform .5s var(--pt-spring); }
.pt-part-measure.mb-area .ms-thumb { transform: none; }
.pt-part-measure.mb-tech .ms-thumb { transform: translateX(100%); }
.pt-part-measure .ms-jobs { justify-content: flex-start; }
/* The period of the view: this month, or the last six. */
.pt-part-measure .ms-note { position: relative; display: grid; margin: 0 0 .5em .1em; }
.pt-part-measure .ms-note > span { grid-area: 1 / 1; font: 600 .8em/1.2 var(--pt-text); letter-spacing: .02em; color: var(--pt-lichen); white-space: nowrap;
  transition: opacity .3s ease, transform .45s var(--pt-spring); }
.pt-part-measure .ms-note-1 { opacity: 0; transform: translateY(-.4em); }
.pt-part-measure.mb-area .ms-note-1,
.pt-part-measure.mb-tech .ms-note-1 { opacity: 1; transform: none; }
.pt-part-measure.mb-area .ms-note-6,
.pt-part-measure.mb-tech .ms-note-6 { opacity: 0; transform: translateY(.4em); }
.pt-part-measure .ms-views { position: relative; display: grid; }
.pt-part-measure .ms-view { grid-area: 1 / 1; display: flex; flex-direction: column; justify-content: center; gap: .5em; min-width: 0;
  opacity: 0; transform: translateX(1.2em); transition: opacity .3s ease, transform .55s var(--pt-spring); }
.pt-part-measure.mb-area .ms-v-area,
.pt-part-measure.mb-tech .ms-v-tech,
.pt-part-measure:not(.mb-area):not(.mb-tech) .ms-v-month { opacity: 1; transform: none; }
.pt-part-measure.mb-tech .ms-v-area,
.pt-part-measure:not(.mb-area):not(.mb-tech) .ms-v-area,
.pt-part-measure:not(.mb-area):not(.mb-tech) .ms-v-tech { transform: translateX(-1.2em); }
/* A row: who or where, a bar (its share of the largest), the count. */
.pt-part-measure .ms-row { display: grid; grid-template-columns: auto minmax(0, 1fr) 6.2em 1.7em; column-gap: .55em; align-items: center; height: 1.55em; }
.pt-part-measure .ms-pc { justify-self: start; padding: .2em .55em .22em; border-radius: 999px; background: rgba(217, 197, 154, .16); color: var(--pt-sand);
  font: 700 .8em/1.2 var(--pt-text); font-variant-numeric: tabular-nums; }
.pt-part-measure .ms-sub { min-width: 0; font: 500 .84em/1.2 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-bar { position: relative; height: .5em; border-radius: .25em; background: rgba(236, 230, 218, .08); overflow: hidden; }
.pt-part-measure .ms-bar i { position: absolute; inset: 0; border-radius: inherit; background: var(--pt-mist); transform: scaleX(var(--w, 1)); transform-origin: 0 50%; }
.pt-part-measure .ms-n { justify-self: end; font: 500 .88em/1.2 var(--pt-head); letter-spacing: -.01em; color: var(--pt-bone); font-variant-numeric: tabular-nums; }
/* By technician: what each of them sold this month, item by item (as
   Grow's items sold), in one grid: the parts down the left in the same
   order for both, a column each, so a row is one part for both and the eye
   compares across (Dimitar: "same row - same part"). Every count has its
   bar on one scale: Maria in dusk, Ryan in sage, as in Grow; a zero is an
   empty bar. The page's title reads Sold meanwhile. */
.pt-part-measure .ms-v-tech { display: block; }
.pt-part-measure .ms-st { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr); column-gap: .9em; row-gap: .5em; align-items: center; }
.pt-part-measure .ms-who { display: flex; align-items: center; gap: .45em; min-width: 0; }
.pt-part-measure .ms-av { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; width: 2.1em; height: 2.1em; border-radius: 50%;
  font: 600 .8em/1 var(--pt-head); color: var(--pt-night); background: var(--pt-dusk); }
.pt-part-measure .ms-av-r { background: var(--pt-sage); }
.pt-part-measure .ms-who-n { font: 600 .88em/1.2 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-it-n { min-width: 0; font: 500 .84em/1.2 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-cell { display: grid; grid-template-columns: 2.4em minmax(0, 1fr); align-items: center; column-gap: .4em; min-width: 0; }
.pt-part-measure .ms-qty { display: flex; align-items: baseline; justify-content: flex-end; gap: .15em; white-space: nowrap; }
.pt-part-measure .ms-qty small { font: 500 .8em/1.2 var(--pt-text); color: var(--pt-lichen); }
.pt-part-measure .ms-qty b { font: 500 .88em/1.2 var(--pt-head); letter-spacing: -.01em; color: var(--pt-bone); font-variant-numeric: tabular-nums; }
.pt-part-measure .ms-share { position: relative; height: .34em; border-radius: .17em; background: rgba(236, 230, 218, .08); overflow: hidden; }
.pt-part-measure .ms-share i { position: absolute; inset: 0; border-radius: inherit; background: var(--pt-dusk); transform: scaleX(var(--w, 1)); transform-origin: 0 50%; }
.pt-part-measure .ms-cell-r .ms-share i { background: var(--pt-sage); }
/* The page's title: Jobs, or Sold while the technicians show. */
.pt-part-measure .ms-t2 { display: grid; }
.pt-part-measure .ms-t2 > span { grid-area: 1 / 1; transition: opacity .3s ease, transform .45s var(--pt-spring); }
.pt-part-measure .ms-t-sold { opacity: 0; transform: translateY(.4em); }
.pt-part-measure.mb-tech .ms-t-jobs { opacity: 0; transform: translateY(-.4em); }
.pt-part-measure.mb-tech .ms-t-sold { opacity: 1; transform: none; }
/* Jobs a month: six columns, this month's lit. */
.pt-part-measure .ms-v-month { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: .5em; height: 6.6em; }
.pt-part-measure .ms-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: .3em; min-width: 0; height: 100%; justify-content: flex-end; }
.pt-part-measure .ms-col .ms-n { justify-self: auto; font-size: .8em; color: var(--pt-lichen); }
.pt-part-measure .ms-colbar { width: 62%; height: 3.6em; border-radius: .35em .35em .12em .12em; background: rgba(147, 183, 198, .5);
  transform: scaleY(var(--h, 1)); transform-origin: 50% 100%; }
.pt-part-measure .ms-col small { font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-col-now .ms-colbar { background: var(--pt-mist); box-shadow: 0 0 .9em rgba(147, 183, 198, .35); }
.pt-part-measure .ms-col-now .ms-n,
.pt-part-measure .ms-col-now small { color: var(--pt-bone); }

/* ---------- step 1, page job: parts used, cost and profit ------------------------ */
/* Job 1043's two parts slide in, then three tiles land with their figures
   rolling up (measure.js): what the parts cost, what they sold for, and the
   profit, which pops. */
.pt-part-measure .ms-job { justify-content: center; gap: .85em; }
.pt-part-measure .ms-tbl { display: flex; flex-direction: column; }
.pt-part-measure .ms-tr { display: grid; grid-template-columns: minmax(0, 1fr) 4.4em 4.4em; column-gap: .5em; align-items: center; height: 1.7em; padding: 0 .45em;
  box-shadow: inset 0 -1px 0 rgba(236, 230, 218, .05); }
.pt-part-measure .ms-tr > span { font: 500 .86em/1.2 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-tr > span + span { justify-self: end; font-weight: 600; font-variant-numeric: tabular-nums; }
.pt-part-measure .ms-tr-h { height: 1.45em; }
.pt-part-measure .ms-tr-h > span,
.pt-part-measure .ms-tr-h > span + span { font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); }
.pt-part-measure .ms-tr1,
.pt-part-measure .ms-tr2 { opacity: 0; transform: translateX(-.8em); transition: opacity .3s ease, transform .5s var(--pt-spring); }
.pt-part-measure.pt-s1 .ms-tr1,
.pt-part-measure.pt-s1 .ms-tr2 { opacity: 1; transform: none; }
.pt-part-measure .ms-tiles { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: .6em; }
.pt-part-measure .ms-tile { position: relative; display: flex; flex-direction: column; gap: .2em; padding: .5em .7em .55em; border-radius: .75em;
  background: rgba(236, 230, 218, .05); box-shadow: inset 0 0 0 1px rgba(236, 230, 218, .07);
  opacity: 0; transform: translateY(.7em) scale(.92); transition: opacity .3s ease, transform .55s var(--pt-spring); }
.pt-part-measure.pt-s1 .ms-tile { opacity: 1; transform: none; }
.pt-part-measure .ms-tile small { font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-tile b { font: 500 1.05em/1.2 var(--pt-head); letter-spacing: -.02em; color: var(--pt-bone); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pt-part-measure .ms-tile-g { background: rgba(157, 184, 159, .14); box-shadow: inset 0 0 0 1px rgba(157, 184, 159, .35); color: var(--pt-sage); }
.pt-part-measure .ms-tile-g b { color: var(--pt-sage); }
.pt-part-measure .ms-tile-g::before { border-radius: .95em; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tr1 { transition-delay: .4s; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tr2 { transition-delay: .6s; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tile-c { transition-delay: 1.05s; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tile-p { transition-delay: 1.2s; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tile-g { transition-delay: 1.35s; }
.pt-part-measure:not(.ms-quick)[data-step="1"] .ms-tile-g::before { animation: ms-ring-sq .8s ease-out 2.05s forwards; }

/* ---------- step 2, page stock: parts forecast, restock in time ------------------- */
/* Two views in one step (measure.js: mb-chart, then none, the view at
   rest). First the chart: belts on hand week by week draws itself (a window
   that slides over the still line while the line inside it slides back),
   then the forecast runs on from this week in dashes and crosses the
   reorder level: a red ring pulses there, Db's line comes in with the Auto
   order button beside it, and the button is pressed. Then the order: the
   list of the parts running out fills in, line by line (how many are left,
   how many to order), Email to warehouse is pressed, and Sent to warehouse
   lands. The plot sits in the lower part of the chart box (--top), so the
   line's head room is free. */
.pt-part-measure .ms-stock { justify-content: flex-start; }
.pt-part-measure .ms-subs { position: relative; flex: 0 0 auto; display: grid; }
.pt-part-measure .ms-sub { grid-area: 1 / 1; min-width: 0; transition: opacity .3s ease, transform .55s var(--pt-spring); }
.pt-part-measure .ms-sub-fc { opacity: 0; transform: translateY(-.8em); }
.pt-part-measure.mb-chart .ms-sub-fc { opacity: 1; transform: none; }
.pt-part-measure.mb-chart .ms-sub-ord { opacity: 0; transform: translateY(.8em); }
/* The header: Belts and its note while the chart shows; Restock, and at
   the end the sage Sent to warehouse with a tick, for the order. */
.pt-part-measure .ms-t-b { opacity: 0; transform: translateY(.4em); }
.pt-part-measure.mb-chart .ms-t-a { opacity: 1; transform: none; }
.pt-part-measure:not(.mb-chart) .ms-pg-stock .ms-t-a { opacity: 0; transform: translateY(-.4em); }
.pt-part-measure:not(.mb-chart) .ms-pg-stock .ms-t-b { opacity: 1; transform: none; }
.pt-part-measure .ms-hd-r { display: grid; justify-items: end; align-items: center; }
.pt-part-measure .ms-hd-r > * { grid-area: 1 / 1; }
.pt-part-measure .ms-note-fc { transition: opacity .3s ease; }
.pt-part-measure:not(.mb-chart) .ms-note-fc { opacity: 0; }
.pt-part-measure .ms-sage { background: rgba(157, 184, 159, .17); color: var(--pt-sage); }
.pt-part-measure .ms-sent { opacity: 0; transform: scale(.55); transform-origin: 100% 50%; transition: opacity .25s ease, transform .55s var(--pt-spring); }
.pt-part-measure.pt-s2:not(.mb-chart) .ms-sent { opacity: 1; transform: none; }
.pt-part-measure .ms-tick { position: relative; flex: 0 0 auto; width: 1.05em; height: 1.05em; border-radius: 50%; background: currentColor; }
.pt-part-measure .ms-tick::after { content: ""; position: absolute; left: .37em; top: .19em; width: .27em; height: .5em;
  border: solid var(--pt-night); border-width: 0 .13em .13em 0; transform: rotate(45deg); }
/* The order: a part a row, what is left (clay, it is low) and what to order. */
.pt-part-measure .ms-ord { display: flex; flex-direction: column; }
.pt-part-measure .ms-or { display: grid; grid-template-columns: minmax(0, 1fr) 3.6em 4.6em; column-gap: .5em; align-items: center; height: 1.6em; padding: 0 .45em;
  box-shadow: inset 0 -1px 0 rgba(236, 230, 218, .05); }
.pt-part-measure .ms-or > span { font: 500 .86em/1.2 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-or > span + span { justify-self: end; font-weight: 600; font-variant-numeric: tabular-nums; }
.pt-part-measure .ms-or-h { height: 1.45em; }
.pt-part-measure .ms-or-h > span,
.pt-part-measure .ms-or-h > span + span { font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); }
.pt-part-measure .ms-or .ms-left { color: var(--pt-clay); }
.pt-part-measure .ms-or1,
.pt-part-measure .ms-or2,
.pt-part-measure .ms-or3,
.pt-part-measure .ms-or4 { transition: opacity .3s ease, transform .5s var(--pt-spring); }
.pt-part-measure.mb-chart .ms-or1,
.pt-part-measure.mb-chart .ms-or2,
.pt-part-measure.mb-chart .ms-or3,
.pt-part-measure.mb-chart .ms-or4 { opacity: 0; transform: translateY(-.6em); }
/* Line by line, each clearly after the one before; then Email to warehouse
   comes in under the list, is pressed as Auto order was, and the sage
   Sent to warehouse lands in the header. Times from the turn to the order. */
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-or1 { transition-delay: .35s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-or2 { transition-delay: .75s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-or3 { transition-delay: 1.15s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-or4 { transition-delay: 1.55s; }
.pt-part-measure .ms-mail { display: flex; justify-content: flex-end; margin-top: .55em; }
.pt-part-measure .ms-mail .ms-btn { opacity: 1; transform: none; transition: opacity .3s ease, transform .5s var(--pt-spring); }
.pt-part-measure.mb-chart .ms-mail .ms-btn { opacity: 0; transform: scale(.7); }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-mail .ms-btn { transition-delay: 2.05s; animation: ms-press .42s ease-out 2.6s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-mail .ms-tap { animation: ms-tap .6s ease-out 2.6s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-mail .ms-ring1 { animation: ms-ripple .9s ease-out 2.65s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-mail .ms-ring2 { animation: ms-ripple .9s ease-out 2.85s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-sent { transition-delay: 3.25s; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-sent::before { animation: ms-ring .7s ease-out 3.35s forwards; }
.pt-part-measure:not(.ms-quick)[data-step="2"]:not(.mb-chart) .ms-sent .ms-shine::after { animation: ms-shine .9s ease-in-out 3.5s; }
.pt-part-measure .ms-chart { position: relative; flex: 0 0 auto; height: var(--chart); }
.pt-part-measure .ms-area { position: absolute; left: 0; right: 0; bottom: 0; top: var(--top); }
.pt-part-measure .ms-grid { position: absolute; inset: 0; border-radius: .3em;
  background: repeating-linear-gradient(180deg, rgba(236, 230, 218, .05) 0 1px, rgba(236, 230, 218, 0) 1px 25%); }
.pt-part-measure .ms-min { position: absolute; left: 0; right: 0; top: var(--cy); height: 0; border-top: .14em dashed rgba(208, 154, 124, .8); }
.pt-part-measure .ms-min-t { position: absolute; right: 0; bottom: calc(100% - var(--cy) + .3em); font: 600 .8em/1.2 var(--pt-text); color: var(--pt-clay); white-space: nowrap; }
.pt-part-measure .ms-now { position: absolute; top: 0; bottom: 0; left: var(--nx); width: 0; border-left: .1em solid rgba(236, 230, 218, .18); }
.pt-part-measure .ms-plot { position: absolute; inset: 0; overflow: hidden; transform: translateX(-100%); transition: transform 1s cubic-bezier(.45, .05, .35, 1); }
.pt-part-measure .ms-plot-in { position: absolute; inset: 0; transform: translateX(100%); transition: transform 1s cubic-bezier(.45, .05, .35, 1); }
.pt-part-measure .ms-plot-f { left: var(--nx); }   /* its svg shows only the forecast's slice of the 120 units */
.pt-part-measure .ms-plot svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
.pt-part-measure .ms-line,
.pt-part-measure .ms-fc { fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.pt-part-measure .ms-line { stroke: var(--pt-mist); }
.pt-part-measure .ms-fc { stroke: var(--pt-sand); stroke-dasharray: 5 5; }
.pt-part-measure.pt-s2 .ms-plot,
.pt-part-measure.pt-s2 .ms-plot-in { transform: none; }
.pt-part-measure .ms-dot,
.pt-part-measure .ms-cross { position: absolute; width: .8em; height: .8em; margin: -.4em 0 0 -.4em; border-radius: 50%; }
/* This week's point, and the crossing: a red ring that pulses while the step plays. */
.pt-part-measure .ms-dot { left: var(--nx); top: var(--ny); background: var(--pt-mist); box-shadow: 0 0 0 .2em var(--pt-raised), 0 0 .7em rgba(147, 183, 198, .7);
  opacity: 0; transform: scale(.3); transition: opacity .25s ease, transform .45s var(--pt-spring); }
.pt-part-measure .ms-cross { left: var(--cx); top: var(--cy); background: #D67062; box-shadow: 0 0 0 .2em var(--pt-raised), 0 0 .8em rgba(214, 112, 98, .8);
  opacity: 0; transform: scale(.3); transition: opacity .25s ease, transform .5s var(--pt-spring); }
.pt-part-measure .ms-cross::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: .12em solid #D67062; opacity: 0; }
.pt-part-measure.pt-s2 .ms-dot,
.pt-part-measure.pt-s2 .ms-cross { opacity: 1; transform: none; }
.pt-part-measure[data-step="2"]:not(.ms-quick) .ms-cross::after { animation: ms-ring-o 1.4s ease-out 2.2s infinite; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-plot-h,
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-plot-h .ms-plot-in { transition-delay: .35s; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-dot { transition-delay: 1.3s; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-plot-f,
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-plot-f .ms-plot-in { transition-duration: .75s; transition-delay: 1.4s; }
.pt-part-measure:not(.ms-quick)[data-step="2"] .ms-cross { transition-delay: 2.1s; }
/* The weeks under it (each one's Tuesday): this one lit, the forecast ones in sand. */
.pt-part-measure .ms-axis { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); margin-top: .45em; }
.pt-part-measure .ms-axis span { text-align: center; font: 600 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-axis .ms-ax-now { color: var(--pt-bone); }
.pt-part-measure .ms-axis .ms-ax-f { color: var(--pt-sand); }

/* ---------- step 3, page map: plan your expansion ----------------------------------- */
/* Today's areas light up one by one, then the next one, worked out from the
   sales history and its prediction, glows in sand and keeps glowing; the
   chip names it and Db hops. Tiles as the suburbs lie, laid back in 3D. */
.pt-part-measure .ms-areas { justify-content: center; gap: .9em; perspective: 30em; perspective-origin: 50% 10%; }
/* Tiles of 5.1 x 2.6 em, .55 em apart, the second row set off by half a
   tile (19.25 em in all, inside a phone's 19.7 em page). */
.pt-part-measure .ms-map { position: relative; flex: 0 0 auto; width: 19.25em; height: 5.9em; margin: 0 auto; transform-style: preserve-3d; transform: rotateX(20deg); }
.pt-part-measure .ms-tile-m { position: absolute; width: 5.1em; height: 2.6em; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .1em;
  border-radius: .6em; background: rgba(236, 230, 218, .045); box-shadow: inset 0 0 0 1px rgba(236, 230, 218, .08); }
.pt-part-measure .ms-m1 { left: 0; top: 0; }
.pt-part-measure .ms-m2 { left: 5.65em; top: 0; }
.pt-part-measure .ms-m3 { left: 11.3em; top: 0; }
.pt-part-measure .ms-m4 { left: 2.83em; top: 3.3em; }
.pt-part-measure .ms-m5 { left: 8.48em; top: 3.3em; }
.pt-part-measure .ms-m6 { left: 14.13em; top: 3.3em; }
.pt-part-measure .ms-tile-m b { position: relative; font: 500 .84em/1.1 var(--pt-head); letter-spacing: .02em; color: rgba(167, 175, 164, .7); }
.pt-part-measure .ms-tile-m small { position: relative; font: 600 .8em/1.1 var(--pt-text); color: var(--pt-bone); white-space: nowrap; }
.pt-part-measure .ms-m-on b,
.pt-part-measure .ms-m-next b { color: var(--pt-bone); }
.pt-part-measure .ms-lit { position: absolute; inset: 0; border-radius: inherit; background: rgba(147, 183, 198, .18);
  box-shadow: inset 0 0 0 .1em rgba(147, 183, 198, .6); opacity: 0; transition: opacity .4s ease; }
.pt-part-measure.pt-s3 .ms-lit { opacity: 1; }
.pt-part-measure .ms-m-next .ms-lit { background: rgba(217, 197, 154, .22); box-shadow: inset 0 0 0 .1em rgba(217, 197, 154, .8), 0 .5em 1.3em rgba(217, 197, 154, .25); }
.pt-part-measure .ms-m-next small { color: var(--pt-sand); }
.pt-part-measure .ms-m-next { transition: transform .6s var(--pt-spring); }
.pt-part-measure.pt-s3 .ms-m-next { transform: translateZ(.7em); }
.pt-part-measure .ms-m-next::after { content: ""; position: absolute; inset: -.25em; border-radius: .8em; border: .12em solid var(--pt-sand); opacity: 0; pointer-events: none; }
/* After the card has settled (1.3 s): the areas, the next, the chip. */
.pt-part-measure[data-step="3"]:not(.ms-quick) .ms-m-next::after { animation: ms-ring-sq 1.6s ease-out 3s infinite; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m1 .ms-lit { transition-delay: 1.35s; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m2 .ms-lit { transition-delay: 1.5s; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m3 .ms-lit { transition-delay: 1.65s; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m4 .ms-lit { transition-delay: 1.8s; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m5 .ms-lit,
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-m-next { transition-delay: 2.4s; }
/* The chip names it. */
.pt-part-measure .ms-next { opacity: 0; transform: scale(.55); transform-origin: 100% 50%; transition: opacity .25s ease, transform .55s var(--pt-spring); }
.pt-part-measure.pt-s3 .ms-next { opacity: 1; transform: none; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-next { transition-delay: 2.8s; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-next::before { animation: ms-ring .7s ease-out 2.9s forwards; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-next .ms-shine::after { animation: ms-shine .9s ease-in-out 3.05s; }
/* The key. */
.pt-part-measure .ms-legend { display: flex; justify-content: center; gap: 1.2em; opacity: 0; transition: opacity .4s ease; }
.pt-part-measure.pt-s3 .ms-legend { opacity: 1; }
.pt-part-measure:not(.ms-quick)[data-step="3"] .ms-legend { transition-delay: 2.1s; }
.pt-part-measure .ms-lg { display: inline-flex; align-items: center; gap: .45em; font: 500 .8em/1.2 var(--pt-text); color: var(--pt-lichen); white-space: nowrap; }
.pt-part-measure .ms-lg i { width: .8em; height: .8em; border-radius: .25em; background: rgba(147, 183, 198, .3); box-shadow: inset 0 0 0 .12em rgba(147, 183, 198, .7); }
.pt-part-measure .ms-lg-next i { background: rgba(217, 197, 154, .3); box-shadow: inset 0 0 0 .12em rgba(217, 197, 154, .85); }

/* ---------- the rewind: the pages fade, the set stays ------------------------------- */
.pt-part-measure.is-rewind .ms-pages { opacity: 0; }

/* ---------- the steps under the scene ----------------------------------------------- */
/* Desktop: small floating pills in a compact wrap; the one in play is lit in
   mist, the layer's tone. */
.pt-part-measure .pt-part-steps { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 12px 0 0; padding: 0; list-style: none; }
.pt-part-measure .pt-part-steps li { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px 6px 9px; border-radius: 999px; background: rgba(236, 230, 218, .06); color: var(--pt-bone);
  font: 500 var(--pt-fs-say)/1.3 var(--pt-text); cursor: default;
  animation: ms-pill 6s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -1.2s); }
.pt-part-measure .pt-part-steps li::before { content: ""; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
  background: var(--tone, var(--pt-mist)); opacity: .45; transform: scale(.85); transition: opacity .3s ease, transform .4s var(--pt-spring); }
.pt-part-measure .pt-part-steps li::after { content: ""; position: absolute; z-index: -1; inset: 0; border-radius: inherit;
  background: radial-gradient(circle at 12.5px 50%, rgba(147, 183, 198, .55), rgba(147, 183, 198, 0) 15px), rgba(236, 230, 218, .07);
  opacity: 0; transition: opacity .35s ease; }
.pt-part-measure .pt-part-steps li > span { opacity: .7; transition: opacity .3s ease; }
.pt-part-measure .pt-part-steps li.is-on::before { opacity: 1; transform: scale(1.2); }
.pt-part-measure .pt-part-steps li.is-on::after,
.pt-part-measure .pt-part-steps li.is-on > span { opacity: 1; }
.pt-part-measure .pt-part-steps li:focus-visible { outline: 2px solid var(--pt-sand); outline-offset: 3px; }
@keyframes ms-pill { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* Nothing moves in a layer that is not the one in front (Db's own loops are
   paused by site.css). */
.pt-layer:not(.is-current) .pt-part-measure .ms-float,
.pt-layer:not(.is-current) .pt-part-measure .ms-set::after,
.pt-layer:not(.is-current) .pt-part-measure .ms-sweep i,
.pt-layer:not(.is-current) .pt-part-measure .ms-cross::after,
.pt-layer:not(.is-current) .pt-part-measure .ms-m-next::after,
.pt-layer:not(.is-current) .pt-part-measure .pt-part-steps li { animation-play-state: paused; }

/* ---------- the lg column (992 to 1199, 444 wide): the steps as dots -------------- */
@media (min-width: 992px) and (max-width: 1199.98px) {
  html.js .pt-part-measure .pt-part-steps { position: relative; flex-wrap: nowrap; justify-content: center; gap: 0; height: 50px; margin-top: 12px; }
  html.js .pt-part-measure .pt-part-steps li { position: static; isolation: auto; justify-content: center; align-items: flex-start;
    width: 22px; height: 14px; padding: 4px 0 0; background: none; animation: none; }
  html.js .pt-part-measure .pt-part-steps li::after { display: none; }
  html.js .pt-part-measure .pt-part-steps li.is-on::before { transform: scale(1.45); }
  html.js .pt-part-measure .pt-part-steps li > span { position: absolute; left: 0; right: 0; top: 21px; width: max-content; margin: 0 auto;
    padding: .4em 1em .45em; border-radius: 999px; background: rgba(236, 230, 218, .08); line-height: 1.3; white-space: nowrap;
    opacity: 0; transform: translateY(5px); pointer-events: none; transition: opacity .3s ease, transform .45s var(--pt-spring); }
  html.js .pt-part-measure .pt-part-steps li.is-on > span { opacity: 1; transform: none; pointer-events: auto; }
  html.js .pt-part-measure[data-step="-1"] .pt-part-steps li:first-child > span { opacity: .5; transform: none; }
}

/* ---------- phones ------------------------------------------------------------------- */
/* With the layer's copy above, a short phone has about 185 px for the scene
   and its caption line (measured: 213 at 360x640 to the arrow's clearance,
   230 at 375x667), so: Db small at the left, the panel the rest of the
   width, every page a little tighter. His line (step 2 only) sits over the
   chart's free head room, its tail towards him. The steps become one line:
   four dots and the caption of the one in play. */
@media (max-width: 575.98px) {
  .pt-part-measure .pt-part-stage { font-size: 12.5px; font-size: max(12.5px, min(13.6px, calc(100cqw / 25.6))); perspective: 820px; perspective-origin: 60% 45%; }
  .pt-part-measure .ms-set { width: 25.6em; height: 14em; --chart: 7.6em; --top: 44%; }
  .pt-part-measure .ms-set::before { background:
      radial-gradient(44% 34% at 62% 80%, rgba(147, 183, 198, .10), rgba(147, 183, 198, 0) 72%),
      radial-gradient(14% 20% at 7% 86%, rgba(217, 197, 154, .10), rgba(217, 197, 154, 0) 72%); }
  .pt-part-measure .ms-set::after { left: 5.4em; width: 19.6em; top: 13.1em; height: .9em; }
  .pt-part-measure .ms-db { left: 0; bottom: .4em; width: 3.6em; transform: translateZ(.8em); }
  .pt-part-measure .ms-db .pt-char { animation-name: ms-bob-sm; }
  .pt-part-measure .ms-float { left: 4.4em; top: .2em; width: 21.2em; height: 13.6em; }
  .pt-part-measure .ms-card { border-radius: .85em; transform: rotateY(-6deg) rotateX(2deg); }
  .pt-part-measure.pt-s3 .ms-c1 { transform: translate3d(-4.5em, .3em, -3em) rotateY(30deg) rotateX(2deg); }
  .pt-part-measure .ms-c2 { transform: translate3d(1.8em, 0, -2em) rotateY(-30deg) rotateX(2deg); }   /* near: a phone's edge is close */
  .pt-part-measure.pt-s3 .ms-c2 { transform: rotateY(-6deg) rotateX(2deg); }
  .pt-part-measure .ms-pages { inset: .62em .72em .45em; }
  .pt-part-measure .ms-hd { height: 1.95em; padding-bottom: .42em; margin-bottom: .2em; }
  .pt-part-measure .ms-note { margin-bottom: .3em; }
  .pt-part-measure .ms-row { column-gap: .45em; grid-template-columns: auto minmax(0, 1fr) 4.6em 1.7em; }
  .pt-part-measure .ms-v-month { height: 6em; }
  .pt-part-measure .ms-colbar { height: 3.2em; }
  .pt-part-measure .ms-job { gap: .55em; }
  .pt-part-measure .ms-tr { height: 1.55em; }
  .pt-part-measure .ms-tile { padding: .4em .55em .45em; }
  .pt-part-measure .ms-tile b { font-size: .98em; }
  .pt-part-measure .ms-areas { gap: .6em; }
  .pt-part-measure .ms-or { height: 1.5em; }
  .pt-part-measure .ms-or-h { height: 1.35em; }
  .pt-part-measure .ms-mail { margin-top: .45em; }
  /* His line and the button over the chart's head room, one line at the
     chart's right, the button just left of the line (.55 em, 7 px, apart),
     in front of the panel: the one deliberate overlap, while the chart
     shows. Both go as the order comes in (the list needs the room). */
  /* The head room is the chart's top 44% (3.3 em); the line sits in its
     middle, the bubble's tail to the left, towards the button and Db. */
  .pt-part-measure .ms-say { left: auto; right: .75em; top: 3.68em; width: 12.4em; transform: translateZ(1.6em); }
  .pt-part-measure .ms-say .pt-bubble { padding: .5em .8em .52em; border-radius: 1.2em; transform-origin: 0 50%; }
  .pt-part-measure .ms-say .pt-bubble::before { left: -6px; bottom: calc(50% - 6px); clip-path: polygon(0 0, 0 100%, 100% 100%); }
  .pt-part-measure .ms-auto { left: auto; right: 13.7em; top: 3.7em; transform: translateZ(1.6em); }
  .pt-part-measure[data-step="2"]:not(.mb-chart) .ms-say,
  .pt-part-measure[data-step="2"]:not(.mb-chart) .ms-auto { opacity: 0; transition-delay: 0s; }
}
@keyframes ms-bob-sm { 0%, 100% { translate: 0 0; } 50% { translate: 0 -4px; } }
@media (max-width: 575.98px) {
  html.js .pt-part-measure .pt-part-steps { position: relative; flex-wrap: nowrap; justify-content: flex-start; gap: 0; height: 22px; margin-top: 6px; }
  html.js .pt-part-measure .pt-part-steps li { position: static; isolation: auto; flex: 0 0 15px; justify-content: center; width: 15px; height: 22px; padding: 0;
    background: none; animation: none; }
  html.js .pt-part-measure .pt-part-steps li::after { display: none; }
  html.js .pt-part-measure .pt-part-steps li::before { width: 6px; height: 6px; }
  html.js .pt-part-measure .pt-part-steps li.is-on::before { transform: scale(1.5); }
  html.js .pt-part-measure .pt-part-steps li > span { position: absolute; left: 66px; top: 0; font-size: calc(var(--pt-fs-say) - 1px); line-height: 22px; white-space: nowrap;
    opacity: 0; transform: translateY(6px); pointer-events: none; transition: opacity .3s ease, transform .45s var(--pt-spring); }
  html.js .pt-part-measure .pt-part-steps li.is-on > span { opacity: 1; transform: none; pointer-events: auto; }
  html.js .pt-part-measure[data-step="-1"] .pt-part-steps li:first-child > span { opacity: .5; transform: none; }
}

/* ---------- instant draws (measure.js) ----------------------------------------------- */
/* A jump to a step (a hover, a tap, the test hook) glides there quickly with
   no delays; the reset snaps. Last, to win the ties. */
.pt-part-measure.ms-quick .ms-mv { transition-duration: .3s; transition-delay: 0s; animation: none; }
.pt-part-measure.ms-quick .ms-mv > *,
.pt-part-measure.ms-quick .ms-mv::before,
.pt-part-measure.ms-quick .ms-mv::after { transition-delay: 0s; animation: none; }
.pt-part-measure.ms-quick .ms-say,
.pt-part-measure.ms-quick .ms-say .pt-bubble,
.pt-part-measure.ms-quick .ms-auto { transition-delay: 0s; animation: none; }
.pt-part-measure.ms-snap .ms-mv,
.pt-part-measure.ms-snap .ms-mv *,
.pt-part-measure.ms-snap .ms-mv::before,
.pt-part-measure.ms-snap .ms-mv::after,
.pt-part-measure.ms-snap .ms-say,
.pt-part-measure.ms-snap .ms-say .pt-bubble,
.pt-part-measure.ms-snap .ms-auto { transition: none; animation: none; }
