/*
  Kubify — split stage.

  Two grounds held side by side for the whole page: a light one for the thing
  you rent and a dark one for the machine you own. The divider between them is
  the page's only chrome, and it moves.

  One accent hue at two lightnesses. The page hard-cuts between a light ground
  and a dark one, and no single stop clears 4.5:1 on both.
*/

:root {
  --sc-canvas:     #0B0D10;
  --sc-surface:    #13161B;
  --sc-ink:        #F2F4F7;
  --sc-ink-soft:   #99A3B2;
  --sc-accent:     #6BA1FF;
  --sc-accent-ink: #0B0D10;

  --sc-font-display: "Archivo", ui-sans-serif, system-ui, sans-serif;
  --sc-font-text:    "Geist", ui-sans-serif, system-ui, sans-serif;
  --mono:            "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* The light ground, and the accent stop that clears 4.5:1 on it. */
  --paper:      #EFF1F4;
  --paper-deep: #E3E6EB;
  --paper-ink:  #14171C;
  --paper-soft: #545C68;
  --paper-line: #D2D7DE;
  --accent-on-paper: #1F5FD8;

  /* Where the divider sits, 0 to 1. Driven by the drag and by the install act. */
  --seam: 0.5;

  --seam-w: 1px;
  --edge: rgba(255, 255, 255, 0.07);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--sc-canvas);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.skip {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 60;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--sc-accent);
  color: var(--sc-accent-ink);
  font: 500 13px/1 var(--sc-font-text);
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.skip:focus-visible { transform: translateY(0); }

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--sc-accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── The divider, which is the chrome ──────────────────────────────────────
   Fixed for the whole page, because the comparison is the whole page. It
   carries the two labels and the argument's progress, and it can be dragged.  */

.seam {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
}

.seam__rule {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--seam) * 100%);
  width: var(--seam-w);
  background: linear-gradient(
    to bottom,
    rgba(107, 161, 255, 0.05),
    rgba(107, 161, 255, 0.5) 18%,
    rgba(107, 161, 255, 0.5) 82%,
    rgba(107, 161, 255, 0.05)
  );
  transform: translateX(-50%);
}

.seam__labels {
  position: absolute;
  top: clamp(18px, 3.4vh, 34px);
  left: calc(var(--seam) * 100%);
  display: flex;
  gap: 22px;
  transform: translateX(-50%);
  font: 500 11px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}
.seam__label--left  { color: var(--paper-soft); }
.seam__label--right { color: var(--sc-ink-soft); }

/* The grip sits at the vertical middle, where a hand goes looking for it. */
.seam__grip {
  position: absolute;
  top: 50%;
  left: calc(var(--seam) * 100%);
  width: 26px;
  height: 64px;
  margin: -32px 0 0 -13px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border-radius: 999px;
  border: 1px solid rgba(107, 161, 255, 0.34);
  background: color-mix(in srgb, var(--sc-canvas) 82%, transparent);
  backdrop-filter: blur(6px);
  cursor: ew-resize;
  pointer-events: auto;
  touch-action: none;
  transition: border-color 160ms cubic-bezier(0.23, 1, 0.32, 1),
              transform 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.seam__grip-rule {
  width: 1px;
  height: 18px;
  background: var(--sc-accent);
  opacity: 0.75;
}
@media (hover: hover) and (pointer: fine) {
  .seam__grip:hover { border-color: var(--sc-accent); transform: scale(1.06); }
}
.seam__grip:active { transform: scale(0.97); }

.seam__hint {
  position: absolute;
  top: calc(50% - 6px);
  left: calc(var(--seam) * 100% + 22px);
  margin: 0;
  font: 400 10px/1 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sc-ink-soft);
  opacity: 0.55;
  transition: opacity 200ms cubic-bezier(0.23, 1, 0.32, 1);
}
.seam.is-held .seam__hint,
.seam.is-gone .seam__hint { opacity: 0; }

/* The install act drives the seam off the edge, and the chrome goes with it. */
.seam.is-gone { opacity: 0; }
.seam { transition: opacity 320ms cubic-bezier(0.23, 1, 0.32, 1); }

