/* ==========================================================================
   Trust bento — light cards in two bento grids (the second mirrored). Each card
   has its text on top and a scene that fills the rest, running into its bottom edge.
   ========================================================================== */

.trust-bento {
  --tb-radius: 28px;
  --tb-ease: cubic-bezier(0.16, 1, 0.3, 1);
  background-color: var(--background-color);

  .section-header {
    margin-bottom: 72px;
  }
}

/* ── Header reveal (words slide up from their own mask) ─────────────────── */

.tw {
  display: inline-block;
  overflow: clip;
  vertical-align: top;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;

  > span {
    display: inline-block;
    transform: translateY(110%);
    transition: transform 1.1s var(--tb-ease) calc(var(--w) * 45ms);
  }
}

.is-inview .tw > span {
  transform: none;
}

.trust-bento.is-ready [data-trust-reveal] :is(.section-pre-title, .section-description) {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.8s ease 0.3s, transform 1s var(--tb-ease) 0.3s;
}

.trust-bento.is-ready [data-trust-reveal].is-inview :is(.section-pre-title, .section-description) {
  opacity: 1;
  transform: none;
}

/* ── Grid: 1 col → 2 col → 4-col bento with a mirrored second act ───────── */

.trust-bento-act + .trust-bento-act {
  margin-top: var(--block-space-sm);
}

.trust-bento-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--block-space-sm);
  margin: 0;

  @media (min-width: 700px) {
    grid-template-columns: repeat(2, 1fr);

    > :first-child {
      grid-column: 1 / -1;
    }
  }

  @media (min-width: 1025px) {
    grid-template-columns: repeat(4, 1fr);
    grid-auto-flow: dense;

    > :first-child {
      grid-column: span 2;
      grid-row: span 2;
    }

    > :nth-child(2) {
      grid-column: span 2;
    }
  }
}

@media (min-width: 1025px) {
  .trust-bento-act--scale .trust-bento-grid > :first-child {
    grid-column: 3 / 5;
  }
}

/* ── Card ───────────────────────────────────────────────────────────────── */

.trust-bento-card {
  --tv-ink: var(--brand-primary);
  --tv-text: var(--neutral-800);
  --tv-text-muted: var(--text-muted);
  --tv-muted: rgb(0 68 66 / 0.08);
  --tv-muted-strong: rgb(0 68 66 / 0.18);
  --tv-accent: var(--brand-accent-200);
  --tv-on-accent: var(--brand-primary-800);
  --tv-surface: rgb(255 255 255 / 0.6);
  --tv-surface-solid: #fff;

  position: relative;
  display: flex;
  flex-direction: column-reverse;
  gap: 28px;
  padding: 28px 28px 0;
  border-radius: var(--tb-radius);
  background: var(--neutral-75);
  overflow: hidden;

  @media (min-width: 1025px) {
    padding: 32px 32px 0;
  }
}

/* The scene fills the rest of the card */
.trust-bento-visual {
  display: flex;
  flex: 1 0 auto;
  align-items: center;
  justify-content: center;
}

.trust-bento-body {
  flex: none;
}

