/* ═══════════════════════════════════════════════════════════
   Cymela — Technology Page Styles
   ═══════════════════════════════════════════════════════════ */

/* ─── Capability Showcase ─── */
.capability {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border: 1px solid var(--border);
  margin-bottom: var(--space-8);
  overflow: hidden;
  background: var(--surface-200);
}

.capability--reverse {
  direction: rtl;
}

.capability--reverse > * {
  direction: ltr;
}

/* no second column at all — for a capability with no accurate illustration
   to pair it with, rather than leaving .capability's 1fr 1fr grid half
   empty */
/* the border and background live on .capability itself (the grid
   container), not on .capability__body — so capping only the body's width
   left the two-thirds-empty box in the screenshot: content shrank, the
   box behind it didn't. Capping the container is what actually removes
   the dead space. */
.capability--text-only {
  grid-template-columns: 1fr;
  max-width: 62ch;
}

.capability--text-only .capability__body {
  padding: var(--space-8);
}

.capability__image {
  position: relative;
  min-height: 550px;
  overflow: hidden;
}

.capability__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s var(--ease-out-expo);
}

.capability:hover .capability__image img {
  transform: scale(1.04);
}

.capability__body {
  position: relative;
  padding: var(--space-10);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-5);
}

.status-viz {
  width: 100%;
  height: 100%;
}

.status-viz__lines line {
  stroke: var(--border);
  stroke-width: 1;
  opacity: 0.5;
}

.status-viz__lines line.is-active {
  animation: statusLineGlow var(--dur, 6s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}

@keyframes statusLineGlow {
  0%, 100% { stroke: var(--border); opacity: 0.5; }
  50% { stroke: var(--accent-muted); opacity: 1; }
}

.status-viz__node {
  fill: var(--text-25);
  transform-box: fill-box;
  transform-origin: center;
  animation: statusNodePulse var(--dur, 6s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}

@keyframes statusNodePulse {
  0%, 100% { opacity: 0.35; transform: scale(1); }
  50% { opacity: 0.85; transform: scale(1.2); }
}

.status-viz__node--hub {
  fill: var(--accent-muted);
  animation-name: statusNodePulseHub;
}

@keyframes statusNodePulseHub {
  0%, 100% { opacity: 0.5; transform: scale(1); fill: var(--accent-muted); }
  50% { opacity: 1; transform: scale(1.3); fill: var(--accent); }
}

/* A real screen recording, not an illustration — so the terminal text has to
   stay readable, which drives this whole variant.
   In the standard two-column .capability the clip only gets half the
   container: a 1166px-wide capture rendered into ~699px is 0.60x, and terminal
   text at 60% is unreadable. Full width puts every clip between 0.91x and
   1.20x instead.
   Cropping is not an option: the longest lines (the per-step token
   probabilities) run nearly the full width of the recorded window, so any
   horizontal crop cuts off the most interesting part of the output. */
.capability--video {
  grid-template-columns: 1fr;
}

/* One fixed shape for every clip. Letting each clip keep its own height
   meant the block grew and shrank by up to 178px whenever the clip changed,
   shoving everything below it up and down the page.
   --video-crop is the knob: it's the width:height ratio of the box, so a
   HIGHER number means a shorter box and more of the clip's (mostly empty)
   bottom cut away. It must stay above the widest clip ratio — currently
   1.85 — or clips start getting cropped at the sides instead. */
.capability--video .capability__image {
  --video-crop: 2.1;
  min-height: 0;
  aspect-ratio: var(--video-crop);
}

/* cover + top, so each clip is scaled to fill the box by WIDTH and the
   surplus is taken off the BOTTOM only. The bottom of these captures is
   mostly unused terminal; the sides are not — the longest lines (the
   per-step token probabilities) run nearly the full width of the recorded
   window, so a horizontal crop would cut the most interesting output. */
.video-loop__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

.capability__illustration-note {
  position: absolute;
  right: var(--space-10);
  bottom: var(--space-6);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-25);
}

.capability__num {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-25);
}

.capability__title {
  font-family: var(--font-mono);
  font-size: clamp(var(--text-2xl), 2.5vw, var(--text-3xl));
  font-weight: 500;
  color: var(--text-100);
  line-height: var(--leading-tight);
}

.capability__desc {
  font-size: var(--text-base);
  color: var(--text-50);
  line-height: var(--leading-relaxed);
  max-width: none;
}

.capability__specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

.capability__spec {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-300);
  border: 1px solid var(--border);
  min-width: 120px;
}

.capability__spec-value {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--text-100);
}

.capability__spec-label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-25);
}

@media (max-width: 768px) {
  .capability {
    grid-template-columns: 1fr;
  }

  .capability--reverse {
    direction: ltr;
  }

  .capability__image {
    min-height: 250px;
  }

  .capability__body {
    padding: var(--space-6);
  }
}


/* ─── Tech Specs Table ─── */
.tech-specs {
  padding: 0 var(--space-5);
  padding-bottom: var(--section-gap);
}

.tech-specs__inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

.tech-specs .data-table {
  margin-top: var(--space-8);
}


/* ─── Infrastructure Grid ─── */
.infra-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border: 1px solid var(--border);
  margin-top: var(--space-8);
}

.infra-item {
  padding: var(--space-8);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--surface-200);
  transition: background var(--transition-slow);
}

.infra-item:nth-child(3n) {
  border-right: none;
}

.infra-item:hover {
  background: var(--surface-300);
}

.infra-item__icon {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--surface-300);
  margin-bottom: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  color: var(--accent-muted);
}

.infra-item__title {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--text-90);
  margin-bottom: var(--space-3);
}

.infra-item__desc {
  font-size: var(--text-sm);
  color: var(--text-50);
  line-height: var(--leading-relaxed);
  max-width: none;
}

@media (max-width: 768px) {
  .infra-grid {
    grid-template-columns: 1fr;
  }

  .infra-item {
    border-right: none;
  }
}


/* ─── Partnerships / Funding Note ─── */
.training-contact {
  margin-top: var(--space-12);
  padding-top: var(--space-8);
  border-top: 1px solid var(--border);
}

.training-contact__label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-25);
  margin-bottom: var(--space-3);
}

.training-contact__text {
  font-size: var(--text-sm);
  color: var(--text-50);
  max-width: 62ch;
  line-height: var(--leading-relaxed);
}

.training-contact__text a {
  color: var(--accent-muted);
  transition: color var(--transition-fast);
}

.training-contact__text a:hover {
  color: var(--accent);
}
