/*
 * Veltax — veltax.tensoractivity.com.
 *
 * A copy of TensorActivity's stylesheet (/var/TensorActivity/site/assets/
 * style.css, as of 2026-10-09), so Veltax's pages look like they come from the
 * company that makes it, and a rule-set of Veltax's own at the end
 * ("Veltax"). A copy rather than a link to tensoractivity.com: a font asked for
 * across origins needs CORS headers that site does not send, and this site
 * should not break when that one changes. The reasoning for every rule above
 * the Veltax section is in the original's comments; the ones that matter most:
 *
 * Tokens first, and components only ever use tokens. Dark mode is a second set
 * of token values, never a second set of components.
 *
 * Orange is a surface with dark text on it, or a small mark — never text.
 * #fb6302 on the light ground is 2.92:1, which fails WCAG even for large text.
 * Where orange has to be read, it is --brand-ink.
 *
 * Bump ?v=N in every page whenever this file changes: it is cached for a day.
 */

@font-face {
  font-family: "Inter Tight";
  src: url("/assets/fonts/intertight-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: optional;
}

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: light dark;

  --bg: #fbfaf8;
  --bg-2: #f3f1ed;
  --surface: #ffffff;
  --surface-2: #f7f5f2;
  --line: #e7e3dc;
  --line-2: #d8d2c8;

  --text: #15130f;
  --text-2: #57514a;
  --text-3: #6f685f;

  --brand: #fb6302;
  --brand-ink: #b64a00;
  --brand-soft: #fff1e6;
  --on-brand: #15130f;

  --danger: #b42318;
  --danger-soft: #fef3f2;
  --danger-line: #f5c2bd;
  --on-danger: #ffffff;
  --ok: #067647;
  --ok-soft: #e8f6ee;

  /* The dark band the homepage ends on, and toasts. Dark in both themes. */
  --stage: #15130f;
  --stage-text: #f4f1ec;
  --stage-text-2: #b5ada3;
  --stage-line: rgb(255 255 255 / .14);

  --shadow-sm: 0 1px 2px rgb(21 19 15 / .06);
  --shadow: 0 1px 2px rgb(21 19 15 / .05), 0 12px 32px -12px rgb(21 19 15 / .18);
  --shadow-lg: 0 2px 4px rgb(21 19 15 / .04), 0 28px 64px -24px rgb(21 19 15 / .30);

  --font: "Inter Tight", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --r-sm: 8px;
  --r: 12px;
  --r-lg: 18px;
  --r-pill: 999px;

  --page: 72rem;
  --gutter: clamp(1rem, 4vw, 2rem);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b0a09;
    --bg-2: #11100e;
    --surface: #161412;
    --surface-2: #1d1a17;
    --line: #2a2622;
    --line-2: #3a342e;

    --text: #f4f1ec;
    --text-2: #b5ada3;
    --text-3: #938a80;

    --brand: #ff7a1f;
    --brand-ink: #ff9a52;
    --brand-soft: rgb(255 122 31 / .12);
    --on-brand: #15130f;

    --danger: #f97066;
    --danger-soft: rgb(249 112 102 / .10);
    --danger-line: rgb(249 112 102 / .35);
    --on-danger: #15130f;
    --ok: #47cd89;
    --ok-soft: rgb(71 205 137 / .12);

    --stage: #161412;
    --stage-line: #2a2622;

    --shadow-sm: 0 1px 2px rgb(0 0 0 / .5);
    --shadow: 0 1px 2px rgb(0 0 0 / .4), 0 12px 32px -12px rgb(0 0 0 / .7);
    --shadow-lg: 0 2px 4px rgb(0 0 0 / .4), 0 28px 64px -24px rgb(0 0 0 / .85);
  }
}

