/* ============================================================
   ZENOS - Technology Page Styles (Dark Theme)
   ============================================================ */

/* --- Hero --- */
.tech-hero {
  min-height: 70vh;
  display: flex;
  align-items: center;
  position: relative;
  padding-top: var(--nav-height);
  background: var(--black);
  color: var(--white);
  overflow: hidden;
}

.tech-hero__bg {
  position: absolute;
  inset: 0;
}

.tech-hero__gradient {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 40% 40%, rgba(123, 112, 251, 0.15) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 70%, rgba(84, 255, 224, 0.08) 0%, transparent 40%);
}

.tech-hero__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(84, 255, 224, 0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(84, 255, 224, 0.03) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse at 60% 40%, black 20%, transparent 70%);
  -webkit-mask-image: radial-gradient(ellipse at 60% 40%, black 20%, transparent 70%);
}

/* Floating particles */
.tech-hero__particles {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.tech-particle {
  position: absolute;
  width: 3px;
  height: 3px;
  background: var(--cyan);
  opacity: 0;
  animation: floatParticle 6s infinite;
}

.tech-particle:nth-child(1) { left: 20%; top: 30%; animation-delay: 0s; }
.tech-particle:nth-child(2) { left: 60%; top: 20%; animation-delay: 1s; animation-duration: 8s; }
.tech-particle:nth-child(3) { left: 80%; top: 60%; animation-delay: 2s; animation-duration: 7s; }
.tech-particle:nth-child(4) { left: 40%; top: 70%; animation-delay: 3s; }
.tech-particle:nth-child(5) { left: 70%; top: 40%; animation-delay: 1.5s; animation-duration: 5s; }
.tech-particle:nth-child(6) { left: 30%; top: 50%; animation-delay: 4s; animation-duration: 9s; }

@keyframes floatParticle {
  0% { opacity: 0; transform: translateY(0); }
  20% { opacity: 0.6; }
  80% { opacity: 0.4; }
  100% { opacity: 0; transform: translateY(-60px); }
}

.tech-hero__content {
  position: relative;
  z-index: 2;
  max-width: 720px;
  padding: var(--space-2xl) 0;
}

.tech-hero h1 {
  margin-bottom: var(--space-md);
}

.tech-hero__sub {
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  line-height: 1.7;
  opacity: 0.6;
  max-width: 600px;
  margin-bottom: var(--space-lg);
}

.tech-hero__ctas {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* Anchor targets sit under both the fixed nav AND the sticky sub-nav. */
.tech-section[id] { scroll-margin-top: calc(var(--nav-height) + 3.5rem); }

/* Two-layer sticky sub-nav. See matching .esports-nav comment in
   esports.css for the reasoning — ::before paints the 1px divider
   at the nav's bottom edge outside the scroll container, so the
   active link's 2px purple underline overlaps it cleanly. */
.tech-nav {
  position: sticky;
  top: var(--nav-height);
  z-index: 99;
  background: rgba(14, 11, 22, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: 0.9rem 0 0;
}

.tech-nav::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: rgba(123, 112, 251, 0.18);
  pointer-events: none;
}

.tech-nav__inner {
  display: flex;
  align-items: flex-end;
  gap: var(--space-lg);
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}

.tech-nav__inner::-webkit-scrollbar { display: none; }

.tech-nav__link {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--grey-light);
  padding: 0 0 0.55rem;
  border-bottom: 2px solid transparent;
  transition: color var(--duration-fast), border-color var(--duration-fast);
}

.tech-nav__link:hover,
.tech-nav__link--active {
  color: var(--cyan);
  border-bottom-color: var(--cyan);
}

/* --- Tech sections --- */
.tech-section {
  padding: var(--space-xl) 0;
  position: relative;
  overflow: hidden;
}

@media (max-width: 640px) {
  .tech-section { padding: var(--space-lg) 0; }
  /* Sticky sub-nav: keep the horizontal scrim visible but tighten
     padding so it doesn't eat too much of the viewport. */
  .tech-nav { padding-top: 0.6rem; }
  .tech-nav__inner { gap: var(--space-md); }
  .tech-hero { min-height: auto; padding-bottom: var(--space-lg); }
  .tech-hero__content { padding: var(--space-xl) 0 var(--space-lg); }
  /* CTA pairs grow equally so primary + secondary match width. */
  .tech-hero__ctas .btn,
  .tech-compressed__ctas .btn {
    flex: 1 1 0;
    justify-content: center;
    min-width: 0;
  }
}

.tech-section__layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xl);
  align-items: start;
}