.trust-bento-card-title {
  margin-bottom: 8px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.trust-bento-card-text {
  max-width: 46ch;
  margin: 0;
  font-size: 15px;
}

/* ── Card entrance ──────────────────────────────────────────────────────── */

.trust-bento.is-ready .trust-bento-card {
  opacity: 0;
  transform: translateY(40px);
  transition:
    opacity 0.9s ease calc(var(--i) * 90ms),
    transform 1.2s var(--tb-ease) calc(var(--i) * 90ms);
}

.trust-bento.is-ready .trust-bento-card.is-inview {
  opacity: 1;
  transform: none;
}

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

/* Billing card: the chart bleeds to the card's side edges */
.trust-bento .trust-bento-card--billing {
  .trust-bento-visual {
    align-items: flex-end;
  }

  /* A soft glow under the line that fades out well before the card edge */
  .tv-stop-accent {
    stop-color: var(--brand-accent);
    stop-opacity: 0.16;
  }

  .tv-stop-accent--end {
    stop-opacity: 0;
  }

  .tv-draw {
    stroke: var(--brand-accent);
  }

  :is(.tv-core, .tv-halo) {
    fill: var(--brand-accent);
  }

  /* Legend: a dot + label per line; the typical bill is faded back */
  .tv-key {
    opacity: 0.6;

    circle { fill: var(--tv-text-muted); }
    text { text-anchor: start; }
  }

  .tv-key--accent {
    opacity: 1;

    circle { fill: var(--brand-accent); }
    text { fill: var(--neutral-800); }
  }

  .tv-billing {
    width: calc(100% + 56px);
    height: auto;
    max-height: none;
    margin-inline: -28px;
    padding-top: 16px;

    @media (min-width: 1025px) {
      width: calc(100% + 64px);
      margin-inline: -32px;
    }
  }
}

/* White panel behind the log */
.trust-bento .tv-feed {
  height: auto;
  width: calc(100% + 24px);
  margin-inline: -12px;
  padding: 4px 20px;
  border: 1px solid var(--neutral-100);
  border-radius: 16px;
  background: #fff;
}

/* Visibility card: the log, rows split by hairlines. It sits on the card's bottom edge and runs
   past it, cut by the card like the other app screens */
.trust-bento .trust-bento-card--visibility {
  .trust-bento-visual {
    align-items: flex-end;
  }

  .tv-feed {
    gap: 0;
    max-height: none;
    padding-inline: 12px;
    margin-bottom: -16px;
  }

  ul {
    gap: 0;
  }

  /* Mark, action and host on the first line; the skeleton and the result under them */
  li {
    display: grid;
    grid-template-columns: 18px minmax(0, 1fr) auto;
    align-items: center;
    gap: 0 8px;
    margin-inline: -12px;
    padding: 14px 12px;
    border: 0;
    border-bottom: 1px solid var(--neutral-100);
    border-radius: 0;
    background: none;

    &:last-child {
      border-bottom: 0;
    }
  }

  .is-failed {
    --tv-log-mark: var(--error-color-200);
    --tv-log-mark-bg: color-mix(in srgb, var(--error-color-100) 60%, #fff);
    transition-property: opacity, transform, background-color;
    transition-duration: 0.6s, 0.8s, 0.4s;
    transition-delay: calc(var(--r) * 0.18s + 0.2s), calc(var(--r) * 0.18s + 0.2s), calc(0.8s + var(--r) * 0.7s);
  }

  strong {
    flex: none;
    font-size: 12px;
    font-weight: 500;
  }

  /* The failed row turns pink once it fails */
  .tv-run .is-failed {
    background: #fff1f1;
  }

  /* Skeleton: who ran it, then how long it took */
  small {
    display: flex;
    grid-column: 2;
    gap: 6px;
  }

  i {
    display: block;
    width: 72px;
    height: 6px;
    border-radius: 4px;
    background: var(--neutral-100);

    & + i {
      width: 36px;
    }
  }

  /* Under a failure: its reason as red bars, then three button skeletons as bars. They open once
     the row fails */
  .tv-log-error {
    display: flex;
    grid-column: 2 / -1;
    flex-direction: column;
    gap: 6px;
    margin-top: 12px;
    opacity: 0;
    transition: opacity 0.4s ease calc(0.8s + var(--r) * 0.7s + 0.5s);

    i {
      width: 85%;
      background: var(--error-color-100);

      & + i {
        width: 55%;
      }
    }

    span {
      display: flex;
      gap: 6px;
      margin-top: 8px;
    }

    b {
      width: 56px;
      height: 6px;
      border-radius: 4px;
      background: var(--neutral-100);
    }
  }

  .tv-run .tv-log-error {
    opacity: 1;
  }
}

/* A spinner while its row runs: a light brand-green arc fading into a pale track. It then gives
   way to a tick or a cross on a tinted circle */
.tv-log-icon {
  --tv-log-at: calc(0.8s + var(--r) * 0.7s);
  /* A plain success green for the tick, kept apart from the brand green */
  --tv-log-green: #16a34a;
  position: relative;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background:
      conic-gradient(transparent 15%, color-mix(in srgb, var(--brand-accent-200) 25%, transparent) 50%, color-mix(in srgb, var(--brand-accent-200) 80%, #fff)),
      var(--neutral-200);
    mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
    animation: tv-log-spin 0.9s linear infinite;
    transition: opacity 0.2s ease var(--tv-log-at);
  }

  svg {
    opacity: 0;
    transition: opacity 0.3s ease var(--tv-log-at);
  }
}

.tv-run .tv-log-icon {
  background: var(--tv-log-mark-bg, #dcfce7);
  color: var(--tv-log-mark, var(--tv-log-green));
  transition: background-color 0.3s ease var(--tv-log-at);

  &::before {
    opacity: 0;
  }

  svg {
    opacity: 1;
  }
}

@keyframes tv-log-spin {
  to { transform: rotate(1turn); }
}

.tv-log-title {
  display: flex;
  grid-column: 2 / -1;
  align-items: baseline;
  gap: 5px;
  min-width: 0;
  white-space: nowrap;
}

.tv-log-host {
  overflow: hidden;
  font-size: 12px;
  font-weight: 500;
  text-overflow: ellipsis;
  color: #00a4ff;
}

.tv-log-status {
  /* A failure shows a red bar the height of the other placeholders once its row resolves */
  justify-self: end;

  b {
    display: block;
    width: 44px;
    height: 6px;
    border-radius: 4px;
    background: var(--error-color-100);
    opacity: 0;
    transition: opacity 0.3s ease calc(0.8s + var(--r) * 0.7s);
  }
}

.tv-run .tv-log-status b {
  opacity: 1;
}

/* Automation, onboarding and the GPU form cards: the app screen sits on the card's bottom edge and runs
   past it, so the card crops its bottom like a cut-out of a real screen */
.trust-bento-card:is(.trust-bento-card--automation, .trust-bento-card--onboarding, .trust-bento-card--bim, .trust-bento-card--control) {
  .trust-bento-visual {
    align-items: flex-end;
  }

  .tv-form {
    max-height: none;
    margin-bottom: -24px;
    padding-bottom: 40px;
  }
}

/* Production card: 12 servers, 3 to a row, above the Cloudspace hub. js/trust.js runs a line from the
   middle of each server down its column and curves it into the hub's top edge */
.tv-fleet {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px 12px;
  align-items: center;
  height: auto;
  padding: 24px 0;

  ul {
    display: contents;
  }

  li {
    position: relative;
    display: flex;
    align-items: center;
    justify-self: center;
    gap: 8px;
    /* One width for every box, so the grid reads as even columns */
    width: min(100%, 180px);
    min-width: 130px;
    padding: 12px;
    border: 1px solid var(--neutral-300);
    border-radius: 12px;
    background: #fff;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--neutral-800);
    white-space: nowrap;
    opacity: 0;
    translate: 0 8px;
    transition: opacity 0.6s var(--tv-ease), translate 0.6s var(--tv-ease);
    transition-delay: calc(0.3s + var(--r) * 0.05s);
  }

  li img {
    display: block;
    width: 32px;
    height: 32px;
  }
}

.tv-run .tv-fleet li {
  opacity: 1;
  translate: none;
}

.tv-fleet-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;

  .tv-draw {
    stroke: var(--tv-muted-strong);
    stroke-width: 1.25;
  }

  .tv-comet {
    stroke: var(--neutral-800);
    stroke-width: 5;
    stroke-dasharray: 0 100;
    stroke-dashoffset: 0;
  }
}

/* The one system under them all (hub styles in trust-visuals.css) */
.tv-fleet .tv-fleet-hub {
  position: relative;
  grid-column: 1 / -1;
  margin-top: 40px;
  justify-self: center;
  width: min(232px, 100%);
  height: auto;
}

/* Phones: 3 servers to a row is tight, so the boxes are compact and long names wrap at the hyphen */
@media (max-width: 480px) {
  .tv-fleet {
    gap: 12px 6px;
    margin-inline: -16px;
  }

  .tv-fleet li {
    width: 100%;
    gap: 6px;
    min-width: 0;
    padding: 8px 4px;
    font-size: 11px;
    text-align: center;
    white-space: normal;
  }
}

/* GPU network card: the diagram at the size of the small cards */
.trust-bento .tv-net {
  width: min(100%, 300px);
  margin-bottom: 28px;
}

/* Hybrid card: a small still diagram, its lines dark */
.trust-bento-card--hybrid .trust-bento-visual {
  margin-bottom: var(--block-space-md);
}

.trust-bento .tv-hybrid {
  width: min(100%, 420px);

  /* A crisp 1px line on screen, so both draw the same solid colour however small the diagram is */
  .tv-line-muted {
    stroke: var(--neutral-800);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    shape-rendering: crispEdges;
  }

  /* All three boxes share one border, a true 1px however small the diagram is drawn */
  :is(.tv-hub, .tv-box) {
    stroke: var(--neutral-100);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
  }
}

/* Hybrid GPU card: the two environments at a calm size */
.trust-bento-card--hybrid-gpu .trust-bento-visual {
  margin-bottom: var(--block-space-md);
}

.trust-bento .tv-hy {
  width: min(100%, 480px);
}

/* Visibility GPU card: the environment diagram */
.trust-bento-card--visibility-gpu .trust-bento-visual {
  margin-bottom: var(--block-space-md);
}

.trust-bento .tv-ops {
  width: min(100%, 540px);
}

/* Chat card: the phone rises from the bottom and the card crops it */
.trust-bento-card--chat .trust-bento-visual {
  position: relative;
  display: block;
  min-height: 380px;
}

/* Globe card: the top of the globe rises from the bottom edge (width set by JS) */
.trust-bento-card--globe {
  .trust-bento-visual {
    position: relative;
    display: block;
    min-height: 236px;
  }

  .tv-globe {
    position: absolute;
    left: 50%;
    bottom: -332px;
    height: 550px;
    max-height: none;
    transform: translateX(-50%);
  }
}
