/* ==========================================================================
   Trust illustrations — small animated scenes inside the trust cards.
   The host sets the --tv-* colour tokens. JS adds .tv-run to the host to play
   the entrance, and .tv-play while its loops may run.
   ========================================================================== */

.tv {
  --tv-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --tv-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  width: 100%;
  height: 100%;
  max-height: 100%;
}

.tv-play {
  --tv-play: running;
}

/* JS replays a scene: back to its start at once, with no transitions */
.tv-reset,
.tv-reset * {
  transition: none !important;
  animation: none !important;
}

svg.tv text {
  font-family: "Poppins", sans-serif;
  font-size: 14px;
  text-anchor: middle;
  fill: var(--tv-text);
}

/* ── SVG primitives ─────────────────────────────────────────────────────── */

.tv-line-muted { stroke: var(--tv-muted-strong); stroke-width: 1.5; }
.tv-grid { stroke: var(--tv-muted); stroke-width: 1; }

.tv-draw {
  stroke: var(--tv-accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 1.6s var(--tv-ease) var(--d, 0s);
}

.tv-draw--thick { stroke-width: 3; }
.tv-run .tv-draw { stroke-dashoffset: 0; }

/* A single short dash travelling along the path */
.tv-comet {
  stroke: var(--tv-accent);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-dasharray: 6 100;
  stroke-dashoffset: 6;
  animation: tv-comet 2.8s linear var(--d, 0s) infinite;
  animation-play-state: var(--tv-play, paused);
}

@keyframes tv-comet {
  to { stroke-dashoffset: -100; }
}

.tv-node,
.tv-pop {
  opacity: 0;
  transition: opacity 0.8s var(--tv-ease) var(--d, 0s);
}

.tv-run .tv-node,
.tv-run .tv-pop { opacity: 1; }

.tv-core {
  fill: var(--tv-accent);
  stroke: var(--tv-surface-solid);
  stroke-width: 3;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0);
  transition: transform 0.9s var(--tv-spring) var(--d, 0s);
}

.tv-run .tv-core { transform: scale(1); }

.tv-halo {
  fill: var(--tv-accent);
  opacity: 0.16;
  transform-box: fill-box;
  transform-origin: center;
  animation: tv-halo 3s var(--tv-ease) calc(var(--d, 0s) + 1.2s) infinite;
  animation-play-state: var(--tv-play, paused);
}

@keyframes tv-halo {
  from { transform: scale(0.4); opacity: 0.4; }
  to { transform: scale(1.7); opacity: 0; }
}

svg.tv .tv-caption {
  font-size: 15px;
  fill: var(--tv-text-muted);
}

.tv-box {
  fill: var(--tv-surface);
  stroke: var(--tv-muted-strong);
  stroke-width: 1.5;
}

.tv-chip { fill: var(--tv-muted); }
.tv-chip--on { fill: var(--tv-accent); }

.tv-led {
  fill: var(--tv-muted-strong);
  transition: fill 0.4s ease var(--d, 0s);
}

.tv-run .tv-led { fill: var(--tv-accent); }

/* Cloudspace hub: a brand-accent glow breathes behind the box while it gently scales */
.tv-hub-pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: tv-hub-pulse 3s ease-in-out infinite;
  animation-play-state: var(--tv-play, paused);
}

.tv-hub {
  fill: var(--tv-surface-solid);
  stroke: var(--neutral-100);
  stroke-width: 1;
}

.tv-hub-glow {
  fill: var(--brand-accent);
  transform-box: fill-box;
  transform-origin: center;
  animation: tv-hub-glow 3s ease-in-out infinite;
  animation-play-state: var(--tv-play, paused);
}

svg.tv .tv-hub-name {
  font-size: 18px;
  fill: var(--neutral-800);
}

svg.tv .tv-hub-pulse .tv-caption {
  font-size: 14px;
  fill: var(--text-muted);
}

@keyframes tv-hub-pulse {
  50% { transform: scale(1.04); }
}

@keyframes tv-hub-glow {
  0%, 100% { opacity: 0.25; transform: scale(0.94); }
  50% { opacity: 0.7; transform: scale(1.04); }
}

/* ── Billing ────────────────────────────────────────────────────────────── */

.tv-spiky {
  stroke: var(--tv-text-muted);
  stroke-width: 1.5;
  stroke-dasharray: 4 5;
  stroke-linejoin: round;
  opacity: 0.6;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1.8s var(--tv-ease) 0.1s;
}

.tv-run .tv-spiky { clip-path: inset(0 0 0 0); }