@media (max-width: 991px) {
  .tech-section__layout {
    grid-template-columns: 1fr;
  }
}

/* --- Code block aesthetic --- */
.code-block {
  background: rgba(123, 112, 251, 0.06);
  border: 1px solid var(--border-dark);
  padding: var(--space-md);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--purple-tint);
  overflow-x: auto;
}

.code-block .keyword { color: var(--cyan); }
.code-block .string { color: var(--yellow); }
.code-block .comment { color: var(--grey); opacity: 0.5; }
.code-block .type { color: var(--magenta); }

/* --- Tech feature cards (dark) --- */
.tech-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

.tech-card {
  padding: var(--space-lg);
  transition: opacity var(--duration-mid) var(--ease-out);
}

.tech-card:hover p {
  opacity: 0.85;
}

.tech-card__icon {
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-sm);
  color: var(--cyan);
}

.tech-card h4 {
  margin-bottom: var(--space-xs);
  font-size: 1rem;
}

.tech-card p {
  font-size: 0.875rem;
  opacity: 0.6;
  line-height: 1.6;
  transition: opacity var(--duration-fast);
}

@media (max-width: 640px) {
  .tech-cards {
    grid-template-columns: 1fr;
  }
}

/* --- VTX architecture diagram (HTML cards + chips) ----
   Replaces the old monolithic SVG. Three stacked chipped
   cards: Core, Extensions, Frame Structure. */
.vtx-diagram {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.vtx-layer,
.vtx-frame {
  padding: var(--space-md) var(--space-lg);
}

.vtx-layer__label,
.vtx-frame__label {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--purple);
  margin-bottom: var(--space-sm);
}

.vtx-layer--ext .vtx-layer__label {
  color: var(--cyan);
}

.vtx-layer__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.vtx-chip {
  padding: 5px 10px;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--purple-tint);
  background: rgba(123, 112, 251, 0.08);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
}

.vtx-chip--cyan {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.08);
}

/* Frame structure */
.vtx-frame__row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 10px;
  background: rgba(123, 112, 251, 0.05);
  border-left: 2px solid var(--purple);
  margin-top: 6px;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.7rem;
}

.vtx-frame__tag {
  color: var(--cyan);
  font-weight: 600;
  white-space: nowrap;
}

.vtx-frame__tag--yellow {
  color: var(--yellow);
}

.vtx-frame__meta {
  color: var(--purple-tint);
  opacity: 0.55;
}

.vtx-frame__entities {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 6px;
}

@media (max-width: 640px) {
  .vtx-frame__entities { grid-template-columns: 1fr; }
}

.vtx-frame__entity {
  padding: 8px 10px;
  background: rgba(84, 255, 224, 0.04);
  border-left: 2px solid var(--cyan);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.7rem;
  animation: vtxPulse 2.4s ease-in-out infinite;
}

.vtx-frame__entity--dim {
  opacity: 0.7;
  animation-delay: 0.6s;
  animation-duration: 2.8s;
}

.vtx-frame__entity-label {
  color: var(--cyan);
  font-weight: 700;
  margin-bottom: 3px;
}

.vtx-frame__entity-meta {
  color: var(--purple-tint);
  opacity: 0.55;
  line-height: 1.5;
}

@keyframes vtxPulse {
  0%, 100% { opacity: 0.75; }
  50% { opacity: 1; }
}

.vtx-diagram__caption {
  text-align: right;
  margin-top: 10px;
  font-size: 0.75rem;
  color: var(--purple-tint);
  opacity: 0.5;
  font-style: italic;
}

/* --- UAF comparison diagram (Hub vs Pairwise) ----
   A single SVG with two halves. Left: spaghetti of N×(N−1) pairwise
   converters. Right: clean hub with N bidirectional modules. Sells the
   "why UAF exists" story in a single frame. Text lives inside the SVG
   since labels are short (engine names + counts). */
.uaf-compare {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.uaf-compare__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Below ~900px the 4 columns compress past legibility (text inside the
   SVG has fixed px sizes, so shrinking the viewBox just makes everything
   tiny). Switch to a horizontal scroll with a legibility floor — users
   can swipe to see each column at readable size. */
@media (max-width: 900px) {
  .uaf-compare {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    /* Faint scroll hint on the right edge */
    mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
    padding-bottom: 4px;
  }
  .uaf-compare__svg {
    min-width: 900px;
  }
  .uaf-compare::-webkit-scrollbar { height: 4px; }
}

.uaf-compare__caption {
  text-align: center;
  font-size: 0.875rem;
  color: var(--purple-tint);
  opacity: 0.55;
  margin-top: var(--space-md);
  font-weight: 500;
  padding: 0 var(--gutter);
}

/* --- Supported titles chipped strip --- */
.titles-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: var(--space-md);
}

