/*
 * Roca Professionals, public site: animated scenes, set B. Partners (scene-network), levels (scene-levels),
 * learning (scene-cert); markup in src/Site/templates/scene-*.php.
 * Base styles are the finished picture; keyframes move away from it and back. So with prefers-reduced-motion
 * (rp-base.css cuts animations to 1 ms) every scene stays on a complete frame. Staggering uses negative delays
 * only: a positive delay would hold a half-built frame under reduced motion.
 * Cycle lengths are written in seconds here on purpose (scene timing, not UI timing).
 */

/* ==== scene-network: company in the middle, staff on two tilted orbits ======================== */

/* The orbit plane is squashed to 50% in the markup; nodes and dots undo it (rotate back, scale 1 2). */
.rp-scene--network svg * {
  transform-box: view-box;
  transform-origin: 0 0;
}

.rp-scene--network .rn-spin--in { --rn-period: 48s; --rn-reach: 68px; }
.rp-scene--network .rn-spin--out { --rn-period: 72s; --rn-reach: 118px; }

/* --rn-shift: place of the node in the 9 s story; --rn-phase: its start angle on the orbit (for depth). */
.rp-scene--network .rn-n1 { --rn-shift: -9s; --rn-phase: -62s; }
.rp-scene--network .rn-n2 { --rn-shift: -8.45s; --rn-phase: -1.333s; }
.rp-scene--network .rn-n3 { --rn-shift: -7.9s; --rn-phase: -14s; }
.rp-scene--network .rn-n4 { --rn-shift: -7.35s; --rn-phase: -17.333s; }
.rp-scene--network .rn-n5 { --rn-shift: -6.8s; --rn-phase: -38s; }
.rp-scene--network .rn-n6 { --rn-shift: -6.25s; --rn-phase: -33.333s; }

.rp-scene--network .rn-ground {
  fill: var(--rp-stone);
}

.rp-scene--network .rn-orbit {
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
}

.rp-scene--network .rn-orbit--outer {
  stroke-dasharray: 2 6;
}

.rp-scene--network .rn-spin {
  animation: rn-spin var(--rn-period) linear infinite;
}

.rp-scene--network .rn-unspin {
  animation: rn-unspin var(--rn-period) linear infinite;
}

.rp-scene--network .rn-link {
  stroke: var(--rp-muted);
  stroke-width: 1.5;
  animation: rn-link 9s ease-in-out var(--rn-shift) infinite;
}

.rp-scene--network .rn-flow {
  transform: translateX(var(--rn-reach));
  animation: rn-flow 9s ease-in-out var(--rn-shift) infinite;
}

.rp-scene--network .rn-dot {
  fill: var(--rp-accent);
  opacity: 0;
  animation: rn-dot 9s ease-in-out var(--rn-shift) infinite;
}

.rp-scene--network .rn-depth {
  animation: rn-depth var(--rn-period) ease-in-out var(--rn-phase) infinite;
}

.rp-scene--network .rn-node {
  fill: var(--rp-surface);
  stroke: var(--rp-ink);
  stroke-width: 1.5;
}

.rp-scene--network .rn-initials {
  fill: var(--rp-ink);
  font-family: var(--rp-font);
  font-size: 10px;
  font-weight: var(--rp-fw-medium);
  letter-spacing: .02em;
  text-anchor: middle;
}

.rp-scene--network .rn-ping {
  stroke: var(--rp-accent);
  stroke-width: 1.5;
  opacity: 0;
  animation: rn-ping 9s ease-out var(--rn-shift) infinite;
}

.rp-scene--network .rn-badge {
  animation: rn-badge 9s ease-in-out var(--rn-shift) infinite;
}

.rp-scene--network .rn-badge__tail {
  fill: var(--rp-accent);
}

.rp-scene--network .rn-badge__disc {
  fill: var(--rp-accent);
  stroke: var(--rp-surface);
  stroke-width: 1.5;
}

.rp-scene--network .rn-badge__core {
  stroke: var(--rp-surface);
  stroke-width: 1.2;
}