/* -------------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 1rem/1.6 var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.02em; line-height: 1.15; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; }
code, .mono { font-family: var(--mono); font-size: .875em; }
::selection { background: var(--brand); color: var(--on-brand); }

:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }

[hidden] { display: none !important; }

.container { width: 100%; max-width: var(--page); margin-inline: auto; padding-inline: var(--gutter); }

.skip { position: absolute; left: -9999px; top: 0; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.skip:focus { left: 1rem; top: 1rem; z-index: 100; padding: .5rem .875rem; border-radius: var(--r-sm); background: var(--surface); box-shadow: var(--shadow); }

.muted { color: var(--text-2); }
.fine { font-size: .875rem; color: var(--text-3); }

/* An icon from a page's <symbol> sprite. Stroke, not fill, so one set of
   paths serves every size and both themes through currentColor. */
.i { width: 1.25rem; height: 1.25rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

/* ------------------------------------------------------------------ header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.site-header .container { display: flex; align-items: center; gap: 1rem; height: 4rem; }

/* The mark keeps its hard corners: it is the favicon too, and softening it
   here would make the two disagree about what the logo is. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: .625rem;
  color: var(--text);
  font-weight: 650;
  font-size: 1.0625rem;
  letter-spacing: -.02em;
  text-decoration: none;
}
.brand svg { width: 1.75rem; height: 1.75rem; }

.nav { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.nav > a:not(.btn) {
  padding: .5rem .75rem;
  border-radius: var(--r-sm);
  color: var(--text-2);
  font-size: .9375rem;
  font-weight: 500;
  text-decoration: none;
}
.nav > a:not(.btn):hover { color: var(--text); background: var(--bg-2); }
.nav > .btn:first-of-type { margin-left: .5rem; }
@media (max-width: 44rem) { .nav .hide-sm { display: none; } }
@media (max-width: 26rem) { .nav .hide-xs { display: none; } }

/* ----------------------------------------------------------------- buttons */

.btn {
  --btn-bg: var(--text);
  --btn-fg: var(--bg);
  --btn-line: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  height: 2.5rem;
  padding-inline: 1.125rem;
  border: 1px solid var(--btn-line);
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: 550 .9375rem/1 var(--font);
  letter-spacing: -.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .06s ease;
}
/* Ink at rest, orange under the pointer: the mark's own logic — a dark shape
   on an orange field — and the accent appears exactly where somebody is
   already looking. */
.btn:hover { --btn-bg: var(--brand); --btn-fg: var(--on-brand); }
.btn:active { transform: translateY(1px); }
.btn .i { width: 1.125rem; height: 1.125rem; }

.btn-lg { height: 3rem; padding-inline: 1.5rem; font-size: 1rem; }
.btn-sm { height: 2.125rem; padding-inline: .875rem; font-size: .875rem; }

.btn-secondary { --btn-bg: var(--surface); --btn-fg: var(--text); --btn-line: var(--line-2); box-shadow: var(--shadow-sm); }
.btn-secondary:hover { --btn-bg: var(--bg-2); --btn-fg: var(--text); --btn-line: var(--line-2); }

.btn-ghost { --btn-bg: transparent; --btn-fg: var(--text); }
.btn-ghost:hover { --btn-bg: var(--bg-2); --btn-fg: var(--text); }

.btn-danger { --btn-bg: var(--danger); --btn-fg: var(--on-danger); }
.btn-danger:hover { --btn-bg: var(--danger); --btn-fg: var(--on-danger); filter: brightness(.92); }

.btn-danger-ghost { --btn-bg: transparent; --btn-fg: var(--danger); --btn-line: var(--line-2); }
.btn-danger-ghost:hover { --btn-bg: var(--danger-soft); --btn-fg: var(--danger); --btn-line: var(--danger-line); }

.btn[disabled], .btn[aria-busy="true"] { opacity: .65; pointer-events: none; }

.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ pieces */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  height: 1.5rem;
  padding-inline: .5625rem;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-2);
  color: var(--text-2);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .005em;
  white-space: nowrap;
  vertical-align: middle;
}
.badge-ok { color: var(--ok); background: var(--ok-soft); border-color: transparent; }
.badge-brand { color: var(--brand-ink); background: var(--brand-soft); border-color: transparent; }
.badge-dot::before { content: ""; width: .375rem; height: .375rem; border-radius: 50%; background: currentColor; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }

.avatar {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 650;
  font-size: 1.0625rem;
  line-height: 1;
}

