/*
 * Roca Professionals, public site: animated scenes A. Templates: scene-wrench.php (plumbers), scene-plan.php
 * (designers), scene-receipt.php (shop staff). Line drawings on the tokens, animated by CSS only (the CSP
 * forbids inline styles and scripts). Rules for every scene here:
 * - all parts of one scene share its cycle length, so the pause off screen (rp-motion.css) keeps them in sync;
 * - no animation-delay: timing lives in keyframe percentages;
 * - keyframe 100% is the finished picture and 0% equals it, so the loop has no jump and
 *   prefers-reduced-motion (1 ms, one run, fill both) stops on a complete drawing.
 */

/* ---- Wrench: a union nut on a pipe is tightened in two strokes, the leak stops, +10 points ----------- */

.rp-scene--wrench .sw-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rp-scene--wrench .sw-hair {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-linecap: round;
}

.rp-scene--wrench .sw-thin {
  fill: none;
  stroke: var(--rp-muted);
  stroke-width: 1;
}

.rp-scene--wrench .sw-fill {
  fill: var(--rp-surface);
}

.rp-scene--wrench .sw-floor {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.rp-scene--wrench .sw-drop {
  fill: var(--rp-accent);
  transform-box: fill-box;
  transform-origin: 50% 0;
}

.rp-scene--wrench .sw-ripple {
  fill: none;
  stroke: var(--rp-accent);
  stroke-width: 1.25;
  transform-box: fill-box;
  transform-origin: center;
}

.rp-scene--wrench .sw-points__num {
  font-family: var(--rp-font);
  font-size: 22px;
  font-weight: var(--rp-fw-medium);
  letter-spacing: -0.02em;
  fill: var(--rp-accent);
}

.rp-scene--wrench .sw-points__unit {
  font-family: var(--rp-font);
  font-size: 10px;
  fill: var(--rp-muted);
}

/* The nut turns about its centre; the wrench about the same point, the origin of its translated group. */
.rp-scene--wrench .sw-nut {
  transform-box: fill-box;
  transform-origin: center;
  animation: rp-sw-nut 5.6s ease-in-out infinite both;
}

.rp-scene--wrench .sw-wrench {
  transform-box: view-box;
  transform-origin: 0 0;
  animation: rp-sw-wrench 5.6s ease-in-out infinite both;
}

.rp-scene--wrench .sw-drop--a { animation: rp-sw-drop-a 5.6s linear infinite both; }
.rp-scene--wrench .sw-drop--b { animation: rp-sw-drop-b 5.6s linear infinite both; }
.rp-scene--wrench .sw-ripple--a { animation: rp-sw-ripple-a 5.6s ease-out infinite both; }
.rp-scene--wrench .sw-ripple--b { animation: rp-sw-ripple-b 5.6s ease-out infinite both; }
.rp-scene--wrench .sw-points { animation: rp-sw-points 5.6s var(--rp-ease) infinite both; }

/* Two strokes of 30 degrees with a 60 degree swing back between them: the nut ends 60 degrees on,
   which looks the same as its start, so the loop closes. */
@keyframes rp-sw-nut {
  0%, 10% { transform: rotate(0deg); }
  24%, 46% { transform: rotate(30deg); }
  60%, 100% { transform: rotate(60deg); }
}

@keyframes rp-sw-wrench {
  0%, 10% { transform: rotate(-60deg); }
  24%, 28% { transform: rotate(-30deg); }
  34% { transform: rotate(-60deg) scale(1.025); }
  40%, 46% { transform: rotate(-90deg); }
  60%, 100% { transform: rotate(-60deg); }
}

/* A drop grows under the nut, falls with gravity (ease-in) and leaves a ripple; none after tightening. */
@keyframes rp-sw-drop-a {
  0% { opacity: 0; transform: translateY(0) scale(0.2); }
  1% { opacity: 1; }
  9% { transform: translateY(0) scale(1); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
  15% { opacity: 1; transform: translateY(41px) scale(1); }
  15.5%, 100% { opacity: 0; transform: translateY(42px) scale(1); }
}

@keyframes rp-sw-drop-b {
  0%, 31% { opacity: 0; transform: translateY(0) scale(0.2); }
  32% { opacity: 1; }
  43% { transform: translateY(0) scale(1); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
  49% { opacity: 1; transform: translateY(41px) scale(1); }
  49.5%, 100% { opacity: 0; transform: translateY(42px) scale(1); }
}

@keyframes rp-sw-ripple-a {
  0%, 15% { opacity: 0; transform: scale(0.3); }
  15.5% { opacity: 1; }
  23%, 100% { opacity: 0; transform: scale(1.35); }
}

@keyframes rp-sw-ripple-b {
  0%, 49% { opacity: 0; transform: scale(0.3); }
  49.5% { opacity: 1; }
  57%, 100% { opacity: 0; transform: scale(1.35); }
}

/* +10 rises once the nut is tight, stays to the end of the cycle and fades as the next one starts. */
@keyframes rp-sw-points {
  0% { opacity: 1; transform: translateY(-4px); }
  5% { opacity: 0; transform: translateY(-10px); }
  62% { opacity: 0; transform: translateY(8px); }
  71% { opacity: 1; transform: translateY(0); }
  100% { opacity: 1; transform: translateY(-4px); }
}

/* ---- Plan: walls of a bathroom drawn on tracing paper, fixtures, the 2 400 dimension, approval ------- */

.rp-scene--plan .sp-sheet {
  fill: var(--rp-surface);
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-linejoin: round;
}

.rp-scene--plan .sp-grid {
  fill: none;
  stroke: var(--rp-line);
  stroke-width: 0.5;
}

.rp-scene--plan .sp-grid--major {
  stroke: var(--rp-line-strong);
}

.rp-scene--plan .sp-fold {
  fill: var(--rp-stone);
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-linejoin: round;
}

.rp-scene--plan .sp-label {
  font-family: var(--rp-font);
  font-size: 9.5px;
  fill: var(--rp-muted);
}

.rp-scene--plan .sp-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rp-scene--plan .sp-thin {
  fill: none;
  stroke: var(--rp-muted);
  stroke-width: 1;
  stroke-linecap: round;
}

.rp-scene--plan .sp-paper {
  fill: var(--rp-surface);
}

.rp-scene--plan .sp-stone {
  fill: var(--rp-stone);
}

.rp-scene--plan .sp-lead {
  fill: currentColor;
}

/* A wall is one centre line stroked twice: ink 9.5 wide, stone 6.5 on top, so two 1.5 lines with the wall
   between them draw together and the pencil can follow a single path. */
.rp-scene--plan .sp-wall {
  fill: none;
  stroke-linecap: butt;
  stroke-linejoin: miter;
  stroke-dasharray: 1 1;
  animation: rp-sp-walls 8s linear infinite both;
}

.rp-scene--plan .sp-wall--edge {
  stroke: currentColor;
  stroke-width: 9.5;
}

.rp-scene--plan .sp-wall--core {
  stroke: var(--rp-stone);
  stroke-width: 6.5;
}

.rp-scene--plan .sp-jamb {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}

.rp-scene--plan .sp-door-leaf {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 1 1;
}

.rp-scene--plan .sp-door-arc {
  fill: none;
  stroke: var(--rp-muted);
  stroke-width: 1;
  stroke-dasharray: 1 1;
}

.rp-scene--plan .sp-dim__ext {
  fill: none;
  stroke: var(--rp-muted);
  stroke-width: 1;
  stroke-linecap: round;
}

.rp-scene--plan .sp-dim__line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-dasharray: 1 1;
}

.rp-scene--plan .sp-dim__text {
  font-family: var(--rp-font-mono);
  font-size: 10px;
  fill: currentColor;
}

.rp-scene--plan .sp-chip__box {
  fill: var(--rp-surface);
  stroke: var(--rp-accent);
  stroke-width: 1.25;
}

.rp-scene--plan .sp-chip__tick {
  fill: none;
  stroke: var(--rp-accent);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rp-scene--plan .sp-chip__text {
  font-family: var(--rp-font);
  font-size: 10px;
  font-weight: var(--rp-fw-medium);
  fill: var(--rp-accent);
}

.rp-scene--plan .sp-fix {
  transform-box: fill-box;
  transform-origin: center;
}

.rp-scene--plan .sp-layer { animation: rp-sp-layer 8s ease-in-out infinite both; }
.rp-scene--plan .sp-jamb--a { animation: rp-sp-jamb-a 8s linear infinite both; }
.rp-scene--plan .sp-jamb--b { animation: rp-sp-jamb-b 8s linear infinite both; }
.rp-scene--plan .sp-window { animation: rp-sp-window 8s ease-in-out infinite both; }
.rp-scene--plan .sp-door-leaf { animation: rp-sp-door-leaf 8s ease-in-out infinite both; }
.rp-scene--plan .sp-door-arc { animation: rp-sp-door-arc 8s ease-in-out infinite both; }
.rp-scene--plan .sp-fix--tub { animation: rp-sp-tub 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-fix--basin { animation: rp-sp-basin 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-fix--wc { animation: rp-sp-wc 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-fix--shower { animation: rp-sp-shower 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-dim__ext { animation: rp-sp-dim-ext 8s ease-in-out infinite both; }
.rp-scene--plan .sp-dim__line { animation: rp-sp-dim-line 8s linear infinite both; }
.rp-scene--plan .sp-dim__text { animation: rp-sp-dim-text 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-chip { animation: rp-sp-chip 8s var(--rp-ease) infinite both; }
.rp-scene--plan .sp-pencil { animation: rp-sp-pencil 8s ease-in-out infinite both; }

/* The finished plan fades out at the start of a cycle; everything resets while the layer is invisible. */
@keyframes rp-sp-layer {
  0% { opacity: 1; }
  4%, 5% { opacity: 0; }
  6%, 100% { opacity: 1; }
}

/* Walls 8-40 %: the pencil keyframes below hit the corners at the same share of the path length. */
@keyframes rp-sp-walls {
  0%, 4.9% { stroke-dashoffset: 0; }
  5%, 8% { stroke-dashoffset: 1; }
  40%, 100% { stroke-dashoffset: 0; }
}

@keyframes rp-sp-jamb-a {
  0%, 4.9% { opacity: 1; }
  5%, 8% { opacity: 0; }
  9%, 100% { opacity: 1; }
}

@keyframes rp-sp-jamb-b {
  0%, 4.9% { opacity: 1; }
  5%, 39.5% { opacity: 0; }
  40.5%, 100% { opacity: 1; }
}

@keyframes rp-sp-window {
  0%, 4.9% { opacity: 1; }
  5%, 40% { opacity: 0; }
  44%, 100% { opacity: 1; }
}

@keyframes rp-sp-door-leaf {
  0%, 4.9% { stroke-dashoffset: 0; }
  5%, 40% { stroke-dashoffset: 1; }
  43%, 100% { stroke-dashoffset: 0; }
}

@keyframes rp-sp-door-arc {
  0%, 4.9% { stroke-dashoffset: 0; }
  5%, 42% { stroke-dashoffset: 1; }
  47%, 100% { stroke-dashoffset: 0; }
}

@keyframes rp-sp-tub {
  0%, 4.9% { opacity: 1; transform: scale(1); }
  5%, 44% { opacity: 0; transform: scale(0.94); }
  50%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes rp-sp-basin {
  0%, 4.9% { opacity: 1; transform: scale(1); }
  5%, 48% { opacity: 0; transform: scale(0.9); }
  54%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes rp-sp-wc {
  0%, 4.9% { opacity: 1; transform: scale(1); }
  5%, 52% { opacity: 0; transform: scale(0.9); }
  58%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes rp-sp-shower {
  0%, 4.9% { opacity: 1; transform: scale(1); }
  5%, 56% { opacity: 0; transform: scale(0.94); }
  62%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes rp-sp-dim-ext {
  0%, 4.9% { opacity: 1; }
  5%, 59% { opacity: 0; }
  62%, 100% { opacity: 1; }
}

@keyframes rp-sp-dim-line {
  0%, 4.9% { stroke-dashoffset: 0; }
  5%, 62% { stroke-dashoffset: 1; }
  72%, 100% { stroke-dashoffset: 0; }
}

@keyframes rp-sp-dim-text {
  0%, 4.9% { opacity: 1; transform: translateY(0); }
  5%, 72% { opacity: 0; transform: translateY(3px); }
  77%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes rp-sp-chip {
  0%, 4.9% { opacity: 1; transform: translateY(0); }
  5%, 78% { opacity: 0; transform: translateY(5px); }
  85%, 100% { opacity: 1; transform: translateY(0); }
}

/* The pencil tip is the group origin: it follows the wall centre line, then the dimension line. */
@keyframes rp-sp-pencil {
  0% { opacity: 0; transform: translate(282px, 226px); }
  5% { opacity: 0; transform: translate(196px, 226px); }
  8% { opacity: 1; transform: translate(160px, 196px); animation-timing-function: linear; }
  13.06% { transform: translate(60px, 196px); animation-timing-function: linear; }
  20.35% { transform: translate(60px, 52px); animation-timing-function: linear; }
  30.5% { transform: translate(260px, 52px); animation-timing-function: linear; }
  37.76% { transform: translate(260px, 196px); animation-timing-function: linear; }
  40%, 44% { transform: translate(216px, 196px); }
  60% { transform: translate(64.75px, 217px); }
  62% { transform: translate(64.75px, 217px); animation-timing-function: linear; }
  72% { opacity: 1; transform: translate(255.25px, 217px); }
  78%, 100% { opacity: 0; transform: translate(282px, 226px); }
}

/* ---- Receipt: a terminal prints a receipt, a stamp lands, the quarter goal fills ------------------- */

.rp-scene--receipt .sr-sheet {
  fill: var(--rp-surface);
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-linejoin: round;
}

.rp-scene--receipt .sr-text {
  font-family: var(--rp-font);
  font-size: 9.5px;
  fill: currentColor;
}

.rp-scene--receipt .sr-strong {
  font-weight: var(--rp-fw-strong);
}

.rp-scene--receipt .sr-mono {
  font-family: var(--rp-font-mono);
  font-size: 9px;
}

.rp-scene--receipt .sr-muted {
  fill: var(--rp-muted);
}

.rp-scene--receipt .sr-ink {
  fill: currentColor;
}

.rp-scene--receipt .sr-total {
  font-size: 10px;
  font-weight: var(--rp-fw-medium);
  fill: currentColor;
}

.rp-scene--receipt .sr-rule {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-dasharray: 2 2.5;
}

.rp-scene--receipt .sr-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rp-scene--receipt .sr-hair {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 1;
  stroke-linecap: round;
}

.rp-scene--receipt .sr-fill {
  fill: var(--rp-surface);
}

.rp-scene--receipt .sr-stone {
  fill: var(--rp-stone);
}

.rp-scene--receipt .sr-slot {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
}

.rp-scene--receipt .sr-base {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.rp-scene--receipt .sr-led {
  fill: var(--rp-accent);
}

.rp-scene--receipt .sr-stamp__ring {
  fill: none;
  stroke: var(--rp-accent);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rp-scene--receipt .sr-stamp__inner {
  fill: none;
  stroke: var(--rp-accent);
  stroke-width: 0.9;
}

.rp-scene--receipt .sr-stamp__text {
  font-family: var(--rp-font);
  font-size: 9.5px;
  font-weight: var(--rp-fw-strong);
  letter-spacing: 0.03em;
  fill: var(--rp-accent);
}

.rp-scene--receipt .sr-caption {
  font-family: var(--rp-font);
  font-size: 9.5px;
  fill: var(--rp-muted);
}

.rp-scene--receipt .sr-goal__label--done {
  fill: var(--rp-accent);
}

/* Ticks are dashes of a 9 wide stroke. The new ones use the pattern "gap 100, 14 ticks": moving the
   offset from 184 to 100 in 14 steps uncovers one tick per step, from the left, without sliding. */
.rp-scene--receipt .sr-ticks {
  fill: none;
  stroke: var(--rp-line-strong);
  stroke-width: 9;
  stroke-linecap: butt;
}

.rp-scene--receipt .sr-ticks--done,
.rp-scene--receipt .sr-ticks--new {
  stroke: var(--rp-accent);
}

.rp-scene--receipt .sr-goal__mark {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
}

.rp-scene--receipt .sr-stamp {
  transform-box: fill-box;
  transform-origin: center;
}

.rp-scene--receipt .sr-paper { animation: rp-sr-paper 6.5s ease-in-out infinite both; }
.rp-scene--receipt .sr-stamp { animation: rp-sr-stamp 6.5s ease-in-out infinite both; }
.rp-scene--receipt .sr-led { animation: rp-sr-led 6.5s ease-in-out infinite both; }
.rp-scene--receipt .sr-ticks-new { animation: rp-sr-ticks-new 6.5s ease-in-out infinite both; }
.rp-scene--receipt .sr-ticks--new { animation: rp-sr-ticks 6.5s linear infinite both; }
.rp-scene--receipt .sr-goal__label { animation: rp-sr-goal-todo 6.5s ease-in-out infinite both; }
.rp-scene--receipt .sr-goal__label--done { animation-name: rp-sr-goal-done; }

/* The printed receipt is torn off upwards, then the next one feeds out of the slot (9-40 %). */
@keyframes rp-sr-paper {
  0% { opacity: 1; transform: translateY(0); }
  5% { opacity: 0; transform: translateY(-16px); }
  5.5% { opacity: 0; transform: translateY(154px); }
  6%, 9% { opacity: 1; transform: translateY(154px); }
  40%, 100% { opacity: 1; transform: translateY(0); }
}

/* The stamp comes down from above (scale 1.45 to 1, ease-in) and stays. */
@keyframes rp-sr-stamp {
  0%, 5.9% { opacity: 1; transform: scale(1); }
  6%, 44% { opacity: 0; transform: scale(1.45); animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
  46.5% { opacity: 0.9; }
  49%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes rp-sr-led {
  0%, 9% { opacity: 0.25; }
  12% { opacity: 1; }
  19% { opacity: 0.25; }
  23% { opacity: 1; }
  30% { opacity: 0.25; }
  34% { opacity: 1; }
  41%, 100% { opacity: 0.25; }
}

@keyframes rp-sr-ticks-new {
  0% { opacity: 1; }
  4%, 5% { opacity: 0; }
  6%, 100% { opacity: 1; }
}

@keyframes rp-sr-ticks {
  0%, 4.9% { stroke-dashoffset: 100; }
  5%, 54% { stroke-dashoffset: 184; animation-timing-function: steps(14, end); }
  72%, 100% { stroke-dashoffset: 100; }
}

@keyframes rp-sr-goal-todo {
  0% { opacity: 0; }
  4%, 72% { opacity: 1; }
  76%, 100% { opacity: 0; }
}

@keyframes rp-sr-goal-done {
  0% { opacity: 1; }
  4%, 72% { opacity: 0; }
  76%, 100% { opacity: 1; }
}