.tv-stop-accent { stop-color: var(--tv-accent); stop-opacity: 0.22; }
.tv-stop-accent--end { stop-opacity: 0; }

.tv-area {
  opacity: 0;
  transition: opacity 1.2s ease 1.6s;
}

.tv-run .tv-area { opacity: 1; }

/* ── HTML scenes: shared bits ───────────────────────────────────────────── */

.tv-feed {
  display: flex;
  flex-direction: column;
  justify-content: center;
  font-size: 14px;
  line-height: 1.4;
  color: var(--tv-text);
}

/* Typing dots and their bounce, used by the phone chat */
@keyframes tv-typing {
  0% { opacity: 0; transform: translateY(8px); }
  15%, 80% { opacity: 1; transform: none; }
  100% { opacity: 0; }
}

@keyframes tv-bounce {
  0%, 60%, 100% { transform: none; }
  30% { transform: translateY(-4px); }
}

/* ── Globe (canvas injected by globe.gl) ────────────────────────────────── */

.tv-globe {
  position: relative;
  overflow: hidden;

  canvas {
    display: block;
    opacity: 0;
    transition: opacity 1.2s ease;
  }

  &.is-loaded canvas {
    opacity: 1;
  }

  /* Touch screens: globe.gl sets touch-action: none on the canvas, which would stop the page scrolling */
  &:not(.is-draggable) {
    pointer-events: none;
  }

  &.is-draggable {
    cursor: grab;

    &:active {
      cursor: grabbing;
    }
  }
}

.tv-globe-site {
  position: relative;
  width: 0;
  height: 0;
  pointer-events: none;

  /* The pin's tip sits on the site */
  img {
    position: absolute;
    left: -14px;
    top: -27px;
    width: 28px;
    height: 28px;
    max-width: none;
  }
}

.tv-globe-label {
  position: absolute;
  left: 16px;
  top: -30px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 4px 14px rgb(0 49 48 / 0.12);
  font-size: 12px;
  font-weight: 500;
  color: var(--neutral-800);
  white-space: nowrap;

  span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--brand-accent-200);
  }
}

/* ── Support chat on a phone (bleeds off the card, cropped by it) ──────── */

.tv-chat-wrap {
  position: relative;
  transform: translateY(60px);
  opacity: 0;
  transition: transform 1.2s var(--tv-ease), opacity 0.8s ease;
}

.tv-run .tv-chat-wrap {
  transform: none;
  opacity: 1;
}

.tv-chat {
  position: absolute;
  top: 56px;
  left: 50%;
  width: 300px;
  height: 600px;
  padding: 14px 16px;
  border: 1px solid var(--neutral-100);
  border-radius: 24px;
  background: #fff;
  transform: translateX(-50%) rotate(-7deg);
  transform-origin: 50% 0;
  font-size: 13px;
  line-height: 1.45;
  overflow: hidden;
}

.tv-chat-head {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  margin: -14px -16px 14px;
  background: var(--neutral-800);
  color: #fff;
}

.tv-chat-title {
  font-size: 16px;
  font-weight: 500;
}

.tv-chat-thread {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tv-chat-out,
.tv-chat-in {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease var(--d), transform 0.7s var(--tv-ease) var(--d);
}

.tv-run :is(.tv-chat-out, .tv-chat-in) {
  opacity: 1;
  transform: none;
}

.tv-chat-out {
  align-self: flex-end;
  max-width: 82%;
  padding: 10px 14px;
  border-radius: 18px 18px 4px 18px;
  background: var(--neutral-200);
}

.tv-chat-slot {
  display: grid;

  > * { grid-area: 1 / 1; }
}

.tv-chat-typing {
  align-self: start;
  justify-self: start;
  display: flex;
  gap: 4px;
  padding: 12px 14px;
  border-radius: 18px 18px 18px 4px;
  background: #fff;
  opacity: 0;

  span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    animation: tv-bounce 1s ease-in-out infinite;
  }

  span:nth-child(2) { animation-delay: 0.15s; }
  span:nth-child(3) { animation-delay: 0.3s; }
}

.tv-run .tv-chat-typing { animation: tv-typing 1.3s ease 1s both; }

.tv-chat-in p {
  margin: 6px 0 0;
  font-size: 13.5px;
}

.tv-chat-meta {
  display: flex;
  align-items: center;
  gap: 10px;

  small {
    display: block;
    font-size: 11px;
    color: var(--text-muted);
  }

  strong {
    display: block;
    font-size: 13px;
    font-weight: 600;
  }
}

