/* infra.css — animations of the "Our Infrastructure" cards (#infrastructure), shared by every page.
   Every animation only moves transform/opacity, loops forever and is NOT switched off by the OS
   "reduce motion" setting (the client wants them visible). Colours come from theme variables, so the
   same rules work in dark and light mode. */

/* ------------------------------------------------ 1. CPU card + 3. fast provisioning (same as the old site) */
.infra-card-tw .cpu-trace { stroke-dasharray: 6; animation: traceFlow 2s linear infinite; }
.infra-card-tw .hourglass { transform-origin: 50% 50%; transform-box: fill-box; animation: flipHourglass 3.2s ease-in-out infinite; }
.infra-card-tw .clock-hand-spin { transform-origin: 50% 85%; transform-box: fill-box; animation: spinClockHand 5s linear infinite; }
@keyframes traceFlow { to { stroke-dashoffset: -24; } }
@keyframes flipHourglass { 0%, 40% { transform: rotate(0deg); } 50%, 90% { transform: rotate(180deg); } 100% { transform: rotate(360deg); } }
@keyframes spinClockHand { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ------------------------------------------------ 2. technical support: a short chat that replays every 6s
   0.0s  customer bubble pops in from its tail, its two text lines write themselves
   1.3s  admin "typing..." bubble appears, three dots bounce
   2.7s  typing bubble hands over to the answer bubble (soft scale + fade), answer line writes itself
   5.0s  both bubbles fade out together, short pause, replay
   The avatar of whoever is "talking" lights up. */
.sup-chat .sup-bubble,
.sup-chat .sup-line,
.sup-chat .sup-dot,
.sup-chat .sup-avatar { transform-box: fill-box; }

.sup-chat .sup-question { transform-origin: 89% 100%; animation: supQuestion 6s cubic-bezier(.22, .9, .3, 1) infinite; }
.sup-chat .sup-typing   { transform-origin: 30% 100%; animation: supTyping 6s cubic-bezier(.22, .9, .3, 1) infinite; opacity: 0; }
.sup-chat .sup-answer   { transform-origin: 10.5% 100%; animation: supAnswer 6s cubic-bezier(.22, .9, .3, 1) infinite; opacity: 0; }

.sup-chat .sup-line { transform-origin: 0% 50%; animation: 6s cubic-bezier(.3, .7, .2, 1) infinite; }
.sup-chat .sup-line-1 { animation-name: supLine1; }
.sup-chat .sup-line-2 { animation-name: supLine2; }
.sup-chat .sup-line-3 { animation-name: supLine3; }

.sup-chat .sup-dot { transform-origin: 50% 50%; animation: supDot 1.1s ease-in-out infinite; }
.sup-chat .sup-dot-2 { animation-delay: .15s; }
.sup-chat .sup-dot-3 { animation-delay: .3s; }

.sup-chat .sup-avatar-client { animation: supAvatarClient 6s ease-in-out infinite; }
.sup-chat .sup-avatar-admin  { animation: supAvatarAdmin 6s ease-in-out infinite; }

@keyframes supQuestion {
  0%       { opacity: 0; transform: translateY(14px) scale(.86); }
  7%       { opacity: 1; transform: translateY(0) scale(1.02); }
  11%      { opacity: 1; transform: translateY(0) scale(1); }
  84%      { opacity: 1; transform: translateY(0) scale(1); }
  92%,100% { opacity: 0; transform: translateY(-8px) scale(.98); }
}
@keyframes supLine1 { 0%, 5% { transform: scaleX(0); } 16%, 100% { transform: scaleX(1); } }
@keyframes supLine2 { 0%, 10% { transform: scaleX(0); } 21%, 100% { transform: scaleX(1); } }
@keyframes supTyping {
  0%, 21%  { opacity: 0; transform: translateY(12px) scale(.8); }
  26%      { opacity: 1; transform: translateY(0) scale(1); }
  44%      { opacity: 1; transform: translateY(0) scale(1); }
  48%,100% { opacity: 0; transform: translateY(0) scale(1.04); }
}
@keyframes supDot {
  0%, 60%, 100% { transform: translateY(0); opacity: .45; }
  30%           { transform: translateY(-11px); opacity: 1; }
}
@keyframes supAnswer {
  0%, 45%  { opacity: 0; transform: translateY(12px) scale(.86); }
  52%      { opacity: 1; transform: translateY(0) scale(1.02); }
  56%      { opacity: 1; transform: translateY(0) scale(1); }
  84%      { opacity: 1; transform: translateY(0) scale(1); }
  92%,100% { opacity: 0; transform: translateY(-8px) scale(.98); }
}
@keyframes supLine3 { 0%, 51% { transform: scaleX(0); } 64%, 100% { transform: scaleX(1); } }
@keyframes supAvatarClient { 0% { opacity: .55; } 4%, 20% { opacity: 1; } 28%, 100% { opacity: .55; } }
@keyframes supAvatarAdmin  { 0%, 19% { opacity: .55; } 24%, 62% { opacity: 1; } 70%, 100% { opacity: .55; } }

/* ------------------------------------------------ 4. DDoS protection
   Six "attack packets" around the shield take turns (one per second, 6s loop): a red copy lights up,
   drifts a few units toward the shield, then shrinks and fades as it is blocked, while the original block
   dims and slowly comes back. The shield edge flashes softly at each block and two rings ripple out of it.
   The shield is a tinted fill of --primary on --card, so it is never a dark blob in light mode
   (supersedes the old .shield-pulse rules; that class is no longer used). */
.dd-guard .dd-shield { fill: color-mix(in srgb, var(--primary) 12%, var(--card)); stroke: var(--primary); }
.dd-guard .dd-halo   { stroke: var(--primary); opacity: 0; animation: ddHalo 1s ease-out infinite; }

.dd-guard .dd-ring {
  stroke: var(--primary); opacity: 0;
  transform-box: fill-box; transform-origin: 50% 50%;
  animation: ddRing 3.6s cubic-bezier(.2, .6, .35, 1) infinite;
}
.dd-guard .dd-ring-2 { animation-delay: 1.8s; }

.dd-guard .dd-pkt { animation: ddPacket 6s ease-out infinite; }
.dd-guard .dd-hit {
  fill: color-mix(in srgb, var(--danger) 24%, transparent); stroke: var(--danger); opacity: 0;
  transform-box: fill-box; transform-origin: 50% 50%;
  animation: ddHit 6s cubic-bezier(.3, .7, .3, 1) infinite;
}
/* direction toward the shield centre, in SVG units */
.dd-guard .dd-hit-1 { --dx: -10px; --dy: 9px; }
.dd-guard .dd-hit-2 { --dx: 14px;  --dy: -2px; }
.dd-guard .dd-hit-3 { --dx: -4px;  --dy: -13px; }
.dd-guard .dd-hit-4 { --dx: 10px;  --dy: 10px; }
.dd-guard .dd-hit-5 { --dx: -14px; --dy: -2px; }
.dd-guard .dd-hit-6 { --dx: -8px;  --dy: -11px; }
.dd-guard .dd-pkt-2, .dd-guard .dd-hit-2 { animation-delay: 1s; }
.dd-guard .dd-pkt-3, .dd-guard .dd-hit-3 { animation-delay: 2s; }
.dd-guard .dd-pkt-4, .dd-guard .dd-hit-4 { animation-delay: 3s; }
.dd-guard .dd-pkt-5, .dd-guard .dd-hit-5 { animation-delay: 4s; }
.dd-guard .dd-pkt-6, .dd-guard .dd-hit-6 { animation-delay: 5s; }

@keyframes ddHit {
  0%   { opacity: 0; transform: translate(0, 0) scale(1); }
  3%   { opacity: 1; transform: translate(0, 0) scale(1.04); }
  9%   { opacity: 1; transform: translate(var(--dx), var(--dy)) scale(.96); }
  16%  { opacity: 0; transform: translate(calc(var(--dx) * 1.4), calc(var(--dy) * 1.4)) scale(.7); }
  100% { opacity: 0; transform: translate(0, 0) scale(1); }
}
@keyframes ddPacket { 0% { opacity: 1; } 3%, 16% { opacity: .15; } 34%, 100% { opacity: 1; } }
/* peaks at .58s of every second = the moment each packet reaches the shield (9% of 6s = .54s) */
@keyframes ddHalo { 0%, 46% { opacity: 0; } 58% { opacity: .28; } 100% { opacity: 0; } }
@keyframes ddRing {
  0%       { opacity: .55; transform: scale(1); }
  70%,100% { opacity: 0; transform: scale(1.5); }
}