.icon-chip {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  border-radius: 10px;
  background: var(--brand-soft);
  color: var(--brand-ink);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3125rem .875rem .3125rem .5rem;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: var(--text-2);
  font-size: .8125rem;
  font-weight: 550;
  text-decoration: none;
}
.eyebrow:hover { color: var(--text); border-color: var(--line-2); }
/* A square, not a dot: the mark reduced to its field. */
.eyebrow .dot { width: .5rem; height: .5rem; background: var(--brand); }


.actions { display: flex; flex-wrap: wrap; gap: .75rem; }

/* -------------------------------------------------------------------- hero */

/* Nothing here clips the hero itself: the account card's shadow reaches
   further down than the hero's bottom padding, and clipping it drew a hard
   line across the page. The glow and the waves stay inside the hero's box on
   their own instead. */
.hero { position: relative; isolation: isolate; padding-block: clamp(3.5rem, 9vw, 7rem) clamp(2.5rem, 5vw, 3.5rem); }
/* The hero's own bottom padding and the next section's top padding would
   otherwise stack into a gap bigger than either was meant to be. */
.hero + .section { padding-top: clamp(2.5rem, 6vw, 4.5rem); }

/* The grid, as two sets of waves flowing through it slowly: horizontal lines
   rippling left to right, vertical lines top to bottom. Each set is one SVG
   pattern tile, 448px (eight 56px cells) per wavelength, 12px amplitude,
   drawn once, on an <svg> one wavelength longer than the hero. The animation
   slides that <svg> by exactly one wavelength and starts again, which lands on
   a frame identical to the first, so the loop has no seam. Sliding a sine
   wave along itself is what a travelling wave is: every point on a line rises
   and falls as a crest passes. On top of that, each set swells, a few pixels
   across the line and back every seven or nine seconds, on `translate`, a
   property of its own, so it adds to the slide rather than replacing it.

   Only `transform` moves, so the browser composites a picture it already has
   and repaints nothing. The rejected ways all repaint the whole hero every
   frame: animating `background-position`, animating the path's `d`, or an
   feTurbulence displacement (what the previous site's noise field cost).
   What it does cost: two GPU layers, each the hero plus one wavelength (34 MB
   together on a 2x screen, measured), and compositor frames while the hero is
   on screen. Reduced motion stops it (bottom of
   this file), leaving still waves. */