/* ── The two grounds ──────────────────────────────────────────────────────── */

.act { position: relative; }

.split {
  display: grid;
  grid-template-columns: calc(var(--seam) * 100%) 1fr;
  min-height: 100vh;
  min-height: 100svh;
}

.pane {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
}

/* Restating colour, not only the token: `color` resolves on body and an
   inherited computed value does not change because a subtree redefines the
   variable it came from. */
.pane--left {
  --sc-ink: var(--paper-ink);
  --sc-ink-soft: var(--paper-soft);
  --sc-accent: var(--accent-on-paper);
  color: var(--paper-ink);
  background: var(--paper);
}
.pane--left::after {
  /* The light ground is not flat: real paper has a gradient toward the seam. */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, transparent 60%, rgba(0, 0, 0, 0.045));
  pointer-events: none;
}

.pane--right {
  background: var(--sc-canvas);
}
.pane--right::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 78% 18%, rgba(107, 161, 255, 0.07), transparent 62%);
  pointer-events: none;
}

.pane--quiet { opacity: 0.86; }

.pane__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 46ch;
  margin-inline: auto;
  padding: clamp(28px, 5vw, 76px) clamp(20px, 3.4vw, 54px);
}
.pane__inner--full { max-width: 64ch; }

/* ── Type ─────────────────────────────────────────────────────────────────── */

.display {
  font-family: var(--sc-font-display);
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.02;
  text-wrap: balance;
  margin: 0;
}
/* Two terms, not one: a pure vw ramp hits its cap early and then stops growing,
   which is why the hero read as small type marooned in a wide frame on a large
   monitor. The constant carries the small sizes, the vw carries the large ones. */
.display--lg { font-size: clamp(2.1rem, 2.18rem + 1.08vw, 4.5rem); }
.display--md { font-size: clamp(1.55rem, 1.35rem + 0.6vw, 2.6rem); }