.title-tag {
  padding: 6px 12px;
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--purple-tint);
  background: rgba(123, 112, 251, 0.08);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
  transition: color var(--duration-fast), background var(--duration-fast);
}

.title-tag:hover {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.1);
}

.title-tag--more {
  color: var(--cyan);
  background: transparent;
  border: 1px dashed rgba(84, 255, 224, 0.45);
  clip-path: none;
}

/* --- Open source preview cards --- */
.os-preview-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
}

.os-preview-card {
  padding: var(--space-md);
  text-align: center;
  transition: color var(--duration-mid) var(--ease-out);
}

.os-preview-card__name {
  font-family: var(--font-heading);
  font-size: 1.125rem;
  font-weight: 700;
  margin-bottom: 4px;
}

.os-preview-card__tagline {
  font-size: 0.75rem;
  opacity: 0.5;
  margin-bottom: var(--space-sm);
}

.os-preview-card .badge {
  font-size: 0.6875rem;
}

@media (max-width: 768px) {
  .os-preview-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* --- Publisher value prop --- */
.publisher-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-lg);
}

.publisher-step {
  padding: var(--space-lg);
}

.publisher-step__num {
  font-family: var(--font-heading);
  font-size: 3rem;
  font-weight: 900;
  font-stretch: 125%;
  color: var(--purple);
  opacity: 0.35;
  line-height: 1;
  margin-bottom: var(--space-md);
  display: block;
}

.publisher-step h4 {
  margin-bottom: var(--space-xs);
  font-size: 1.0625rem;
}

.publisher-step p {
  font-size: 0.9375rem;
  opacity: 0.65;
  line-height: 1.6;
}

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

/* --- Tech CTA --- */
.tech-cta {
  padding: var(--space-2xl) 0;
  text-align: center;
  position: relative;
}

.tech-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% 50%, rgba(84, 255, 224, 0.1) 0%, transparent 60%);
  pointer-events: none;
}

.tech-cta h2 {
  margin-bottom: var(--space-md);
}

.tech-cta p {
  opacity: 0.5;
  max-width: 480px;
  margin: 0 auto var(--space-lg);
}

/* ================================================================
   New section components (Data / Asset Interop / Twins / Apps)
   Added in the tech-page reframe — outcomes-first, not spec-docs.
   ================================================================ */

/* --- Section sub-heading (before app tiles etc) --- */
.section-subhead {
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-lg);
}
.section-subhead h3 {
  font-size: 1.5rem;
  color: var(--white);
  opacity: 0.85;
}

/* --- Product duo (PRISM + VTX side-by-side cards) --- */
.product-duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
  margin-top: var(--space-xl);
}

@media (max-width: 767px) {
  .product-duo { grid-template-columns: 1fr; }
}

.product-duo__card {
  padding: var(--space-xl) var(--space-lg);
}

.product-duo__eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--purple);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: var(--space-sm);
}

.product-duo__eyebrow--cyan {
  color: var(--cyan);
}

.product-duo__name {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 2.25rem;
  color: var(--purple);
  line-height: 1;
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}

.product-duo__name--cyan {
  color: var(--cyan);
}

.product-duo__tagline {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: var(--white);
  opacity: 0.65;
  margin-bottom: var(--space-md);
}

.product-duo__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.product-duo__list li {
  position: relative;
  padding-left: 20px;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--white);
  opacity: 0.72;
  margin-bottom: 6px;
}

.product-duo__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 10px;
  width: 10px;
  height: 2px;
  background: var(--purple);
}

.product-duo__list--cyan li::before {
  background: var(--cyan);
}

/* --- VTX dual-schema callout ---------------------
   Two side-by-side cards explaining VTX's two-layer schema model:
   generic (cross-game) and contextual (per-title). Compact vs the
   PRISM/VTX duo above — supports the duo without competing with it. */
.vtx-schema {
  margin-top: var(--space-2xl);
}

.vtx-schema__header {
  text-align: center;
  max-width: 640px;
  margin: 0 auto var(--space-xl);
}

.vtx-schema__header h3 {
  font-size: 1.5rem;
  color: var(--white);
  margin-bottom: var(--space-xs);
}

.vtx-schema__header p {
  color: var(--purple-tint);
  opacity: 0.7;
  line-height: 1.6;
}

.vtx-schema__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
}

@media (max-width: 767px) {
  .vtx-schema__grid { grid-template-columns: 1fr; }
}