.waves {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  color: var(--line-2);
  pointer-events: none;
  -webkit-mask-image: radial-gradient(ellipse 62% 75% at 75% 35%, #000 12%, transparent 72%);
  mask-image: radial-gradient(ellipse 62% 75% at 75% 35%, #000 12%, transparent 72%);
}
.waves svg { position: absolute; max-width: none; will-change: transform; }
.waves path { fill: none; stroke: currentColor; stroke-width: 1; }
.waves .waves-x { top: 0; left: -448px; width: calc(100% + 448px); height: 100%; animation: wave-x 28s linear infinite, swell-x 7s ease-in-out infinite alternate; }
.waves .waves-y { top: -448px; left: 0; width: 100%; height: calc(100% + 448px); animation: wave-y 36s linear infinite, swell-y 9s ease-in-out infinite alternate; }
@keyframes wave-x { to { transform: translateX(448px); } }
@keyframes wave-y { to { transform: translateY(448px); } }
@keyframes swell-x { from { translate: 0 -6px; } to { translate: 0 6px; } }
@keyframes swell-y { from { translate: -6px 0; } to { translate: 6px 0; } }
/* On a phone the desktop grid reads as zoomed in (the owner's word): 56px
   cells make seven columns across a 390px screen. Below 40rem the picture is
   drawn at 0.6, so 34px cells and a 7px amplitude. `scale` applies after the
   sliding `transform`, so the slide shrinks with it and one wavelength is
   still exactly one loop. The <svg> is made 1/0.6 as large to cover the hero
   plus the smaller wavelength (268.8px), and the stroke 1/0.6 as wide so the
   lines stay one pixel. */
@media (max-width: 40rem) {
  .waves .waves-x, .waves .waves-y { scale: .6; transform-origin: 0 0; }
  .waves .waves-x { left: -268.8px; width: calc((100% + 268.8px) / .6); height: calc(100% / .6); }
  .waves .waves-y { top: -268.8px; width: calc(100% / .6); height: calc((100% + 268.8px) / .6); }
  .waves path { stroke-width: 1.6667; }
}
/* The same glow as before, a 26rem circle centred 10rem in from the right
   and 6rem down, now drawn on a box the size of the hero and faded out
   before its bottom edge, so a tall hero on a phone ends in nothing rather
   than in a cut. */
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: radial-gradient(circle 26rem at calc(100% - 10rem) 6rem, rgb(251 99 2 / .20), rgb(251 99 2 / 0));
  -webkit-mask-image: linear-gradient(#000 55%, transparent);
  mask-image: linear-gradient(#000 55%, transparent);
}

.hero-grid { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); gap: clamp(3rem, 6vw, 5rem); align-items: center; }
@media (max-width: 60rem) { .hero-grid { grid-template-columns: 1fr; } }

.hero h1 { font-size: clamp(2.75rem, 7vw, 5.25rem); font-weight: 650; line-height: .98; letter-spacing: -.048em; }

/* TensorActivity, TensorCloud, TensorNotes, TensorOne: played once, ending
   on the last. The four words share one grid cell, so "Tensor" never moves
   and the cell is as wide as "Activity" throughout. Each word leaves upward
   as the next arrives from below, 1.8s apart. Under reduced motion the rule
   at the bottom of this file shortens every animation to nothing but keeps
   its delay, so the words change in place, at the same moments, unmoving. */
/* Sized to its column, not the window: "TensorActivity" on one line is about
   six times its font size wide, so 16% of the column fills it at every width,
   two columns or one, 320px or 1440px. A browser without container units
   drops the declaration and keeps the ".hero h1" size above. */
.hero-copy { container-type: inline-size; }
.hero .wordmark { font-size: clamp(2.5rem, 16cqi, 5.5rem); white-space: nowrap; }
/* On a phone, filling the column edge to edge read as zoomed in: about 43px
   on a 390px screen, three quarters of the width, instead of 57px. */
@media (max-width: 40rem) { .hero .wordmark { font-size: clamp(2.25rem, 12cqi, 3rem); } }
.swap { display: inline-grid; }
.swap > span { grid-area: 1 / 1; }
.swap > span:nth-child(1) { animation: word-out .7s cubic-bezier(.65, 0, .35, 1) 1.8s forwards; }
.swap > span:nth-child(2) { animation: word-in .7s cubic-bezier(.65, 0, .35, 1) 1.8s both, word-out .7s cubic-bezier(.65, 0, .35, 1) 3.6s forwards; }
.swap > span:nth-child(3) { animation: word-in .7s cubic-bezier(.65, 0, .35, 1) 3.6s both, word-out .7s cubic-bezier(.65, 0, .35, 1) 5.4s forwards; }
.swap > span:nth-child(4) { animation: word-in .7s cubic-bezier(.65, 0, .35, 1) 5.4s both; }
@keyframes word-in { from { opacity: 0; transform: translateY(.45em); filter: blur(8px); } }
@keyframes word-out { to { opacity: 0; transform: translateY(-.45em); filter: blur(8px); } }

/* Orange under the words rather than in them: dark text on an orange bar
   passes contrast in both themes, and orange text would not. */
.hl { box-shadow: inset 0 -.2em 0 var(--brand); }

.lead { max-width: 34rem; margin-top: 1.5rem; color: var(--text-2); font-size: clamp(1.125rem, 1.7vw, 1.3125rem); line-height: 1.55; }
.hero .actions { margin-top: 2rem; }
.hero .fine { margin-top: 1.125rem; }

/* The account card: who is signed in, and the apps that account signs in to.
   Signed out, it reads "Your account" beside a person icon; signed in, the
   first name from the site's hint beside its initial. index.html says why
   the app list is written in the page. */
.acct { position: relative; width: 100%; max-width: 25rem; margin-inline: auto; padding: 1rem; border: 1px solid var(--line); border-radius: 22px; background: var(--surface); box-shadow: var(--shadow-lg); animation: rise .6s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }

.acct-head { display: flex; align-items: center; gap: .875rem; padding: .5rem .5rem 1.125rem; }
.acct-avatar { width: 3rem; height: 3rem; font-size: 1.25rem; }
.acct-avatar .i { width: 1.375rem; height: 1.375rem; }
.acct-avatar [data-account-initial]:empty,
.acct-avatar [data-account-initial]:not(:empty) + .i { display: none; }
.acct-name { min-width: 0; overflow: hidden; font-size: 1.25rem; font-weight: 600; letter-spacing: -.02em; text-overflow: ellipsis; white-space: nowrap; }

.acct-label { padding: 1rem .5rem .375rem; border-top: 1px solid var(--line); color: var(--text-3); font-size: .75rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; }
.acct-apps { list-style: none; padding: 0; }
.acct-app { display: flex; align-items: center; gap: .875rem; padding: .625rem .5rem; border-radius: var(--r); color: inherit; text-decoration: none; }
.acct-app > span:nth-child(2) { flex: 1; min-width: 0; }
.acct-app b { display: block; font-weight: 600; font-size: .9375rem; }
.acct-app small { display: block; color: var(--text-3); font-size: .8125rem; }
a.acct-app { transition: background-color .15s ease; }
a.acct-app:hover { background: var(--surface-2); }
a.acct-app:hover .tile-letter { border-color: transparent; background: var(--brand); color: var(--on-brand); }

.tile-letter { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; flex: none; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-2); color: var(--text); font-weight: 650; font-size: .9375rem; transition: background-color .15s ease, color .15s ease, border-color .15s ease; }

/* ---------------------------------------------------------------- sections */

.section { padding-block: clamp(4rem, 9vw, 7rem); }
.section-title { margin-bottom: clamp(1.5rem, 3vw, 2rem); font-size: clamp(2rem, 4.2vw, 3rem); line-height: 1.04; letter-spacing: -.038em; }

/* Four apps, one line each. The whole card is the link where there is one:
   the link's ::after covers the card, so there is one tab stop and one thing
   a screen reader announces, not a card wrapping a link. */
.apps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 64rem) { .apps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .apps { grid-template-columns: 1fr; } }
.app { position: relative; display: flex; flex-direction: column; gap: 1.75rem; padding: 1.25rem; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.app:has(.app-link):hover { border-color: var(--line-2); box-shadow: var(--shadow); transform: translateY(-2px); }
.app:has(.app-link):hover .tile-letter { border-color: transparent; background: var(--brand); color: var(--on-brand); }
.app:has(.app-link:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
.app-top { display: flex; align-items: center; gap: .875rem; }
.app-top .tile-letter { width: 3rem; height: 3rem; border-radius: 14px; font-size: 1.125rem; }
.app h3 { font-size: 1.125rem; letter-spacing: -.02em; }
.app-kind { color: var(--text-3); font-size: .875rem; }
.app-foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-top: auto; }
.app-link { display: inline-flex; align-items: center; gap: .375rem; color: var(--text); font-size: .875rem; font-weight: 600; text-decoration: none; }
.app-link::after { content: ""; position: absolute; inset: 0; border-radius: var(--r-lg); }
.app-link:focus-visible { outline: none; }
.app-link .i { width: 1rem; height: 1rem; transition: transform .15s ease; }
.app:hover .app-link .i { transform: translateX(3px); }

/* The dark band the page ends on, kept at the owner's request on 2026-10-08.
   Straight after the apps, so the two sections' paddings would stack into a
   gap twice the size of either: this one starts at its card. */
.section + .section { padding-top: 0; }
.cta { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 2rem; padding: clamp(2.25rem, 6vw, 4.5rem); border: 1px solid var(--stage-line); border-radius: 28px; background: var(--stage); color: var(--stage-text); }
.cta::before { content: ""; position: absolute; z-index: -1; right: -12rem; bottom: -26rem; width: 44rem; height: 44rem; border-radius: 50%; background: radial-gradient(closest-side, rgb(251 99 2 / .42), rgb(251 99 2 / 0)); }
.cta h2 { max-width: 34rem; font-size: clamp(2rem, 4.5vw, 3.25rem); line-height: 1.02; letter-spacing: -.042em; }
.cta p { max-width: 32rem; margin-top: 1rem; color: var(--stage-text-2); font-size: 1.125rem; }
.cta .btn { --btn-bg: var(--stage-text); --btn-fg: var(--stage); }
.cta .btn:hover { --btn-bg: var(--brand); --btn-fg: var(--on-brand); }
.cta .btn-outline { --btn-bg: transparent; --btn-fg: var(--stage-text); --btn-line: var(--stage-line); }
.cta .btn-outline:hover { --btn-bg: rgb(255 255 255 / .08); --btn-fg: var(--stage-text); --btn-line: var(--stage-text-2); }

/* ---------------------------------------------------------------- documents */

.doc-hero { padding-block: clamp(3rem, 7vw, 5rem) clamp(2rem, 4vw, 2.75rem); border-bottom: 1px solid var(--line); background: var(--bg-2); }
.doc-hero h1 { margin-top: 1.25rem; font-size: clamp(2.25rem, 5.5vw, 3.75rem); line-height: 1.02; letter-spacing: -.042em; }
.doc-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; margin-top: 1rem; color: var(--text-3); font-size: .9375rem; }