.tv-chat-avatar {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-primary-300), var(--brand-accent));
  color: #fff;
  font-size: 11px;
  font-weight: 600;
}

.tv-chat-input {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 22px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--neutral-100);
  color: var(--text-muted);
}

.tv-chat-attach {
  display: grid;
  place-items: center;
  width: 34px;
  height: 38px;
}

.tv-chat-send {
  display: grid;
  margin-left: auto;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--brand-primary);
  color: #fff;
}

/* ── Visibility feed ────────────────────────────────────────────────────── */

.tv-feed {
  gap: 10px;

  ul {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 10px;
    background: var(--tv-surface-solid);
    border: 1px solid var(--tv-muted);
    opacity: 0;
    transform: translateX(-14px);
    transition:
      opacity 0.6s var(--tv-ease) calc(var(--r) * 0.18s + 0.2s),
      transform 0.8s var(--tv-ease) calc(var(--r) * 0.18s + 0.2s);
  }
}

.tv-run.tv-feed li,
.tv-run .tv-feed li { opacity: 1; transform: none; }

/* ── Forms: the automation and onboarding cards show a small app screen ───── */

.tv-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: calc(100% + 24px); /* as wide as the log panel: into the card's side padding */
  height: auto;
  margin-inline: -12px;
  padding: 18px;
  border: 1px solid var(--neutral-100);
  border-radius: 16px;
  background: #fff;
  font-size: 12px;
  line-height: 1.3;
  color: var(--tv-text);

  > strong {
    margin-bottom: 4px;
    font-size: 14px;
    font-weight: 600;
  }

  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
}

.tv-form-label {
  color: var(--tv-text-muted);
}

.tv-form-select {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  border: 1px solid var(--neutral-300);
  border-radius: 8px;
  font-size: 13px;
}

/* Automation: action, frequency with its days, time, a skeleton option */
.tv-sched {
  .tv-form-select {
    margin-bottom: 6px;
  }

  /* The days of the week; Mon, Wed and Fri fill in one after another */
  ul {
    display: flex;
    justify-content: space-between;
    margin: 2px 0 8px;
  }

  li {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border: 1px solid var(--neutral-300);
    border-radius: 50%;
    font-size: 11px;
    font-weight: 500;
    color: var(--tv-text-muted);
    transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
  }

  li:nth-child(2) { transition-delay: 0.9s; }
  li:nth-child(4) { transition-delay: 1.15s; }
  li:nth-child(6) { transition-delay: 1.4s; }
}

.tv-run .tv-sched li:is(:nth-child(2), :nth-child(4), :nth-child(6)) {
  border-color: var(--brand-accent-200);
  background: var(--brand-accent-200);
  color: var(--brand-primary);
}

/* An empty time field showing its placeholder */
.tv-sched-time {
  width: 50%;
  margin-bottom: 6px;
  padding: 8px 10px;
  border: 1px solid var(--neutral-300);
  border-radius: 8px;
  font-size: 13px;
  color: var(--neutral-300);
}

/* Skeleton option: an empty checkbox and a grey bar */
.tv-sched-once {
  display: flex;
  align-items: center;
  gap: 8px;

  b {
    width: 14px;
    height: 14px;
    border: 1px solid var(--neutral-300);
    border-radius: 4px;
  }

  i {
    width: 45%;
    height: 7px;
    border-radius: 4px;
    background: var(--neutral-100);
  }
}