.vtx-schema__card {
  padding: var(--space-lg) var(--space-xl);
}

.vtx-schema__tag {
  display: inline-block;
  padding: 5px 10px;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--purple);
  background: rgba(123, 112, 251, 0.14);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: var(--space-sm);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
}

.vtx-schema__tag--cyan {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.12);
}

.vtx-schema__title {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.125rem;
  color: var(--white);
  margin-bottom: var(--space-xs);
  letter-spacing: 0.01em;
}

.vtx-schema__card p {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--white);
  opacity: 0.7;
}

/* --- Application tiles (4-up grid) --- */
.app-tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
}

@media (max-width: 991px) {
  .app-tiles { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .app-tiles { grid-template-columns: 1fr; }
}

.app-tile {
  padding: var(--space-lg);
  transition: opacity var(--duration-mid) var(--ease-out);
}

.app-tile h4 {
  font-size: 1rem;
  margin-bottom: var(--space-xs);
  color: var(--white);
}

.app-tile p {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--white);
  opacity: 0.6;
  transition: opacity var(--duration-fast);
}

.app-tile:hover p { opacity: 0.85; }

/* --- Code block proof (smaller, framed with a label) --- */
.code-proof {
  margin-top: var(--space-2xl);
  max-width: 640px;
}

.code-proof__label {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--grey-light);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: var(--space-xs);
}

.code-proof .code-block {
  font-size: 0.75rem;
  line-height: 1.75;
}

/* --- Phase 1 / Phase 2 credibility block --- */
.phase-block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
  margin-top: var(--space-2xl);
}

@media (max-width: 991px) {
  .phase-block { grid-template-columns: 1fr; }
}

.phase-block__item {
  padding: var(--space-lg) var(--space-xl);
}

.phase-block__tag {
  display: inline-block;
  padding: 5px 10px;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--purple-tint);
  background: rgba(123, 112, 251, 0.12);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: var(--space-sm);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
}

.phase-block__tag--done {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.12);
}

.phase-block__tag--active {
  color: var(--purple);
  background: rgba(123, 112, 251, 0.14);
}

.phase-block__heading {
  font-size: 1.25rem;
  margin-bottom: var(--space-xs);
  color: var(--white);
}

.phase-block__item p {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--white);
  opacity: 0.7;
  margin-bottom: var(--space-md);
}

.phase-block__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.phase-engine {
  padding: 6px 12px;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--purple-tint);
  background: rgba(123, 112, 251, 0.08);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
}

.phase-engine--done {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.1);
}

.phase-engine--dashed {
  color: var(--cyan);
  background: transparent;
  border: 1px dashed rgba(84, 255, 224, 0.45);
  clip-path: none;
}

/* --- AI-ready bonus callout ----
   Soft tangent at the end of Asset Interop — flags UAF's code-first
   schema as a side-benefit for AI content authoring. Yellow "bonus"
   tag to signal "worth knowing, not a core pitch." */
.uaf-bonus {
  margin-top: var(--space-lg);
  padding: var(--space-lg) var(--space-xl);
  text-align: center;
}

.uaf-bonus__tag {
  display: inline-block;
  padding: 5px 10px;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--yellow);
  background: rgba(255, 222, 81, 0.1);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: var(--space-sm);
  clip-path: polygon(
    5px 0, 100% 0, 100% calc(100% - 5px),
    calc(100% - 5px) 100%, 0 100%, 0 5px
  );
}

.uaf-bonus__heading {
  font-size: 1.25rem;
  margin-bottom: var(--space-xs);
  color: var(--white);
}

.uaf-bonus p {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--purple-tint);
  opacity: 0.75;
  max-width: 720px;
  margin: 0 auto;
}

/* --- Game Twins convergence diagram --- */
.twin-diagram {
  position: relative;
  max-width: 880px;
  margin: 0 auto;
}

.twin-diagram__inputs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
}

@media (max-width: 767px) {
  .twin-diagram__inputs { grid-template-columns: 1fr; }
}

.twin-input {
  padding: var(--space-lg);
  text-align: center;
}

.twin-input__label {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--purple);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: var(--space-sm);
}

.twin-input__label--cyan { color: var(--cyan); }

.twin-input__products {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.5rem;
  color: var(--purple);
  letter-spacing: 0.02em;
  margin-bottom: var(--space-sm);
  display: flex;
  gap: 8px;
  justify-content: center;
  align-items: baseline;
}

.twin-input__products--cyan { color: var(--cyan); }