.doc-layout { display: grid; grid-template-columns: 14rem minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); padding-block: clamp(2.5rem, 5vw, 3.5rem) 5rem; }
@media (max-width: 60rem) { .doc-layout { grid-template-columns: 1fr; } .toc { display: none; } }

.toc { position: sticky; top: 5.5rem; align-self: start; font-size: .875rem; }
.toc-title { margin-bottom: .75rem; color: var(--text-3); font-size: .75rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; }
.toc ol { list-style: none; padding: 0; border-left: 1px solid var(--line); }
.toc a { display: block; margin-left: -1px; padding: .3125rem 0 .3125rem .875rem; border-left: 1px solid transparent; color: var(--text-2); line-height: 1.4; text-decoration: none; }
.toc a:hover { color: var(--text); border-left-color: var(--brand); }

.prose { max-width: 44rem; font-size: 1.0625rem; line-height: 1.75; }
.prose > * + * { margin-top: 1rem; }
.prose h2 { margin-top: 2.75rem; font-size: 1.375rem; letter-spacing: -.02em; scroll-margin-top: 5.5rem; }
.prose h2 + * { margin-top: .75rem; }
.prose p, .prose ul { color: var(--text-2); }
.prose ul { padding-left: 1.25rem; }
.prose li + li { margin-top: .5rem; }
.prose li::marker { color: var(--brand); }
.prose strong { color: var(--text); font-weight: 600; }
.prose a { color: var(--text); text-decoration-color: var(--brand); text-decoration-thickness: 2px; text-underline-offset: 3px; }
.prose a:hover { color: var(--brand-ink); }