.rp-scene--network .rn-face,
.rp-scene--network .rn-top {
  fill: var(--rp-surface);
  stroke: var(--rp-ink);
  stroke-width: 1.5;
}

.rp-scene--network .rn-side {
  fill: var(--rp-stone);
  stroke: var(--rp-ink);
  stroke-width: 1.5;
}

.rp-scene--network .rn-window {
  stroke: var(--rp-muted);
  stroke-width: 1.5;
}

.rp-scene--network .rn-door {
  stroke: var(--rp-ink);
  stroke-width: 1.5;
}

@keyframes rn-spin { to { transform: rotate(360deg); } }
@keyframes rn-unspin { to { transform: rotate(-360deg); } }

/* Depth: biggest at the front of the orbit (0%), smallest at the back (50%). */
@keyframes rn-depth {
  0%, 100% { transform: scale(1.08); }
  50% { transform: scale(.88); }
}

/* Link: drawn from the company out, kept, faded before the next round. */
@keyframes rn-link {
  0%, 3% { transform: scaleX(0); opacity: 1; animation-timing-function: var(--rp-ease); }
  12% { transform: scaleX(1); opacity: 1; }
  82% { transform: scaleX(1); opacity: 1; }
  90% { transform: scaleX(1); opacity: 0; }
  91%, 100% { transform: scaleX(0); opacity: 0; }
}

/* Three data runs per round along the link: travel here, visibility in rn-dot. */
@keyframes rn-flow {
  0%, 12.2% { transform: translateX(18px); }
  23.3% { transform: translateX(var(--rn-reach)); }
  23.4%, 36.7% { transform: translateX(18px); }
  47.8% { transform: translateX(var(--rn-reach)); }
  47.9%, 61.1% { transform: translateX(18px); }
  72.2% { transform: translateX(var(--rn-reach)); }
  72.3%, 100% { transform: translateX(18px); }
}

@keyframes rn-dot {
  0%, 12.2% { opacity: 0; }
  14%, 21.5% { opacity: 1; }
  23.3%, 36.7% { opacity: 0; }
  38.5%, 46% { opacity: 1; }
  47.8%, 61.1% { opacity: 0; }
  62.9%, 70.4% { opacity: 1; }
  72.2%, 100% { opacity: 0; }
}

/* A quiet ring on the node when a run arrives. */
@keyframes rn-ping {
  0%, 23.2% { transform: scale(1); opacity: 0; }
  23.3% { transform: scale(1); opacity: .5; }
  31% { transform: scale(1.45); opacity: 0; }
  31.1%, 47.7% { transform: scale(1); opacity: 0; }
  47.8% { transform: scale(1); opacity: .5; }
  55.5% { transform: scale(1.45); opacity: 0; }
  55.6%, 72.1% { transform: scale(1); opacity: 0; }
  72.2% { transform: scale(1); opacity: .5; }
  80% { transform: scale(1.45); opacity: 0; }
  80.1%, 100% { transform: scale(1); opacity: 0; }
}

/* Certificate mark: appears with the second run, leaves with the link. */
@keyframes rn-badge {
  0%, 47.8% { transform: scale(.3); opacity: 0; animation-timing-function: var(--rp-ease); }
  54% { transform: scale(1); opacity: 1; }
  82% { transform: scale(1); opacity: 1; }
  89% { transform: scale(.6); opacity: 0; }
  100% { transform: scale(.3); opacity: 0; }
}

/* ==== scene-levels: a glass scale fills with water, level badges light up ===================== */

.rp-scene--levels svg * {
  transform-box: view-box;
  transform-origin: 0 0;
}

.rp-scene--levels .rl-floor {
  fill: var(--rp-stone);
}