.twin-input__plus {
  font-size: 1rem;
  font-weight: 500;
  opacity: 0.55;
}

.twin-input__body {
  font-size: 0.875rem;
  color: var(--white);
  opacity: 0.6;
  line-height: 1.5;
}

.twin-diagram__wires {
  display: block;
  width: 100%;
  height: 100px;
  pointer-events: none;
}

@media (max-width: 767px) {
  .twin-diagram__wires { height: 60px; }
}

.twin-output {
  padding: var(--space-2xl) var(--space-xl);
  text-align: center;
}

.twin-output__eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--purple-tint);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: var(--space-sm);
}

.twin-output__name {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 2.75rem;
  color: var(--white);
  line-height: 1;
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}

.twin-output__engine {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--cyan);
  margin-bottom: var(--space-lg);
}

.twin-output__bullets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md) var(--space-lg);
  max-width: 640px;
  margin: 0 auto;
  text-align: left;
}

@media (max-width: 767px) {
  .twin-output__bullets { grid-template-columns: 1fr; }
}

.twin-output__bullet {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--white);
  opacity: 0.75;
}

.twin-output__bullet strong {
  color: var(--white);
  opacity: 1;
  font-weight: 700;
}

/* --- Applications grid (4 first-party + Your App banner) --- */
.app-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
}

@media (max-width: 991px) {
  .app-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .app-grid { grid-template-columns: 1fr; }
}

.app-grid__card {
  padding: var(--space-lg);
}

.app-grid__eyebrow {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--purple);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: 6px;
}

.app-grid__name {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.375rem;
  color: var(--white);
  line-height: 1;
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}

.app-grid__role {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--cyan);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: var(--space-sm);
}

.app-grid__card p {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--white);
  opacity: 0.65;
}

/* The "Your App" banner spans full row, purple-accent */
.app-grid__card--yours {
  grid-column: 1 / -1;
  padding: var(--space-xl) var(--space-2xl);
}

.app-grid__card--yours .app-grid__name {
  color: var(--purple);
  font-size: 1.75rem;
}

.app-grid__card--yours .app-grid__role {
  color: var(--purple-tint);
}

.app-grid__card--yours p {
  opacity: 0.75;
  max-width: 640px;
}

/* ================================================================
   Compressed section layout (dual-column: hooks + illustration)
   Shared between #data (PRISM/VTX) and #assets (UAF/Atlas). Deep
   content lives on the dedicated pages — these sections on the
   tech page are pitch-led: label, headline, short lead, "what you
   can build" hooks, CTA duo into the deep page.
   ================================================================ */
.tech-compressed {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2xl);
  align-items: center;
  margin-top: var(--space-xl);
}

@media (max-width: 991px) {
  .tech-compressed {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }
}

@media (max-width: 640px) {
  .tech-compressed {
    gap: var(--space-lg);
    margin-top: var(--space-lg);
  }
  /* #assets flips graphic-first at desktop (source order: illo, text).
     On mobile, bring the text back first for reading flow — the illo
     is context, the pitch should lead. */
  .tech-compressed .tech-illo--assets,
  .tech-compressed .tech-illo--data,
  .tech-compressed .tech-illo--twin {
    order: 2;
  }
  .tech-compressed .tech-compressed__text,
  .tech-compressed > div:not([class*="tech-illo"]) {
    order: 1;
  }
}

.tech-compressed__products {
  display: flex;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
  flex-wrap: wrap;
}

.tech-compressed__chip {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 0.875rem;
  letter-spacing: 0.08em;
  color: var(--purple);
  padding: 6px 14px;
  background: rgba(123, 112, 251, 0.1);
  text-transform: uppercase;
  clip-path: polygon(
    6px 0, 100% 0, 100% calc(100% - 6px),
    calc(100% - 6px) 100%, 0 100%, 0 6px
  );
}

.tech-compressed__chip--cyan {
  color: var(--cyan);
  background: rgba(84, 255, 224, 0.1);
}

.tech-compressed__hooks {
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0 var(--space-lg);
  display: grid;
  gap: var(--space-md);
}

.tech-compressed__hooks li {
  position: relative;
  padding-left: 32px;
}

.tech-compressed__hooks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 10px;
  width: 16px;
  height: 2px;
  background: linear-gradient(90deg, var(--purple), var(--cyan));
}

.tech-compressed__hooks li strong {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--white);
  line-height: 1.35;
  margin-bottom: 2px;
}

.tech-compressed__hooks li span {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--white);
  opacity: 0.55;
}

/* CTA pair (primary + secondary) matching home hero combo. Primary
   keeps its default top-left chip, secondary's SVG-bg border gives
   it the bottom-right chip — together they read as a Z pair. */