.callout { padding: 1.125rem 1.25rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); box-shadow: var(--shadow-sm); }
.callout-brand { border-color: transparent; background: var(--brand-soft); }
.prose .callout p { color: var(--text); }

/* ------------------------------------------------------------------ footer */

.site-footer { padding-block: 3.5rem 2.5rem; border-top: 1px solid var(--line); color: var(--text-2); font-size: .9375rem; }
.footer-grid { display: grid; grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr)); gap: 2rem; }
@media (max-width: 48rem) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .footer-about, .footer-contact { grid-column: 1 / -1; } }
.footer-about p { max-width: 20rem; margin-top: .875rem; color: var(--text-3); }
.footer-grid h2 { margin-bottom: .875rem; color: var(--text); font-size: .875rem; letter-spacing: 0; }
.footer-grid ul { list-style: none; padding: 0; display: grid; gap: .5rem; }
.footer-grid a { color: var(--text-2); text-decoration: none; overflow-wrap: anywhere; }
.footer-grid a:hover { color: var(--text); }
.footer-base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem; margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--line); color: var(--text-3); font-size: .875rem; }

/* ----------------------------------------------------------------- respect */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

@media print {
  .site-header, .site-footer, .toc, .skip { display: none; }
  .doc-layout { display: block; }
  body { background: #fff; color: #000; }
}

/* A way out, stated plainly on the first screen.
   Quiet rather than hidden: somebody looking for it should not have to learn
   the navigation first, and somebody not looking for it should not meet a red
   button on the way to their devices. */
.home-leave {
  margin: 2rem 0 0;
  font-size: .875rem;
  color: var(--text-3);
  text-align: center;
}
.home-leave a { color: var(--text-3); text-decoration: underline; text-underline-offset: 2px; }
.home-leave a:hover { color: var(--danger); }

/* ------------------------------------------------------------------ Veltax */

/* A sentence, not a wordmark, so smaller than the TensorActivity hero's. */
.hero h1.v-title { margin-top: 1.5rem; font-size: clamp(2.5rem, 5.4vw, 4.25rem); line-height: 1.02; }

/* The hero's phone: the vault's lock screen, drawn in HTML and CSS, so it is
   sharp at every density and cannot arrive after the words beside it. It is a
   picture of the idea, not a screenshot, and is hidden from screen readers. */
.phone {
  position: relative;
  width: 100%;
  max-width: 17.5rem;
  margin-inline: auto;
  padding: .75rem;
  border: 1px solid var(--line-2);
  border-radius: 2.75rem;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  animation: rise .6s cubic-bezier(.2, .7, .2, 1) both;
}
.phone-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  padding: 2.75rem 1.5rem 2rem;
  border-radius: 2.125rem;
  background: var(--stage);
  color: var(--stage-text);
}
.phone-screen .i { width: 1.75rem; height: 1.75rem; color: var(--brand); }
.phone-title { font-weight: 600; letter-spacing: -.01em; }
.phone-dots { display: flex; gap: .75rem; }
.phone-dots span { width: .75rem; height: .75rem; border: 1.5px solid var(--stage-text-2); border-radius: 50%; }
.phone-dots span:nth-child(-n+2) { border-color: var(--brand); background: var(--brand); }
.phone-keys { display: grid; grid-template-columns: repeat(3, 3.25rem); gap: .75rem; margin-top: .5rem; }
.phone-keys span { display: grid; place-items: center; height: 3.25rem; border: 1px solid var(--stage-line); border-radius: 50%; color: var(--stage-text); font-size: 1.25rem; font-weight: 500; }
.phone-keys span:empty { border-color: transparent; }
.phone-foot { color: var(--stage-text-2); font-size: .8125rem; }