.rp-scene--levels .rl-inner,
.rp-scene--levels .rl-tick,
.rp-scene--levels .rl-mark {
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-flask,
.rp-scene--levels .rl-rim {
  stroke: var(--rp-ink);
  stroke-width: 1.75;
}

/* Water: the group carries the level, the two waves slide under it at different speeds. */
.rp-scene--levels .rl-water {
  transform: translateY(100px);
  animation: rl-fill 6.5s ease-in-out infinite;
}

.rp-scene--levels .rl-wave {
  fill: var(--rp-accent);
}

.rp-scene--levels .rl-wave--back {
  opacity: .32;
  animation: rl-wave-left 2.9s linear infinite;
}

.rp-scene--levels .rl-wave--front {
  transform: translateX(-34px);
  animation: rl-wave-right 2.1s linear infinite;
}

.rp-scene--levels .rl-bubble {
  stroke: var(--rp-surface);
  stroke-width: 1;
  opacity: 0;
  animation: rl-bubble 2.6s ease-in infinite;
}

.rp-scene--levels .rl-bubble--2 { animation-duration: 3.3s; animation-delay: -1.4s; }
.rp-scene--levels .rl-bubble--3 { animation-duration: 2.9s; animation-delay: -2.2s; }

.rp-scene--levels .rl-shine {
  stroke: var(--rp-surface);
  stroke-width: 2;
  opacity: .4;
}

.rp-scene--levels .rl-lead {
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
  stroke-dasharray: 0 4.5;
}

.rp-scene--levels .rl-lead-on {
  stroke: var(--rp-accent);
  stroke-width: 1.5;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 0;
}

.rp-scene--levels .rl-knot {
  fill: var(--rp-surface);
  stroke: var(--rp-muted);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-knot-on {
  fill: var(--rp-accent);
  stroke: var(--rp-accent);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-badge {
  fill: var(--rp-surface);
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-badge__ring {
  stroke: var(--rp-line-strong);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-badge__text,
.rp-scene--levels .rl-on__text {
  fill: var(--rp-muted);
  font-family: var(--rp-font);
  font-size: 11px;
  font-weight: var(--rp-fw-medium);
}

.rp-scene--levels .rl-badge__sub,
.rp-scene--levels .rl-on__sub {
  font-weight: var(--rp-fw-regular);
}

.rp-scene--levels .rl-badge-on {
  fill: var(--rp-accent);
  stroke: var(--rp-accent);
  stroke-width: 1.5;
}

.rp-scene--levels .rl-on__ring {
  stroke: var(--rp-surface);
  stroke-width: 1.5;
  opacity: .5;
}

.rp-scene--levels .rl-on__check {
  stroke: var(--rp-surface);
  stroke-width: 1.75;
}

.rp-scene--levels .rl-on__text {
  fill: var(--rp-surface);
}

.rp-scene--levels .rl-on__sub {
  opacity: .8;
}

.rp-scene--levels .rl-glint {
  fill: var(--rp-surface);
  opacity: 0;
  animation: rl-glint 6.5s ease-in-out infinite;
}

/* Level 3 is the reward level: the dark grey instead of the accent. */
.rp-scene--levels .rl-level--3 .rl-badge-on,
.rp-scene--levels .rl-level--3 .rl-knot-on {
  fill: var(--rp-ink-2);
  stroke: var(--rp-ink-2);
}

.rp-scene--levels .rl-level--3 .rl-lead-on {
  stroke: var(--rp-ink-2);
}

/* Each level switches on when the water passes its mark and off on the way down (crossings of rl-fill). */
.rp-scene--levels .rl-level--1 .rl-on { animation: rl-on-1 6.5s ease-in-out infinite; }
.rp-scene--levels .rl-level--2 .rl-on { animation: rl-on-2 6.5s ease-in-out infinite; }
.rp-scene--levels .rl-level--3 .rl-on { opacity: 0; animation: rl-on-3 6.5s ease-in-out infinite; }
.rp-scene--levels .rl-level--1 .rl-lead-on { animation: rl-lead-1 6.5s ease-in-out infinite; }
.rp-scene--levels .rl-level--2 .rl-lead-on { animation: rl-lead-2 6.5s ease-in-out infinite; }
.rp-scene--levels .rl-level--3 .rl-lead-on { stroke-dashoffset: 1; animation: rl-lead-3 6.5s ease-in-out infinite; }

@keyframes rl-fill {
  0%, 6% { transform: translateY(198px); }
  46%, 66% { transform: translateY(52px); }
  92%, 100% { transform: translateY(198px); }
}

@keyframes rl-wave-left { from { transform: translateX(0); } to { transform: translateX(-34px); } }
@keyframes rl-wave-right { from { transform: translateX(-34px); } to { transform: translateX(0); } }

@keyframes rl-bubble {
  0% { transform: translateY(78px); opacity: 0; }
  20% { opacity: .75; }
  85% { opacity: .75; }
  100% { transform: translateY(10px); opacity: 0; }
}

@keyframes rl-lead-1 {
  0%, 16.5% { stroke-dashoffset: 1; }
  19.5%, 84% { stroke-dashoffset: 0; }
  87%, 100% { stroke-dashoffset: 1; }
}

@keyframes rl-lead-2 {
  0%, 25.5% { stroke-dashoffset: 1; }
  28.5%, 78% { stroke-dashoffset: 0; }
  81%, 100% { stroke-dashoffset: 1; }
}

@keyframes rl-lead-3 {
  0%, 36% { stroke-dashoffset: 1; }
  39%, 71.5% { stroke-dashoffset: 0; }
  74.5%, 100% { stroke-dashoffset: 1; }
}

@keyframes rl-on-1 {
  0%, 18.5% { opacity: 0; }
  22%, 84% { opacity: 1; }
  87%, 100% { opacity: 0; }
}

@keyframes rl-on-2 {
  0%, 27.5% { opacity: 0; }
  31%, 78% { opacity: 1; }
  81%, 100% { opacity: 0; }
}

@keyframes rl-on-3 {
  0%, 38% { opacity: 0; }
  41.5%, 71.5% { opacity: 1; }
  74.5%, 100% { opacity: 0; }
}

/* One pass of light over the Level 3 badge right after it lights up. */
@keyframes rl-glint {
  0%, 42% { transform: translateX(-16px); opacity: 0; }
  43% { transform: translateX(-10px); opacity: .4; }
  52% { transform: translateX(150px); opacity: .4; }
  53%, 100% { transform: translateX(156px); opacity: 0; }
}

/* ==== scene-cert: a certificate in 3D, rows appear, the number is typed, a stamp comes down ===== */

/* Sizes in cqi of the scene: it scales with its width like the SVG scenes (100cqi = 320 viewBox units). */
.rp-scene--cert {
  container-type: inline-size;
  aspect-ratio: 4 / 3;
}

.rp-scene--cert .rc-space {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  perspective: 160cqi;
  perspective-origin: 50% 30%;
}

.rp-scene--cert .rc-card {
  position: relative;
  width: 74cqi;
  height: 52cqi;
  margin-top: 3cqi;
  transform-style: preserve-3d;
  transform: rotateY(-10deg);
  animation: rc-sway-y 6.5s ease-in-out infinite alternate;
}

.rp-scene--cert .rc-tilt {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(8deg);
  animation: rc-sway-x 4.3s ease-in-out infinite alternate;
}

.rp-scene--cert .rc-shade,
.rp-scene--cert .rc-edge,
.rp-scene--cert .rc-sheet {
  position: absolute;
  inset: 0;
  border-radius: var(--rp-r-md);
}

/* A flat shadow plate behind the sheet and the edge of the card: depth without blur. */
.rp-scene--cert .rc-shade {
  background: var(--rp-stone);
  transform: translate3d(2cqi, 2.6cqi, -4cqi);
}

.rp-scene--cert .rc-edge {
  background: var(--rp-line-strong);
  transform: translateZ(-.6cqi);
}

.rp-scene--cert .rc-sheet {
  display: grid;
  grid-template-rows: auto 1fr auto;
  row-gap: 3cqi;
  padding: 4.8cqi 6cqi 4.4cqi;
  overflow: hidden;
  background: var(--rp-surface);
  box-shadow: inset 0 0 0 var(--rp-bw) var(--rp-line);
  color: var(--rp-ink);
}

.rp-scene--cert .rc-ribbon {
  position: absolute;
  top: 0;
  right: 7cqi;
  width: 4.4cqi;
  height: 12.5cqi;
  background: var(--rp-ink-2);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 80%, 0 100%);
  transform-origin: 50% 0;
  animation: rc-ribbon 6.5s ease-in-out infinite;
}

.rp-scene--cert .rc-head {
  display: flex;
  align-items: center;
  gap: 2.4cqi;
  padding-bottom: 2.6cqi;
  border-bottom: var(--rp-bw) solid var(--rp-line);
  animation: rc-head 6.5s ease-in-out infinite;
}

.rp-scene--cert .rc-mark {
  height: 3.6cqi;
}

.rp-scene--cert .rc-kind {
  padding-left: 2.4cqi;
  border-left: var(--rp-bw) solid var(--rp-line-strong);
  color: var(--rp-muted);
  font-family: var(--rp-font);
  font-size: 3cqi;
  font-weight: var(--rp-fw-medium);
  line-height: 1;
}

.rp-scene--cert .rc-rows {
  display: grid;
  align-content: center;
  gap: 2.2cqi;
}

.rp-scene--cert .rc-row {
  display: block;
  width: 84%;
  height: 1.4cqi;
  border-radius: var(--rp-r-xs);
  background: var(--rp-line-strong);
  transform-origin: 0 50%;
  animation: rc-row 6.5s ease-in-out -6.5s infinite;
}

.rp-scene--cert .rc-row--name {
  width: 58%;
  height: 2.4cqi;
  background: var(--rp-ink-2);
}

.rp-scene--cert .rc-row--course { animation-delay: -6.24s; }
.rp-scene--cert .rc-row--date { width: 44%; animation-delay: -5.98s; }

.rp-scene--cert .rc-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2cqi;
}

/* The number is typed: a paper-coloured cover slides off it one character (1ch) at a time. */
.rp-scene--cert .rc-number {
  position: relative;
  overflow: hidden;
  padding-right: .3em;
  color: var(--rp-ink-2);
  font-family: var(--rp-font-mono);
  font-size: 3.3cqi;
  line-height: 1.3;
  white-space: nowrap;
  animation: rc-number 6.5s linear infinite;
}

.rp-scene--cert .rc-number__cover {
  position: absolute;
  inset: 0;
  background: var(--rp-surface);
  transform: translateX(110%);
  animation: rc-type 6.5s steps(17, end) infinite;
}

.rp-scene--cert .rc-number__cover::before {
  content: "";
  position: absolute;
  top: .15em;
  bottom: .15em;
  left: 0;
  width: .12em;
  background: var(--rp-accent);
  opacity: 0;
  animation: rc-caret 6.5s linear infinite;
}

.rp-scene--cert .rc-sign {
  flex: none;
  width: 18cqi;
  margin-bottom: .8cqi;
  border-top: var(--rp-bw) solid var(--rp-line-strong);
}

.rp-scene--cert .rc-print,
.rp-scene--cert .rc-print-shade,
.rp-scene--cert .rc-stamp {
  position: absolute;
  right: 6.4cqi;
  bottom: 3cqi;
  width: 15.5cqi;
  aspect-ratio: 1;
  border-radius: 50%;
}

.rp-scene--cert .rc-print-shade {
  background: var(--rp-line);
  opacity: 0;
  animation: rc-print-shade 6.5s ease-in-out infinite;
}

/* The impression: accent rings, the Roca mark and the year, slightly turned like a real stamp. */
.rp-scene--cert .rc-print {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .9cqi;
  border: .5cqi solid var(--rp-accent);
  color: var(--rp-accent);
  transform: rotate(-14deg);
  animation: rc-print 6.5s ease-in-out infinite;
}

.rp-scene--cert .rc-print__ring {
  position: absolute;
  inset: 1.1cqi;
  border: .3cqi dashed var(--rp-accent);
  border-radius: 50%;
}

.rp-scene--cert .rc-print__mark {
  height: 2.4cqi;
}

.rp-scene--cert .rc-print__year {
  font-family: var(--rp-font-mono);
  font-size: 2.9cqi;
  font-weight: var(--rp-fw-medium);
  line-height: 1;
  letter-spacing: .06em;
}

/* The stamp itself: comes down from above the sheet (translateZ), presses, lifts away. */
.rp-scene--cert .rc-stamp {
  opacity: 0;
  transform: translate3d(3cqi, -9cqi, 26cqi);
  animation: rc-stamp 6.5s ease-in-out infinite;
}

.rp-scene--cert .rc-stamp__body {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--rp-accent);
}

.rp-scene--cert .rc-stamp__body::before,
.rp-scene--cert .rc-stamp__body::after {
  content: "";
  position: absolute;
  border-radius: 50%;
}

.rp-scene--cert .rc-stamp__body::before {
  inset: 1.6cqi;
  border: .35cqi solid var(--rp-surface);
  opacity: .45;
}

.rp-scene--cert .rc-stamp__body::after {
  inset: 5cqi;
  background: var(--rp-surface);
  opacity: .9;
}

@keyframes rc-sway-y {
  from { transform: rotateY(-16deg); }
  to { transform: rotateY(12deg); }
}

@keyframes rc-sway-x {
  from { transform: rotateX(13deg); }
  to { transform: rotateX(3deg); }
}

@keyframes rc-head {
  0%, 4% { opacity: 0; transform: translateY(1cqi); }
  10%, 90% { opacity: 1; transform: none; }
  96%, 100% { opacity: 0; transform: none; }
}

@keyframes rc-row {
  0%, 9% { opacity: 1; transform: scaleX(0); animation-timing-function: var(--rp-ease); }
  18%, 90% { opacity: 1; transform: scaleX(1); }
  96% { opacity: 0; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(0); }
}

@keyframes rc-number {
  0%, 90% { opacity: 1; }
  96%, 99% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes rc-type {
  0%, 26% { transform: translateX(0); }
  44%, 97% { transform: translateX(17ch); }
  97.1%, 100% { transform: translateX(0); }
}

@keyframes rc-caret {
  0%, 20% { opacity: 0; }
  21% { opacity: 1; }
  23% { opacity: 0; }
  25%, 44% { opacity: 1; }
  46.5% { opacity: 0; }
  49% { opacity: 1; }
  51.5%, 100% { opacity: 0; }
}

@keyframes rc-stamp {
  0%, 45% { opacity: 0; transform: translate3d(3cqi, -9cqi, 26cqi); }
  47.5% { opacity: 1; transform: translate3d(2.6cqi, -8cqi, 23cqi); }
  56%, 58.5% { opacity: 1; transform: translate3d(0, 0, 0); }
  66% { opacity: 0; transform: translate3d(2.4cqi, -7cqi, 22cqi); }
  100% { opacity: 0; transform: translate3d(3cqi, -9cqi, 26cqi); }
}

@keyframes rc-print-shade {
  0%, 46% { opacity: 0; transform: scale(1.5); }
  56% { opacity: 1; transform: scale(1); }
  58%, 100% { opacity: 0; transform: scale(1); }
}

@keyframes rc-print {
  0%, 57% { opacity: 0; transform: rotate(-14deg) scale(1.05); }
  59%, 90% { opacity: 1; transform: rotate(-14deg) scale(1); }
  96%, 100% { opacity: 0; transform: rotate(-14deg) scale(1); }
}

@keyframes rc-ribbon {
  0%, 64% { opacity: 1; transform: scaleY(0); animation-timing-function: var(--rp-ease); }
  73%, 90% { opacity: 1; transform: scaleY(1); }
  96% { opacity: 0; transform: scaleY(1); }
  100% { opacity: 0; transform: scaleY(0); }
}