/* Onboarding: pick a group and its permissions switch on */
.tv-perm {
  ul {
    display: grid;
    gap: 12px;
    margin-top: 8px;
  }

  li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  /* Skeleton text: a title bar over a shorter description bar */
  li span {
    display: grid;
    flex: 1;
    gap: 6px;
  }

  i {
    height: 7px;
    border-radius: 4px;
    background: var(--neutral-100);
  }

  i + i {
    height: 5px;
    background: color-mix(in srgb, var(--neutral-100) 60%, #fff);
  }

  /* Toggle: off, then on once the group is picked */
  b {
    position: relative;
    flex: none;
    width: 28px;
    height: 16px;
    border-radius: 999px;
    background: var(--neutral-300);
    transition: background-color 0.3s ease calc(0.9s + var(--r) * 0.25s);

    &::after {
      content: "";
      position: absolute;
      top: 2px;
      left: 2px;
      width: 12px;
      height: 12px;
      border-radius: 50%;
      background: #fff;
      transition: translate 0.3s var(--tv-ease) calc(0.9s + var(--r) * 0.25s);
    }
  }
}

.tv-run .tv-perm b {
  background: var(--brand-accent-200);

  &::after {
    translate: 12px 0;
  }
}

/* ── GPU as a Service ───────────────────────────────────────────────────── */

/* The three.js cards' canvas fills its box without sizing it */
:is(.tv-3d, .tv-bim-scene) canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* GPU and Elastic: a three.js scene (js/trust-gpu.js, js/trust-elastic.js) filling the card's visual area */
.tv-3d {
  position: relative;
  align-self: stretch;
  min-height: 220px;
}

/* Flat diagrams (hybrid GPU, visibility GPU): graphite shapes on white, every stroke a true 1.25px */
.tv-diagram {
  --tv-graphite: #252b2a;
  stroke: var(--tv-graphite);
  stroke-width: 1.25;

  * { vector-effect: non-scaling-stroke; }

  .tv-dg-zone { fill: var(--tv-surface-solid); stroke-opacity: 0.3; }
  .tv-dg-unit { fill: var(--tv-surface-solid); }
  .tv-dg-dot { fill: var(--tv-muted-strong); stroke: none; }
  .tv-led { stroke: none; }

  .tv-dg-label {
    font-size: 15px;
    text-anchor: start;
    stroke: none;
  }
}

/* Hybrid GPU: cloud and on-prem side by side, one line between them */
.tv-hy {
  .tv-hy-gpu { fill: var(--tv-graphite); }
  .tv-hy-chip { stroke: var(--tv-surface-solid); }
  .tv-hy-link { stroke: var(--brand-accent); stroke-width: 1.5; }
  .tv-hy-port { fill: var(--tv-surface-solid); stroke: var(--brand-accent-200); }
}

/* Visibility GPU: three nodes and the workloads in their GPU slots, three workload styles */
.tv-ops {
  .tv-ops-bus,
  .tv-ops-rule { stroke-opacity: 0.3; }
  .tv-ops-free { stroke-opacity: 0.25; }
  .tv-ops-a { fill: var(--tv-graphite); stroke: none; }
  .tv-ops-b { fill: var(--tv-surface-solid); stroke: var(--brand-accent-200); }
  .tv-ops-c { fill: color-mix(in srgb, var(--tv-graphite) 14%, #fff); stroke: none; }
}

/* Network: the GPU server joins the private network, drawn as the boundary the four resources share */
.tv-net-zone {
  fill: var(--tv-surface);
  stroke: var(--tv-muted-strong);
  stroke-dasharray: 4 5;
}

svg.tv .tv-net-name {
  font-size: 12px;
  text-anchor: start;
}

.tv-net {
  .tv-hub-name {
    font-size: 14px;
  }

  .tv-hub {
    stroke: var(--neutral-100);
  }
}

/* BIM: a three.js building (js/trust-bim.js) goes from wireframe to BIM model to render */
.tv-bim-scene {
  position: relative;
  aspect-ratio: 264 / 206;
  overflow: hidden;
  border-radius: 10px;
  background: var(--neutral-75);
}

.tv-bim-tag {
  position: absolute;
  bottom: 10px;
  left: 50%;
  translate: -50% 0;
  padding: 4px 10px;
  border: 1px solid var(--neutral-100);
  border-radius: 999px;
  background: #fff;
  font-size: 11px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.6s ease;
}

.tv-bim-scene.is-done .tv-bim-tag {
  opacity: 1;
}

/* Control: GPU instances lying about at odd angles settle into one ordered list */
.tv-tidy {
  > strong {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  > strong img {
    width: 20px;
    height: 20px;
  }

  ul {
    display: grid;
    gap: 8px;
  }

  li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--neutral-300);
    border-radius: 10px;
    background: #fff;
    font-weight: 500;
    color: var(--neutral-800);
    translate: var(--x) var(--y);
    rotate: var(--a);
    transition: translate 0.9s var(--tv-ease), rotate 0.9s var(--tv-ease);
    transition-delay: calc(0.4s + var(--r) * 0.15s);
  }

  li img {
    width: 28px;
    height: 28px;
  }

  small {
    margin-left: auto;
    font-size: 11px;
    color: var(--tv-text-muted);
  }
}

.tv-run .tv-tidy li {
  translate: none;
  rotate: none;
}

/* ── Reduced motion: show every scene in its finished state ─────────────── */

@media (prefers-reduced-motion: reduce) {
  .tv,
  .tv * {
    transition: none !important;
    animation: none !important;
  }
}