.section-lead { max-width: 40rem; margin-top: -.75rem; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); color: var(--text-2); font-size: 1.125rem; }

.features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 60rem) { .features { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .features { grid-template-columns: 1fr; } }
.feature { display: flex; flex-direction: column; gap: .875rem; padding: 1.375rem; }
.feature h3 { font-size: 1.0625rem; letter-spacing: -.015em; }
.feature p { color: var(--text-2); font-size: .9375rem; line-height: 1.6; }

/* What Veltax keeps, and what it does not: two plain lists side by side. */
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 48rem) { .facts { grid-template-columns: 1fr; } }
.facts .card { padding: 1.5rem; }
.facts h3 { display: flex; align-items: center; gap: .625rem; font-size: 1.0625rem; }
.facts ul { list-style: none; padding: 0; margin-top: 1rem; display: grid; gap: .75rem; }
.facts li { display: flex; gap: .625rem; color: var(--text-2); font-size: .9375rem; line-height: 1.55; }
.facts li .i { width: 1.125rem; height: 1.125rem; margin-top: .15rem; }
.facts .yes li .i { color: var(--ok); }
.facts .no li .i { color: var(--text-3); }
.facts-note { max-width: 44rem; margin-top: 1.25rem; color: var(--text-3); font-size: .875rem; }

.plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; max-width: 48rem; }
@media (max-width: 40rem) { .plans { grid-template-columns: 1fr; } }
.plan { display: flex; flex-direction: column; gap: .75rem; padding: 1.5rem; }
.plan h3 { font-size: 1.25rem; }
.plan p { color: var(--text-2); font-size: .9375rem; }
.plan-pro { border-color: transparent; background: var(--brand-soft); }