.tech-compressed__ctas {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* Dark-theme port of esports.css .esports-illo--data — same
   structure (GAME card → PRISM stream row → VTX card → fan-out
   → 3 output chips → cyan callout) but with dark cards and
   cyan output chips to sit cleanly on .section--dark. */
.tech-illo--data {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  max-width: 420px;
  margin: 0 auto;
}

.tech-illo--data .illo-card {
  padding: 14px 18px 16px;
  text-align: left;
}

/* Source card: single chipped card with internal 2-col.
   Left col = source detail (title, any-engine, memory addresses).
   Right col = info note (icon + short constraint callout). */
.tech-illo--data .illo-card--source {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;
}

/* Constraint note — subtle inline info callout on the right of the GAME
   card. Icon + one-line tagline, centre-aligned vertically. */
.tech-illo--data .illo-card__col--note {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding-top: 4px;
}

.tech-illo--data .illo-info-icon {
  color: var(--cyan);
  opacity: 0.65;
  flex-shrink: 0;
}

.tech-illo--data .illo-note-text {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--white);
  opacity: 0.7;
  font-weight: 500;
}

.tech-illo--data .illo-eyebrow {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--grey-light);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 3px;
}

.tech-illo--data .illo-eyebrow--cyan { color: var(--cyan); }

.tech-illo--data .illo-title {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.15rem;
  color: var(--purple-tint);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1;
}

.tech-illo--data .illo-mono {
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--purple-tint);
}

.tech-illo--data .illo-mono--muted { opacity: 0.55; }

.tech-illo--data .illo-prism {
  position: relative;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.tech-illo--data .illo-prism__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.tech-illo--data .illo-prism__content {
  position: relative;
  z-index: 1;
}

.tech-illo--data .illo-prism .illo-title {
  font-size: 1rem;
  color: var(--white);
}

/* Output stack: single fan-out SVG behind both chip rows, absolute-
   positioned chip rows on top so their y-positions are predictable and
   line endpoints align exactly. SVG viewBox height matches stack height,
   so pixel values in the SVG correspond 1:1 to container pixels. */
/* Stack sits flush under VTX so the SVG's y=0 (line origin) is exactly
   at VTX's bottom edge — the fan-out anchors visibly to the card, not
   to a floating point below it. The VTX→row-1 gap lives inside the
   stack as the space between y=0 and the row-1 chips at top:40px. */
.tech-illo--data .illo-outputs-stack {
  position: relative;
  height: 180px;
}

.tech-illo--data .illo-fanout-all {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.tech-illo--data .illo-outputs,
.tech-illo--data .illo-outputs--row2 {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 1;
}

.tech-illo--data .illo-outputs { top: 40px; }
.tech-illo--data .illo-outputs--row2 { top: 120px; }

.tech-illo--data .illo-outputs {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  justify-items: center;
  align-items: start;
}

/* Row-2: 2 chips centered at fan-out endpoints (x=160/320 of 480 viewBox
   = 1/3 and 2/3). flex + space-evenly puts two items at those exact
   positions (empty-chip-empty-chip-empty with equal empty widths). */
.tech-illo--data .illo-outputs--row2 {
  display: flex;
  justify-content: space-evenly;
}

/* Chips sit on top of the fan-out SVG. Background is opaque (solid dark
   with a thin cyan wash) so line segments passing behind row-1 on their
   way to row-2 are hidden within the chip shape. Pseudo-element handles
   the opaque backing; the chip itself keeps the subtle cyan tint overlay. */
.tech-illo--data .illo-output-item {
  position: relative;
  min-width: 88px;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cyan);
  padding: 7px 14px;
  background:
    linear-gradient(rgba(84, 255, 224, 0.1), rgba(84, 255, 224, 0.1)),
    #0E0B16;
  clip-path: polygon(
    8px 0, 100% 0, 100% calc(100% - 8px),
    calc(100% - 8px) 100%, 0 100%, 0 8px
  );
}

.tech-illo--data .illo-cyan-callout {
  align-self: center;
  margin-top: 24px;
  padding: 8px 18px;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--black);
  background: transparent;
  position: relative;
  white-space: nowrap;
  isolation: isolate;
}

.tech-illo--data .illo-cyan-callout::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--cyan);
  clip-path: polygon(
    10px 0, 100% 0, 100% calc(100% - 10px),
    calc(100% - 10px) 100%, 0 100%, 0 10px
  );
}

