/* landing.css — styles unique to the landing page (public/index.html): the
   .page shell, the ambient drifting-logo background, the hero logo, the
   "What are MicroVMs?" explainer + tabs, the demo card grid/groups, and the
   inline "How do MicroVMs work?" tour (public/tour.js). Split out of
   /styles.css; index.html loads it AFTER /styles.css (relies on that file's
   :root palette + shared .hero/.btn base). Landing-only rules live here. */

.page {
  position: relative;
  z-index: 1; /* above the floating-logo background */
  max-width: 1180px;
  margin: 0 auto;
  padding: 2.75rem 1.5rem;
  /* Full-height column so the (expanded) explainer can grow to fill the viewport,
     leaving 50px at the bottom. Landing-only: .page is used only by index.html. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding-bottom: 50px;
}

/* Ambient background: circled, semi-transparent Lambda logos drifting behind the
   page. A fixed, non-interactive layer above the body background but below content. */
.bg-logos {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Narrow viewports have no side margin to hold the VMs — hide them entirely.
   1320px ≈ content column (1180) + room for a VM in each margin. Keep in sync
   with BG_MIN_WIDTH in landing.js. */
@media (max-width: 1320px) {
  .bg-logos { display: none; }
}

/* Connector overlay: dotted, flowing lines between VMs, drawn behind the windows. */
.bg-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.bg-link {
  stroke: var(--accent);
  stroke-width: 1.25;
  stroke-dasharray: 2 7;
  opacity: 0.28;
  animation: link-flow 1.1s linear infinite;
}

@keyframes link-flow {
  to { stroke-dashoffset: -9; } /* one dash+gap period (2 + 7) → seamless loop */
}

/* Each floating item is a tiny monitor on a stand — a bezelled "screen" running
   the circular Lambda logo, over a neck + base — echoing the classic "virtual
   machines" glyph so it reads as a VM rather than a browser/app window. */
.bg-vm {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  opacity: 0.3;
  will-change: transform;
  animation: float-logo linear infinite;
}

/* The display: bezel takes most of the box height; the stand sits under it. */
.bg-vm__screen {
  flex: 1;
  width: 100%;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 10px;
  border: 1.5px solid var(--muted);
  background: var(--card-bg);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
}

/* Stand: a short neck (::before) rising into a wider base bar (::after). */
.bg-vm__stand {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
  width: 100%; /* so the base's % width resolves against the monitor, not the neck */
}
.bg-vm__stand::before {
  content: '';
  width: 10px;
  height: 7px;
  background: var(--muted);
}
.bg-vm__stand::after {
  content: '';
  width: 46%;
  height: 5px;
  border-radius: 2.5px;
  background: var(--muted);
}

.bg-vm__logo {
  width: 52%;
  aspect-ratio: 1;
  overflow: hidden; /* clip the square logo into a circle */
  border-radius: 50%;
  border: 1px solid var(--card-border);
}

.bg-vm__logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@keyframes float-logo {
  0%   { transform: translate(0, 0) rotate(0deg); }
  25%  { transform: translate(14px, -26px) rotate(6deg); }
  50%  { transform: translate(-10px, -44px) rotate(-5deg); }
  75%  { transform: translate(-16px, -20px) rotate(4deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .bg-vm,
  .bg-link { animation: none; }
}

.hero__logo {
  display: block;
  margin: 0 auto 0.8rem;
  width: 60px;
  height: 60px;
}

/* Landing explainer: "What are MicroVMs?" — a lead paragraph + a row of points,
   sitting between the hero and the demo grid. */
.explainer {
  /* No `auto` side margins: as a flex item in the .page column they'd disable the
     default align-items:stretch, shrink-wrapping the card to its content — so it
     narrowed when collapsed. Stretch to the full page width in both states. */
  margin: 0 0 2.75rem;
  padding: 1.75rem 1.9rem;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  display: flex;
  flex-direction: column;
}

/* On the landing splash (demos still hidden) and only while expanded, let the
   explainer card grow to fill the page's remaining height (the 50px bottom
   padding on .page is the gap the user asked for). Collapsed or once demos are
   revealed, it falls back to natural height. */
.demos-hidden .explainer:has(.explainer__toggle[aria-expanded='true']) {
  flex: 1 1 auto;
  min-height: 0; /* let the body shrink + scroll instead of the card growing taller */
}
/* The body (holding the active tab panel) fills the grown height. Its own content
   scrolls, so the card is a FIXED height that never changes between tabs (What /
   How) or as a tour step's content varies. min-height:0 defeats the default
   min-height:auto that would otherwise let tall content expand the card. */
.demos-hidden .explainer:has(.explainer__toggle[aria-expanded='true']) .explainer__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
/* The How panel fills that body as a flex column so the tour can stretch and its
   nav can bottom-align. (The What panel stays natural height; its CTA is pinned to
   the bottom via margin-top:auto below.) */
.demos-hidden
  .explainer:has(.explainer__toggle[aria-expanded='true'])
  #tabpanel-how.is-active {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
/* Pin the CTA (What tab) to the bottom of the fixed-height body. It's hidden on the
   How tab, so this only affects the What tab. */
.demos-hidden
  .explainer:has(.explainer__toggle[aria-expanded='true'])
  .explainer__cta {
  margin-top: auto;
}

/* Header row: a tab strip on the left, the collapse chevron pinned right. */
.explainer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.explainer__tabs {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.explainer__tab {
  padding: 0.5rem 0.9rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.explainer__tab:hover {
  color: var(--fg);
}

.explainer__tab.is-active {
  color: var(--fg);
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--card-border);
}

/* Compact collapse chevron button, pinned to the right of the tab strip. */
.explainer__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--card-border);
  border-radius: 8px;
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.explainer__toggle:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.explainer__chevron {
  flex: none;
  color: var(--muted);
  font-size: 1.9rem;
  line-height: 1;
  transition: transform 0.15s ease;
}

.explainer__toggle:hover .explainer__chevron {
  color: var(--accent);
}

/* Point the chevron sideways when collapsed — pre-paint via the <html> class,
   and post-JS via aria-expanded (JS hands off from one to the other). */
.explainer-collapsed .explainer__body { display: none; }
.explainer-collapsed .explainer__chevron,
.explainer__toggle[aria-expanded='false'] .explainer__chevron {
  transform: rotate(-90deg);
}

/* Collapsed: only the toggle row shows, so trim the section's tall padding. */
.explainer-collapsed .explainer,
.explainer:has(.explainer__toggle[aria-expanded='false']) {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.explainer__body {
  margin-top: 1.1rem;
}

/* Hide the whole explainer until JS has restored the saved tab and rendered the
   tour, then reveal it fully-formed — no flash of the wrong tab or of buttons
   jumping as late content loads. The class is hardcoded on <html> (pre-paint) and
   removed by landing.js on the next animation frame (after the tour has rendered). */
.explainer-init .explainer { visibility: hidden; }

/* Only the active tab's panel is shown; the JS also sets [hidden] on the rest. */
.explainer__tabpanel[hidden],
.explainer__tabpanel:not(.is-active) {
  display: none;
}

/* Pre-paint tab restore: honor a saved "How do…" tab before landing.js runs, so
   there's no flash of the default "What are…" panel. ID selectors outrank the
   .is-active/[hidden] rules above; landing.js drops the .tab-how class once it
   takes over the swap (so later tab clicks aren't overridden). */
.tab-how #tabpanel-what { display: none; }
.tab-how #tabpanel-how { display: block; }
.tab-how #tab-what { color: var(--muted); background: none; border-color: transparent; }
.tab-how #tab-how { color: var(--fg); background: rgba(255, 255, 255, 0.05); border-color: var(--card-border); }

.explainer__placeholder {
  margin-bottom: 0;
  font-style: italic;
}

.explainer__lead {
  margin: 0 0 1.8rem;
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1.65;
}

.explainer__lead strong {
  color: var(--fg);
  font-weight: 600;
}

.explainer__points {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.4rem 1.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.explainer__point {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.7rem;
  row-gap: 0.25rem;
}

.explainer__point-icon {
  grid-row: 1 / 3;
  font-size: 1.9rem;
  line-height: 1;
}

.explainer__point-title {
  align-self: center;
  font-weight: 600;
  font-size: 1.1rem;
}

.explainer__point-text {
  grid-column: 2;
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.5;
}

/* First-visit reveal: hide the demos and show the CTA at the bottom of the
   explainer. Both are driven by the `demos-hidden` class on <html> (set pre-paint,
   removed once the user reveals the demos). */
.demos-hidden .demo-groups { display: none; }
.explainer__cta { display: none; margin-top: 1.6rem; padding-top: 1.6rem; justify-content: center; gap: 0.75rem; flex-wrap: wrap; }
.demos-hidden .explainer__cta { display: flex; }
/* The How tab (the tour) has its own nav + "take me to demos", so the shared CTA is
   redundant there — and hiding it kills the flash of these buttons while the tour
   content loads. Covers the pre-paint hint (.tab-how) and the post-JS is-active state.
   The :has() rule carries an ID so it outranks .demos-hidden; .tab-how is placed after
   it to win on equal specificity during the pre-paint window. */
.explainer:has(#tab-how.is-active) .explainer__cta,
.tab-how .explainer__cta { display: none; }
/* Two classes so these win over the later, equal-specificity `.btn` base. */
.explainer__cta .explainer__learn,
.explainer__cta .explainer__reveal { font-size: 1.15rem; padding: 1rem 1.8rem; }
/* Only the "take me to demos" buttons carry a white border (not the blue primaries). */
.explainer__cta .explainer__reveal { border: 1px solid #fff; }

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

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

/* Scenario boxes: categories sit side by side across a 5-column-wide row, each a
   vertical stack of its cards. A category can span 1 or 2 of those columns
   (.span-1 / .span-2); a 2-span category lays its cards out in two inner columns.
   Totals across the categories (1 + 2 + 2) define the row width. */
.demo-groups {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: auto auto; /* title row, cards row — shared across categories */
  gap: 1.5rem;
  align-items: start;
}

/* Each category spans both rows and adopts them via subgrid, so every category's
   title lands in the same (tallest) title row and every card grid starts on the
   same line — labels are equal height regardless of how many lines they wrap to. */
.demo-group {
  min-width: 0;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 2;
  row-gap: 0; /* spacing between title and cards comes from the title's own margin */
}
.span-1 { grid-column: span 1; }
.span-2 { grid-column: span 2; }

/* Vertical separator centered in the gap before each subsequent category,
   anchored to the card grid so it starts where the buttons start (not at the title). */
.demo-group + .demo-group > .grid::before {
  content: '';
  position: absolute;
  left: -0.75rem; /* half of the 1.5rem column gap */
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--card-border);
}

/* Inner card grid, narrow by default; a 2-span category gets two columns. */
.demo-group .grid { grid-template-columns: 1fr; }
.span-2 .grid { grid-template-columns: repeat(2, 1fr); }

/* Below the full row's comfortable width, stack the categories full-width and let
   each card grid flow responsively. */
@media (max-width: 1024px) {
  .demo-groups { grid-template-columns: 1fr; grid-template-rows: none; gap: 2.25rem; }
  /* Stacked: each category is a normal block again (no shared title row). */
  .demo-group { display: block; }
  .demo-group + .demo-group > .grid::before { display: none; } /* no vertical dividers when stacked */
  .span-1, .span-2 { grid-column: auto; }
  .demo-group .grid,
  .span-2 .grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  }
}

.demo-group__title {
  margin: 0 0 1rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--fg);
  text-align: center;
  padding-bottom: 0.55rem;
  border-bottom: 1px solid var(--card-border);
}

/* Card grid — display + gap only; column count is set per category above
   (.demo-group .grid / .span-2 .grid) and by the responsive media query.
   A fixed auto-row height makes every card in every category exactly the same
   height (cards stretch to fill the row); sized for the worst case (2-line title
   + 3-line subtitle). */
.grid {
  display: grid;
  position: relative; /* anchor for the category separator pseudo-element */
  grid-auto-rows: 8.25rem;
  gap: 1rem;
}

/* Compact horizontal tile: icon on the left, title + subtitle stacked on the
   right. The title row is a FIXED 2-line height (2.5rem = 2 × 1.25 line-height)
   and the title top-aligns into it, so every title starts at the same y and every
   subtitle starts right below the reserved block — titles and subtitles line up
   across cards no matter how many lines each wraps to. The subtitle row (1fr)
   absorbs the rest of the fixed-height box; the icon spans both rows. */
.card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: 2.5rem 1fr;
  align-items: center; /* vertically centres the icon across the two text rows */
  column-gap: 0.7rem;
  row-gap: 0.2rem;
  padding: 0.9rem 1rem;
  text-align: left;
  text-decoration: none;
  color: var(--fg);
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}

.card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

/* Not-yet-implemented demos: greyed, non-interactive, with a red COMING SOON stamp
   angled across the tile. overflow:hidden clips the rotated stamp to the tile. */
.card--soon {
  position: relative;
  overflow: hidden;
  cursor: default;
}
.card--soon:hover {
  transform: none;
  border-color: var(--card-border);
  box-shadow: none;
}
.card--soon .card__icon,
.card--soon .card__title,
.card--soon .card__sub {
  opacity: 0.3;
  filter: grayscale(1);
}
.card__soon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-11deg);
  padding: 0.1rem 0.55rem;
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  white-space: nowrap;
  color: #ff5a5f;
  border: 2px solid #ff5a5f;
  border-radius: 5px;
  background: rgba(20, 20, 24, 0.55);
  pointer-events: none;
}
/* Implemented-but-not-configured demos: same stamp, amber instead of red so it
   reads as "deployable, just not wired up yet" rather than "not built". */
.card__missing {
  color: #f5a623;
  border-color: #f5a623;
}

.card__icon {
  grid-row: 1 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  line-height: 1;
  width: 2.1rem;
}

.card__title {
  grid-column: 2;
  align-self: start;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.25;
}

.card__sub {
  grid-column: 2;
  align-self: start;
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--muted);
}

.card--placeholder {
  opacity: 0.45;
  cursor: not-allowed;
}

.card--placeholder:hover {
  transform: none;
  border-color: var(--card-border);
  box-shadow: none;
}


/* ============================================================================
   Interactive "How do Lambda MicroVMs work?" tutorial (public/tour.js), rendered
   inline in the landing page's How tab. Reuses the palette + .btn family.
   ========================================================================== */
/* Flex column so the nav can be pushed to the bottom (margin-top:auto). When the
   parent panel is a fixed height (the splash), flex:1 makes the tour fill it; the
   step card sits at the top and the nav sits at the very bottom. */
.tour {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* Progress dot strip: ● done · ◉ current · ○ upcoming. */
.tour__progress {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: center;
  margin: 0 0 1.1rem;
}
.tour__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid #fff;
  background: transparent;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.tour__dot.is-done { background: var(--muted); border-color: var(--muted); }
.tour__dot.is-current {
  background: var(--accent);
  border-color: var(--accent);
  transform: scale(1.35);
}

.tour__panel {
  border: 1px solid var(--card-border);
  background: var(--card-bg);
  border-radius: 12px;
  padding: 1.25rem 1.35rem;
}
.tour__panel-head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}
.tour__panel-head--center { justify-content: center; }
.tour__step-num {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.tour__panel-title { margin: 0; font-size: 1.15rem; }
.tour__panel-body { display: block; }
.tour__lead { color: var(--fg); line-height: 1.55; margin: 0 0 1rem; }

/* Code cards (step 1). Horizontal scroll if a line runs long. */
/* Step 1's three code samples laid out side by side (equal columns), so the whole
   image reads at a glance. Wraps to a stack on narrow screens. */
.tour__code-row {
  display: flex;
  gap: 1rem;
  align-items: stretch;
  flex-wrap: wrap;
}
.tour__code-row .tour__code {
  flex: 1 1 0;
  min-width: 0; /* let the pre scroll horizontally instead of forcing the column wide */
  margin: 0;
}
@media (max-width: 720px) {
  .tour__code-row { flex-direction: column; }
}

/* Step 1 packaging diagram: the three code cards → image.zip → Amazon S3.
   Three converging arrows sit under the (equal-width) columns, then the zip and
   S3 nodes stack, centered, below them. */
.tour__pipeline {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}
.tour__pipeline-converge {
  width: 100%;
}
.tour__converge-svg {
  display: block;
  width: 100%; /* full width so origins align under the columns; height:auto keeps
                  the scale uniform (no distortion) */
  height: auto;
  color: var(--accent); /* stroke + arrowhead fill via currentColor */
}
.tour__pipeline-bucket {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}
/* The zip artifact in a box; "Amazon S3" caption sits below it. */
.tour__pipeline-zipbox {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid #ff9900; /* AWS/Amazon orange */
  border-radius: 10px;
  background: var(--card-bg);
}
.tour__pipeline-icon { font-size: 2rem; line-height: 1; }
.tour__pipeline-label { font-size: 0.9rem; font-weight: 600; color: var(--fg); }
.tour__pipeline-bucket-label { font-size: 0.85rem; font-weight: 600; color: #ff9900; }

.tour__code {
  margin: 0 0 1rem;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  overflow: hidden;
  background: #0c0e14;
}
.tour__code-cap {
  padding: 0.45rem 0.8rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: #fff;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--card-border);
}
.tour__code pre {
  margin: 0;
  padding: 0.85rem 0.9rem;
  overflow-x: auto;
}
.tour__code code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
  color: #cdd3e0;
  white-space: pre;
}

/* Terminal-style command card (step 2): green "$" prompt + muted comment line. */
.tour__cmd code { white-space: pre-wrap; overflow-wrap: anywhere; }
.tour__cmd-prompt { color: #2f9e44; font-weight: 600; user-select: none; }
.tour__cmd-comment { color: var(--muted); }

/* Step 3: three connectivity-mode panels (MicroVM → egress target). */
.tour__nets {
  display: flex;
  gap: 1rem;
  align-items: stretch;
}
.tour__net {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 1rem 0.85rem;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  background: var(--card-bg);
}
.tour__net-title { margin: 0; font-size: 0.95rem; color: var(--fg); text-align: center; }
.tour__net-diagram {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 96px;
}
.tour__net-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  background: #0c0e14;
}
.tour__net-icon {
  width: 34px;
  height: 34px;
  object-fit: contain;
  display: block;
}
.tour__net-icon--svg { color: #cdd3e0; }
.tour__net-svg { width: 34px; height: 34px; display: block; }
.tour__net-label {
  /* Match the step description text (.tour__lead): same font, size, colour. */
  font-size: 1rem;
  line-height: 1.55;
  color: var(--fg);
  text-align: center;
}
.tour__net-arrow { color: var(--accent); font-size: 1.4rem; line-height: 1; }
.tour__net-desc {
  margin: 0;
  /* Match the step description text (.tour__lead): same font, size, colour. */
  font-size: 1rem;
  line-height: 1.55;
  color: var(--fg);
  text-align: center;
}
@media (max-width: 720px) {
  .tour__nets { flex-direction: column; }
}

/* Screenshot figures (steps 2 & 3) with a placeholder until the asset is added. */
.tour__figure { margin: 0; }
.tour__figure + .tour__figure { margin-top: 1rem; }
/* Two build screenshots side by side (before/after); stacks on narrow screens. */
.tour__figure-row {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}
.tour__figure-row .tour__figure { flex: 1 1 0; min-width: 0; margin: 0; }
@media (max-width: 720px) {
  .tour__figure-row { flex-direction: column; }
  .tour__figure-row .tour__figure + .tour__figure { margin-top: 1rem; }
}
.tour__figure img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--card-border);
  border-radius: 10px;
}
.tour__figure figcaption {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--muted);
  text-align: center;
}
.tour__figure figcaption.tour__figure-cap--top {
  margin-top: 0;
  margin-bottom: 0.5rem;
  /* Match the step description text (.tour__lead): same font, size, colour. */
  font-size: 1rem;
  line-height: 1.55;
  color: var(--fg);
  text-align: center;
}
.tour__figure-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 180px;
  padding: 1.5rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
  border: 1px dashed var(--card-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
}