.kicker {
  margin: 0 0 18px;
  font: 500 11px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.kicker--accent { color: var(--sc-accent); }

.body {
  margin: 20px 0 0;
  max-width: 42ch;
  color: var(--sc-ink-soft);
  font-size: clamp(0.95rem, 1.05vw, 1.05rem);
  line-height: 1.62;
  text-wrap: pretty;
}
.body--tight { margin-top: 26px; font-size: 0.9rem; }

/* Light on dark reads thin at the same metrics: one step more weight, a touch
   more leading and tracking on the dark side only. */
.pane--right .body { line-height: 1.68; letter-spacing: 0.004em; }

.aside {
  margin: 0;
  max-width: 30ch;
  color: var(--paper-soft);
  font-size: 0.92rem;
  line-height: 1.6;
}

.stack > * + * { margin-top: 22px; }

code {
  font-family: var(--mono);
  font-size: 0.92em;
  padding: 0.1em 0.38em;
  border-radius: 5px;
  background: color-mix(in srgb, currentColor 9%, transparent);
}

a { color: var(--sc-accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  margin: 42px 0 0;
  font-family: var(--sc-font-display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  color: var(--sc-ink);
}
/* The drawn mark is a stand-in. A real logo file replaces it the moment one exists,
   and site.js removes whichever of the two is not being used so neither ghosts. */
.wordmark__mark { display: inline-flex; color: var(--sc-accent); }
.wordmark__logo { display: block; height: auto; }
.wordmark--small { margin: 0; font-size: 0.9rem; }

/* ── Wide screens ──────────────────────────────────────────────────────────
   The grounds stay full-bleed, because they are the two halves of the page, and
   each column stays centred in the ground it belongs to. Pushing both columns at
   the divider was meant to put the comparison across it; what it actually did was
   collect every act into one clump in the middle of the screen, with the whole
   outer half of each ground left empty. The wider the monitor, the worse — which
   is how the install act, the one place that kept its centring, ended up being
   the only part of the page that looked placed. So: measure grows, position does
   not move. */

@media (min-width: 1500px) {
  .pane__inner { max-width: 52ch; }
}

/* ── Ledgers ──────────────────────────────────────────────────────────────── */

.ledger {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
}
.ledger li {
  padding: 13px 0;
  border-top: 1px solid var(--paper-line);
  color: var(--sc-ink-soft);
  font-size: 0.95rem;
  line-height: 1.5;
}
.ledger li:last-child { border-bottom: 1px solid var(--paper-line); }
.ledger span { color: var(--sc-ink); font-weight: 500; }
.ledger--dark li { border-color: rgba(255, 255, 255, 0.09); }

/* ── Facts ────────────────────────────────────────────────────────────────── */

.facts { margin: 30px 0 0; }
.facts > div {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 18px;
  padding: 14px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.facts > div:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.facts dt {
  font: 500 11px/1.5 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sc-accent);
}
.facts dd { margin: 0; color: var(--sc-ink-soft); font-size: 0.92rem; line-height: 1.55; }

.measure {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 20px;
  margin: 34px 0 0;
  padding: 22px 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
/* The number and its unit are one thing. As separate grid items the unit became a
   row of its own, with an "s" sitting under the figure. */
.measure__figure {
  display: flex;
  align-items: baseline;
}

.measure__n {
  font-family: var(--sc-font-display);
  font-weight: 600;
  font-size: clamp(2.4rem, 4vw, 3.6rem);
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--sc-ink);
  font-variant-numeric: tabular-nums;
}
.measure__u {
  font-family: var(--sc-font-display);
  font-weight: 600;
  font-size: 1.4rem;
  color: var(--sc-accent);
  margin-left: -6px;
}
.measure__what {
  color: var(--sc-ink-soft);
  font-size: 0.86rem;
  line-height: 1.5;
}

/* ── Screenshots ──────────────────────────────────────────────────────────── */

.shot { margin: 0; }
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--edge);
  box-shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.8), 0 2px 6px -2px rgba(0, 0, 0, 0.4);
  background: var(--sc-surface);
  /* A slot with nothing in it yet still holds its shape rather than collapsing
     the layout around it. */
  min-height: 120px;
}
.shot--left img {
  border-color: var(--paper-line);
  box-shadow: 0 22px 50px -28px rgba(20, 23, 28, 0.45), 0 2px 5px -2px rgba(20, 23, 28, 0.18);
  background: var(--paper-deep);
}
/* A slot waiting for its file. Sized like the image that will replace it, so the
   page does not reflow when one arrives. */
.shot--empty::before {
  content: attr(data-pending);
  display: flex;
  align-items: flex-end;
  aspect-ratio: 16 / 10;
  padding: 18px;
  border-radius: 12px;
  border: 1px dashed var(--paper-line);
  background:
    repeating-linear-gradient(
      -45deg,
      transparent 0 9px,
      color-mix(in srgb, currentColor 5%, transparent) 9px 10px
    );
  color: var(--sc-ink-soft);
  font: 400 12px/1.4 var(--mono);
}
.pane--right .shot--empty::before { border-color: rgba(255, 255, 255, 0.14); }

.shot figcaption {
  margin-top: 12px;
  font-size: 0.8rem;
  color: var(--sc-ink-soft);
  line-height: 1.5;
}
.shot--right { margin-top: 30px; }

/* ── The install act ──────────────────────────────────────────────────────── */

.act--install .split { align-items: stretch; }