.tech-illo--data .illo-cyan-callout::after {
  content: '';
  position: absolute;
  inset: 1.5px;
  z-index: -1;
  background: var(--cyan-tint);
  clip-path: polygon(
    8.5px 0, 100% 0, 100% calc(100% - 8.5px),
    calc(100% - 8.5px) 100%, 0 100%, 0 8.5px
  );
}

/* =================================================================
   Applications — list-on-left / gallery-on-right. Hovering (or tapping)
   a row swaps the media on the right via .app-list__item--active +
   .app-gallery__media--active classes toggled by the init script below.
   ================================================================= */
.tech-compressed--apps {
  align-items: start;
  margin-top: 0; /* section-header already supplies the gap above */
}

/* Full-width variant of the section-header — overrides the default
   720px cap. Used where the header sits above a two-column grid. */
.section-header--wide {
  max-width: none;
}

/* Tighter vertical padding on a specific tech-section (e.g. Open Source
   which is just a compact header row + 4 cards — no need for the full
   space-xl top/bottom). */
.tech-section--tight {
  padding: var(--space-lg) 0;
}

/* --- Open Source compact: inline header + CTA on one row -------------
   Header block on the left, "Explore the hub →" link on the right.
   Cards sit in a tighter grid below. */
.os-compact {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-lg);
  margin-bottom: var(--space-lg);
  flex-wrap: wrap;
}

.os-compact__head .label {
  display: block;
  margin-bottom: 6px;
}

.os-compact__head h2 {
  margin-bottom: 6px;
}

.os-compact__head p {
  font-size: 0.9375rem;
  color: var(--white);
  opacity: 0.6;
  max-width: 520px;
  margin: 0;
  line-height: 1.5;
}

.os-compact__cta {
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--cyan);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(84, 255, 224, 0.35);
  transition: color var(--duration-fast), border-color var(--duration-fast);
}

.os-compact__cta:hover {
  color: var(--white);
  border-bottom-color: var(--white);
}

.os-compact__cta span {
  transition: transform var(--duration-fast);
}

.os-compact__cta:hover span {
  transform: translateX(2px);
}

/* Tighter grid for the Open Source card row — reduced padding, smaller
   internal spacing so the 4 cards occupy less vertical height. */
.os-preview-grid--tight {
  gap: var(--space-sm);
}

.os-preview-grid--tight .os-preview-card {
  padding: var(--space-sm) var(--space-md);
}

.os-preview-grid--tight .os-preview-card__name {
  font-size: 1rem;
  margin-bottom: 2px;
}

.os-preview-grid--tight .os-preview-card__tagline {
  font-size: 0.6875rem;
  margin-bottom: 8px;
}

.app-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid rgba(123, 112, 251, 0.18);
}

.app-list__item {
  display: block;
  padding: 12px 0 12px 10px;
  border-bottom: 1px solid rgba(123, 112, 251, 0.18);
  border-left: 2px solid transparent;
  cursor: pointer;
  transition: padding-left var(--duration-fast), border-left-color var(--duration-fast);
}

.app-list__item strong {
  display: block;
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1rem;
  line-height: 1.1;
  color: var(--white);
  opacity: 0.6;
  letter-spacing: 0.02em;
  margin-bottom: 3px;
  transition: color var(--duration-fast), opacity var(--duration-fast);
}

.app-list__item span {
  display: block;
  font-size: 0.75rem;
  color: var(--white);
  opacity: 0.5;
  line-height: 1.4;
  transition: opacity var(--duration-fast);
}

.app-list__item:hover strong,
.app-list__item--active strong {
  color: var(--cyan);
  opacity: 1;
}

.app-list__item--active {
  padding-left: 14px;
  border-left-color: var(--cyan);
}

.app-list__item--active span {
  opacity: 0.75;
}

.app-gallery {
  width: 100%;
}

/* Chipped media frame — double chip (top-left + bottom-right) matching
   the Z diagonal used sitewide. Large 28px corners for visual weight. */
.app-gallery__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: transparent;
  overflow: hidden;
  clip-path: polygon(
    28px 0,
    100% 0,
    100% calc(100% - 28px),
    calc(100% - 28px) 100%,
    0 100%,
    0 28px
  );
}

.app-gallery__media {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

.app-gallery__media--active {
  opacity: 1;
}

.app-gallery__media img,
.app-gallery__media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* "Your App" placeholder — dashed chipped frame with eyebrow/title/sub */
.app-gallery__placeholder {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at 50% 50%, rgba(123, 112, 251, 0.12) 0%, transparent 70%),
    rgba(14, 11, 22, 0.6);
}