/* Live controls (steps 4 & 5). */
.tour__controls {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
  margin: 0.25rem 0 1rem;
}
.tour__input {
  flex: 1 1 180px;
  min-width: 140px;
  padding: 0.55rem 0.7rem;
  font: inherit;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--card-border);
  border-radius: 8px;
}
.tour__input:focus { outline: none; border-color: var(--accent); }
.tour__input-label { font-size: 0.95rem; font-weight: 600; color: var(--fg); }

/* "Obtain authorization token" button, success state: green check + green text.
   Stays full-strength even though it's disabled once the token is in hand. */
.tour__obtained,
.tour__obtained:disabled {
  opacity: 1;
  color: #2f9e44;
  border-color: #2f9e44;
  background: rgba(47, 158, 68, 0.14);
  cursor: default;
}
.tour__obtained-check { font-size: 1.25em; font-weight: 800; line-height: 1; }

/* Lifecycle strip (step 4): all phases in one full-width row; active is highlighted. */
.tour__lifecycle {
  display: flex;
  width: 100%;
  gap: 0.3rem;
  margin: 0 0 0.75rem;
}
.tour__stage {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.5rem 0.4rem;
  text-align: center;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--card-border);
  border-radius: 6px;
  opacity: 0.55;
}
.tour__stage.is-active { opacity: 1; color: #fff; }
.tour__stage.is-active[data-phase="none"] { background: var(--muted); border-color: var(--muted); }
.tour__stage.is-active[data-phase="provisioning"],
.tour__stage.is-active[data-phase="suspending"],
.tour__stage.is-active[data-phase="resuming"] { background: #b7791f; border-color: #b7791f; }
.tour__stage.is-active[data-phase="running"] { background: #2f9e44; border-color: #2f9e44; }
.tour__stage.is-active[data-phase="suspended"] { background: var(--muted); border-color: var(--muted); }
.tour__stage.is-active[data-phase="terminating"] { background: #e5484d; border-color: #e5484d; }

@media (max-width: 720px) {
  .tour__lifecycle { flex-wrap: wrap; }
  .tour__stage { flex: 1 1 30%; }
}

.tour__note { font-size: 0.95rem; color: var(--muted); margin: 0.35rem 0 0; }
.tour__note--warn { color: #ffb454; }

/* When the live status message rides inside the "MicroVM state" section title
   (step 4), render it inline and lighter than the bold label, wrapped in parens
   (added via ::before/::after) only when it carries text. */
.tour__section-label .tour__note { font-weight: 400; margin: 0; }
.tour__section-label .tour__note:not(:empty)::before { content: '('; }
.tour__section-label .tour__note:not(:empty)::after { content: ')'; }

/* Category heading above a group of step-4 controls ("MicroVM lifecycle
   controls", "MicroVM state", …). A top border rules a horizontal divider
   between the sections; the first one (marked --first) skips it. */
.tour__section-label {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--fg);
  margin: 1.25rem 0 0.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--card-border);
}
.tour__section-label--first {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* "Learn more" links on the congrats page — boxed cards in a responsive grid. */
.tour__links {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}
@media (max-width: 560px) {
  .tour__links { grid-template-columns: 1fr; }
}
.tour__link-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--card-border);
  background: var(--card-bg);
  border-radius: 10px;
  color: var(--fg);
  text-decoration: none;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.tour__link-box:hover {
  border-color: var(--accent);
  background: var(--card-bg-hover, var(--card-bg));
  transform: translateY(-1px);
}
.tour__link-label { font-weight: 600; font-size: 0.98rem; }
.tour__link-arrow { color: var(--accent); font-size: 1.05rem; flex: none; }

/* Obtained access token (step 4). */
.tour__token-wrap {
  margin: 0.25rem 0 0.6rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--card-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
}
.tour__token-label {
  display: block;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 0.3rem;
}
.tour__token {
  display: block;
  font-size: 0.85rem;
  color: var(--accent);
  word-break: break-all;
  line-height: 1.45;
}

/* Response (step 5). */
.tour__url {
  display: block;
  font-size: 0.9rem;
  color: var(--accent);
  word-break: break-all;
  margin: 0.25rem 0 0.6rem;
}
.tour__greeting {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--fg);
  min-height: 1.2em;
  margin-bottom: 0.5rem;
}
.tour__greeting:empty { display: none; }
.tour__greeting--error { color: #ff6b6b; font-size: 1rem; font-weight: 600; }
.tour__response {
  margin: 0;
  padding: 0.75rem 0.85rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9rem;
  color: #cdd3e0;
  background: #0c0e14;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  overflow-x: auto;
}
.tour__response:empty { display: none; }

.tour__congrats-icon { font-size: 2.6rem; text-align: center; margin-bottom: 0.5rem; }

/* Nav row pinned to the bottom of the tour column (margin-top:auto eats the free
   space above it). Three zones via a 1fr auto 1fr grid: Back left, the "take me to
   demos" skip centered, Next/Finish right. */
.tour__nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 1.1rem;
}
.tour__nav > :first-child { justify-self: start; } /* Back */
.tour__nav > :last-child { justify-self: end; } /* Next / Finish */
.tour__nav .tour__skip { justify-self: center; } /* wins over :last-child on congrats */
/* Match the "What are…" CTA button size (font + height). */
.tour__nav .btn { font-size: 1.15rem; padding: 1rem 1.8rem; }
.btn--ghost {
  color: var(--muted);
  background: transparent;
  border-color: transparent;
  font-weight: 500;
}
.btn--ghost:hover { color: var(--fg); }
/* The tour's "take me to demos" button gets the same white border as the What-tab one. */
.tour__skip { font-size: 0.95rem; border-color: #fff; }

@media (max-width: 560px) {
  .tour__flow-arrow { transform: rotate(90deg); width: 100%; }
  .tour__nav-spacer { flex-basis: 100%; }
}