.term {
  margin-top: 26px;
  border-radius: 12px;
  border: 1px solid var(--paper-line);
  background: #0E1116;
  overflow: hidden;
  box-shadow: 0 26px 60px -34px rgba(20, 23, 28, 0.55);
}
.term__bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 11px 14px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: #151A21;
}
.term__bar span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
}
.term__title {
  margin: 0 0 0 8px;
  font: 400 10px/1 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.34);
}
.term__body {
  margin: 0;
  padding: 18px 16px 22px;
  min-height: 15.5em;
  font-family: var(--mono);
  font-size: clamp(0.66rem, 0.82vw, 0.78rem);
  line-height: 1.75;
  color: #DCE3EC;
  white-space: pre-wrap;
  word-break: normal;
  overflow-wrap: break-word;
}
.term__body code { background: none; padding: 0; font-size: inherit; }
.term__prompt { color: #6BA1FF; }
.term__caret {
  display: inline-block;
  width: 7px;
  height: 1em;
  margin-left: 1px;
  background: #6BA1FF;
  vertical-align: text-bottom;
  animation: blink 1.05s steps(2, start) infinite;
}
.term.is-done .term__caret { animation: none; opacity: 0.25; }
@keyframes blink { to { visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { .term__caret { animation: none; } }

.term__out { color: #8B96A5; }
.term__out b { color: #DCE3EC; font-weight: 500; }
.term__out i { color: #7BD88F; font-style: normal; }

/* The cluster answers. Nodes arrive as their line of output lands. */
.cluster {
  width: 100%;
  max-width: 640px;
  height: auto;
  margin-top: 26px;
  color: var(--sc-accent);
}
.cluster__ns {
  fill: rgba(107, 161, 255, 0.03);
  stroke: rgba(107, 161, 255, 0.22);
  stroke-dasharray: 5 5;
}
.cluster__nslabel {
  fill: var(--sc-ink-soft);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.cluster__nodes .node,
.cluster__wires path {
  opacity: 0;
  transition: opacity 260ms cubic-bezier(0.23, 1, 0.32, 1),
              transform 320ms cubic-bezier(0.23, 1, 0.32, 1);
}
.cluster__nodes .node { transform-box: fill-box; transform-origin: 50% 50%; }
.cluster__nodes .node.is-up { opacity: 1; }
.cluster__wires path { stroke: rgba(107, 161, 255, 0.45); }
.cluster__wires path.is-up { opacity: 1; }
.node rect {
  fill: #161B22;
  stroke: rgba(107, 161, 255, 0.4);
  stroke-width: 1;
}
.node.is-up rect { fill: #182030; }
.node text {
  fill: var(--sc-ink);
  font-family: var(--mono);
  font-size: 12px;
}
.node__sub { fill: var(--sc-ink-soft); font-size: 10px; }
.node__sub--end { text-anchor: end; }
.node--wide rect { fill: rgba(107, 161, 255, 0.1); stroke: rgba(107, 161, 255, 0.55); }
.node--wide text { fill: var(--sc-accent); }

@media (prefers-reduced-motion: reduce) {
  .cluster__nodes .node,
  .cluster__wires path { transition-duration: 1ms; }
}

/* The arrival: the diagram becomes the panel. Absolutely placed over the cluster so
   the cross-fade happens in one spot rather than as a layout change. */
.arrival {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: clamp(16px, 3vw, 48px);
  opacity: 0;
  pointer-events: none;

  /* No transition: opacity and transform are written from scroll position every
     frame, and a duration on top of that fights the hand. */
  will-change: opacity, transform;
}
.arrival img {
  /* Bounded on both axes, and scaled to the screen rather than to a fixed number.
     A flat 1180px cap meant the page's biggest moment rendered at a third of the
     width of an ultrawide: a small bright island in a very large dark field.
     Never wider than the file itself, so it is never upscaled into softness.

     Both bounds are maxima, which is the whole point. A fixed width with a
     capped height is not a smaller picture, it is a squashed one: the height
     clamps, the width does not, and at a laptop's proportions that took a fifth
     out of the vertical. The page's biggest moment was the one thing on it
     rendered at the wrong shape. */
  max-width: min(86vw, 3036px);
  max-height: 82svh;
  width: auto;
  height: auto;
  border-radius: 14px;
  border: 1px solid rgba(107, 161, 255, 0.28);
  box-shadow: 0 50px 120px -50px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(255, 255, 255, 0.03);
  transform: scale(0.985);
}
.act--install .pane--left .pane__inner { transition: opacity 260ms cubic-bezier(0.23, 1, 0.32, 1); }
.act--install.is-collapsing .pane--left .pane__inner { opacity: 0; }

/* The arrival is absolutely placed over the whole pane, so it is already full width
   and nothing about the column's measure has to change as it appears. Widening the
   inner at a threshold reflowed the text underneath, which is a layout jump wearing a
   fade. */
.act--install .pane--right { position: relative; background: transparent; }

/* The radial wash belongs to panes with no ground of their own; over the clip it
   is one gradient too many. */
.act--install .pane--right::after { content: none; }

@media (prefers-reduced-motion: reduce) {
  .arrival, .arrival img { transition-duration: 1ms; }
}

/* ── The ground ───────────────────────────────────────────────────────────
   A clip is a ground when it stops resolving as footage and starts reading as
   texture, and the difference is almost entirely in how hard it is pushed. Held
   low, blended additively so only the light in it survives, and tinted to the
   page's one hue so it belongs here rather than sitting on top looking borrowed.

   The clip is a border loop, so its own composition does the work a scrim would
   otherwise have to: the activity is at the edges and the middle stays dark,
   which is where every line of text on these two sections sits.                */

.ground {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;

  /* Hidden until the page asks for it. Driven from scroll in site.js rather than by a
     class, so it arrives with the panel instead of switching on beside it. */
  opacity: 0;
}

/* Everything in the document sits above the fixed ground. The sections that should not
   show it are opaque, which is most of them; the two at the end are not. */
.act { z-index: 1; }

.ground__clip {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.68;

  /* Pushed in slightly. The clip's activity lives at its edges, so a box wide
     enough to show the whole frame shows mostly the empty middle: on the close,
     which is full width, it read as nothing at all. */
  transform: scale(1.18);

  /* Additive: the particles are light on black, so screen keeps them and drops
     the black entirely. A plain overlay would lay a grey rectangle over the
     ground and flatten it. */
  mix-blend-mode: screen;
}

/* One hue for the page, including this. Without it the ground is the only
   neutral thing on a cobalt site and reads as stock footage. */
/* A column of density where the reading is, rather than a wash over everything.
   A blanket vignette protected text that was never at risk and flattened the clip
   everywhere else, which is the whole reason to have it. */
.ground__tint {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to right,
      transparent,
      rgba(11, 13, 16, 0.88) 18%,
      rgba(11, 13, 16, 0.92) 50%,
      rgba(11, 13, 16, 0.88) 82%,
      transparent
    ),
    linear-gradient(to bottom, rgba(107, 161, 255, 0.18), rgba(107, 161, 255, 0.05));
}

/* Motion in the background is the first thing to go, and the poster is a frame of
   the same clip, so nothing about the composition changes. */
@media (prefers-reduced-motion: reduce) {
  .ground__clip { display: none; }
  .ground { background: url("assets/ground-poster.52f7faae.jpg") center / cover no-repeat; }
}

/* ── The close ────────────────────────────────────────────────────────────── */

/* Transparent so the ground shows through. The canvas colour is on the body, and
   the tint above the clip supplies the rest. */
.act--close { background: transparent; }
.close {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 92vh;
  min-height: 92svh;
}
.close__inner {
  width: 100%;
  max-width: 68ch;
  margin-inline: auto;
  padding: clamp(40px, 7vh, 96px) clamp(20px, 4vw, 48px);
}

/* The two questions. Real radios, moved out of sight rather than removed: a
   `display: none` input is not focusable and not announced, and then the chips
   are decorations that happen to be clickable. Left where they are, the group
   answers to arrow keys and reads as a group, and everything visible is the
   label. */

.wizard { margin: 34px 0 0; }

.pick { margin: 0; padding: 0; border: 0; }
.pick + .pick { margin-top: 22px; }
.pick__legend {
  padding: 0;
  font: 500 11px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.pick__row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 13px;
}
.pick__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--sc-ink-soft);
  font: 500 13px/1 var(--sc-font-text);
  cursor: pointer;
  transition: border-color 140ms cubic-bezier(0.23, 1, 0.32, 1),
              color 140ms cubic-bezier(0.23, 1, 0.32, 1),
              background-color 140ms cubic-bezier(0.23, 1, 0.32, 1);
}
@media (hover: hover) and (pointer: fine) {
  .chip:hover { border-color: rgba(255, 255, 255, 0.3); color: var(--sc-ink); }
}
.pick__input:checked + .chip {
  border-color: rgba(107, 161, 255, 0.55);
  background: color-mix(in srgb, var(--sc-accent) 13%, transparent);
  color: var(--sc-accent);
}
/* The outline belongs to the label, because the input it belongs to is a pixel
   in the corner and nobody would see it there. */
.pick__input:focus-visible + .chip {
  outline: 2px solid var(--sc-accent);
  outline-offset: 2px;
}

/* The command is the answer to the questions above it, so it sits closer to them
   than the default gap, and it is the only thing between them and the small print. */
.wizard + .command { margin-top: 26px; }

.command {
  position: relative;
  margin: 30px 0 0;
  border-radius: 12px;
  border: 1px solid rgba(107, 161, 255, 0.28);
  background: #0E1116;
  overflow: hidden;
}
.command pre {
  margin: 0;
  padding: 22px 20px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: clamp(0.68rem, 0.85vw, 0.8rem);
  line-height: 1.8;
  color: #DCE3EC;
}
.command code { background: none; padding: 0; font-size: inherit; }

.copy {
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(107, 161, 255, 0.34);
  background: color-mix(in srgb, var(--sc-canvas) 84%, transparent);
  color: var(--sc-accent);
  font: 500 12px/1 var(--sc-font-text);
  cursor: pointer;
  transition: border-color 140ms cubic-bezier(0.23, 1, 0.32, 1),
              transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
}
@media (hover: hover) and (pointer: fine) {
  .copy:hover { border-color: var(--sc-accent); }
}
.copy:active { transform: translateY(1px); }
.copy.is-done { color: #7BD88F; border-color: rgba(123, 216, 143, 0.45); }

.fine {
  margin: 24px 0 0;
  max-width: 58ch;
  color: var(--sc-ink-soft);
  font-size: 0.84rem;
  line-height: 1.6;
}

.foot {
  display: flex;
  flex-wrap: wrap;

  /* Centred, not baseline-aligned. A baseline is a property of text, and the wordmark
     is a flex box with a picture in it — the browser takes the bottom of the image as
     its baseline, which sat the sentence a few pixels below the name it was meant to
     line up with. Two short things of different heights on one line want their middles
     matched anyway. */
  align-items: center;
  justify-content: space-between;
  gap: 12px 32px;
  margin-top: 56px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.foot__note {
  margin: 0;
  color: var(--sc-ink-soft);
  font-size: 0.8rem;

  /* Flush to the right edge, which is the only edge it shares with anything. Left
     alignment put its start at wherever the sentence happened to begin, lining up with
     nothing on either side. */
  text-align: right;
}

@media (max-width: 860px) {
  /* Stacked, there is no right edge to be flush with and the eye wants the two lines
     to start together. */
  .foot__note { text-align: left; }
}

/* ── Phone ────────────────────────────────────────────────────────────────
   A split stage has nowhere to put two columns on a 390px screen, so the two
   grounds stack and the seam becomes a horizontal rule between them. The
   comparison survives; the geometry does not have to.                        */

@media (max-width: 860px) {
  .seam__rule,
  .seam__grip,
  .seam__hint { display: none; }

  /* A fixed label over a scrolling column lands on top of a sentence sooner or
     later. Stacked, each ground can say what it is inside itself. */
  .seam__labels { display: none; }

  .pane::before {
    position: absolute;
    top: 18px;
    left: 22px;
    z-index: 2;
    font: 500 10px/1 var(--mono);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.75;
  }
  .pane--left::before  { content: "Rented"; color: var(--paper-soft); }
  .pane--right::before { content: "Yours"; color: var(--sc-ink-soft); }
  .act--install .pane::before,
  .act--close .pane::before { content: none; }

  .split {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .pane { min-height: 62svh; }
  .pane--left::after { background: linear-gradient(to bottom, transparent 70%, rgba(0, 0, 0, 0.05)); }
  .pane__inner { max-width: none; padding: clamp(32px, 9vw, 52px) 22px; }

  .display--lg { font-size: clamp(1.9rem, 7.6vw, 2.5rem); }
  .facts > div { grid-template-columns: 1fr; gap: 4px; }
  .act--install .pane { min-height: 0; }
  .term__body { min-height: 13em; }
}