.app-gallery__placeholder > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.app-gallery__placeholder-content {
  position: relative;
  text-align: center;
  padding: var(--space-md);
}

.app-gallery__placeholder-eyebrow {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--purple);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-bottom: var(--space-xs);
  opacity: 0.9;
}

.app-gallery__placeholder-title {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 1.75rem;
  color: var(--white);
  letter-spacing: 0.02em;
  margin-bottom: 8px;
}

.app-gallery__placeholder-sub {
  font-size: 0.9375rem;
  color: var(--purple-tint);
  opacity: 0.7;
}

/* --- Assets compressed illo — "Native Stack" (Concept 4 from uaf-preview)
   Two-column SVG: engine tiles stacked on the left (each pulsing in
   sequence as the scan sweep hits them), UAF spec card on the right
   (asset-class rows wave top-to-bottom after the engine scan). No
   lines between columns — reads as compatibility matrix, not routing. */
.tech-illo--assets,
.tech-illo--twin {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
}

.tech-illo--assets svg,
.tech-illo--twin .twin-illo__flow {
  display: block;
  width: 100%;
  height: auto;
}

/* --- Game Twin viewport window ----
   HTML window chrome wrapping a <model-viewer>. Title bar matches the
   Atlas window pattern (traffic-light dots, centred title, meta on the
   right). Viewport body = 3D live render of virtex-fps.glb. Bottom
   status bar carries the LIVE pulse + frame counter. */
/* Chipped bottom-right window. Can't use `clip-path` + `border` together
   (clip-path slices the border at the chip diagonal), so the border and
   dark fill come from an SVG background on ::before instead. The
   model-viewer canvas is clipped to the same chip shape below so it
   doesn't overflow past the diagonal. */
.twin-viewport {
  position: relative;
  background: transparent;
  margin-top: -8px;
}

.twin-viewport::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none' viewBox='0 0 200 200'%3E%3Cpolygon points='1,1 199,1 199,186 186,199 1,199' fill='%230E0B16' fill-opacity='0.9' stroke='%2354FFE0' stroke-width='1.5' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
}

/* Second ::after layer draws ONLY the stroke, on top of all content so
   the cyan border is never covered by the 3D canvas edge. */
.twin-viewport::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none' viewBox='0 0 200 200'%3E%3Cpolygon points='1,1 199,1 199,186 186,199 1,199' fill='none' stroke='%2354FFE0' stroke-width='1.5' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
}

.twin-viewport > * {
  position: relative;
  z-index: 1;
}

.twin-viewport__titlebar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 26px;
  padding: 0 12px;
  background: rgba(84, 255, 224, 0.06);
  border-bottom: 1px solid rgba(84, 255, 224, 0.25);
  position: relative;
  z-index: 2;
}

.twin-viewport__dots {
  position: relative;
  width: 22px;
  height: 5px;
  flex-shrink: 0;
}

.twin-viewport__dots::before,
.twin-viewport__dots::after {
  content: '';
  position: absolute;
  top: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--cyan);
}

.twin-viewport__dots::before {
  left: 0;
  opacity: 0.5;
  box-shadow: 8px 0 0 rgba(84, 255, 224, 0.4);
}

.twin-viewport__dots::after {
  left: 16px;
  opacity: 0.3;
}

.twin-viewport__title {
  flex: 1;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  color: var(--cyan);
}

.twin-viewport__meta {
  font-family: var(--font-body);
  font-size: 0.625rem;
  color: var(--cyan);
  opacity: 0.6;
  font-weight: 500;
  white-space: nowrap;
}

.twin-viewport__model {
  display: block;
  width: 100%;
  height: 240px;
  background: transparent;
  /* Clip the 3D canvas to the chip shape so it doesn't render past the
     bottom-right diagonal. Matches the SVG border on .twin-viewport::before. */
  clip-path: polygon(0 0, 100% 0, 100% 93%, 93% 100%, 0 100%);
  --poster-color: transparent;
  --progress-bar-color: var(--cyan);
  --progress-bar-height: 1px;
}

.twin-viewport__model::part(default-progress-mask) {
  display: none;
}

.twin-viewport__status {
  position: absolute;
  left: 12px;
  bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 2;
  pointer-events: none;
}

.twin-viewport__pulse {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--purple);
  animation: twinPulse 1s infinite;
}

@keyframes twinPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}

.twin-viewport__live {
  font-family: var(--font-heading);
  font-weight: 900;
  font-stretch: 125%;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  color: var(--purple);
}

.twin-viewport__frame {
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.625rem;
  color: var(--purple-tint);
  opacity: 0.7;
}

