/**
 * Reset + primitives shared by the site and the portal.
 */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	background: var(--ts-bg);
	color: var(--ts-text);
	font-family: var(--ts-font);
	font-size: var(--ts-b1-size);
	line-height: var(--ts-b1-lh);
	font-weight: 400;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }

button {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
}

:where(a, button, [tabindex]):focus-visible {
	outline: 2px solid var(--ts-brand);
	outline-offset: 3px;
	border-radius: 4px;
}

.ts-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ---------- layout ---------- */

.ts-container {
	width: min(var(--ts-container), 100% - (var(--ts-gutter) * 2));
	margin-inline: auto;
}

/* ---------- type ---------- */

.ts-h2 {
	font-size: var(--ts-h2-size);
	line-height: var(--ts-h2-lh);
	letter-spacing: var(--ts-h2-ls);
	font-weight: 700;
	color: var(--ts-ink);
}

.ts-h3 {
	font-size: var(--ts-h3-size);
	line-height: var(--ts-h3-lh);
	font-weight: 700;
	color: var(--ts-ink);
}

.ts-b2 {
	font-size: var(--ts-b2-size);
	line-height: var(--ts-b2-lh);
}

.ts-eyebrow {
	font-size: var(--ts-eyebrow-size);
	line-height: var(--ts-eyebrow-lh);
	letter-spacing: var(--ts-eyebrow-ls);
	font-weight: 700;
	text-transform: uppercase;
	color: var(--ts-brand);
}

/* ---------- buttons ----------
   Both header CTAs share one padding box. The outlined variant measures 2px
   taller in Figma purely because its 1px border sits outside the fill, so the
   border is added here rather than baked into the height. */

/* This is the Figma Button component (node 1:375): px-24 py-14, radius 40,
   16/22 type. Everything inherits it. The header pills are the one exception
   and override below in site.css. */
.ts-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 14px 24px;
	border-radius: 40px;
	font-size: var(--ts-b1-size);
	line-height: 22px;
	font-weight: 700;
	white-space: nowrap;
	transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.ts-btn--primary {
	background: var(--ts-brand);
	color: var(--ts-white);
	box-shadow: var(--ts-shadow-btn);
}

.ts-btn--outline {
	background: var(--ts-white);
	color: var(--ts-ink);
	border: 1px solid var(--ts-hairline);
}

@media (hover: hover) {
	.ts-btn:hover { transform: translateY(-1px); }
	.ts-btn--primary:hover { background: #3a38b8; }
}

@media (prefers-reduced-motion: reduce) {
	.ts-btn { transition: none; }
	.ts-btn:hover { transform: none; }
}

/* =========================================================================
   Language switcher - dropdown

   Laid out inline the three links cost ~106px, which the translated header
   could not spare. Collapsed to a toggle it costs ~72px and never grows.
   ========================================================================= */

.ts-lang {
	position: relative;
	flex-shrink: 0;
}

.ts-lang__toggle {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 8px 10px;
	border-radius: var(--ts-r-pill);
	font-size: 14px;
	font-weight: 700;
	color: var(--ts-text);
	transition: background-color .15s ease, color .15s ease;
}

.ts-lang__globe,
.ts-lang__chev { display: grid; place-items: center; }

.ts-lang__chev { transition: transform .2s ease; }

.ts-lang__toggle[aria-expanded='true'] .ts-lang__chev { transform: rotate(180deg); }

@media (hover: hover) {
	.ts-lang__toggle:hover { background: rgba(26, 26, 35, .05); color: var(--ts-ink); }
}

.ts-lang__list {
	position: absolute;
	right: 0;
	top: calc(100% + 8px);
	z-index: 120;
	min-width: 180px;
	padding: 8px;
	border: 1px solid var(--ts-hairline);
	border-radius: 18px;
	background: var(--ts-white);
	box-shadow: 0 18px 40px rgba(26, 26, 35, .14);
}

.ts-lang__list[hidden] { display: none; }

.ts-lang__item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	border-radius: 12px;
	font-size: 15px;
	font-weight: 700;
	color: var(--ts-ink);
	white-space: nowrap;
	transition: background-color .15s ease;
}

.ts-lang__abbr {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 30px;
	padding: 2px 6px;
	border-radius: 6px;
	background: var(--ts-bg);
	font-size: 12px;
	color: var(--ts-text);
}

.ts-lang__item.is-active { color: var(--ts-brand); }
.ts-lang__item.is-active .ts-lang__abbr {
	background: rgba(65, 63, 201, .12);
	color: var(--ts-brand);
}

@media (hover: hover) {
	.ts-lang__item:hover,
	.ts-lang__item:focus-visible { background: var(--ts-bg-soft); }
}

/* Sits between the nav and the CTAs. */
.ts-lang--header { margin-left: auto; }

.ts-lang--mobile { margin-bottom: 16px; align-self: center; }
.ts-lang--mobile .ts-lang__toggle { font-size: 16px; padding: 12px 16px; }
.ts-lang--mobile .ts-lang__list { right: auto; left: 50%; transform: translateX(-50%); }

@media (max-width: 900px) {
	.ts-lang--header { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.ts-lang__toggle,
	.ts-lang__chev,
	.ts-lang__item { transition: none; }
}

/* =========================================================================
   Video lightbox

   Lives here rather than in site.css because both surfaces open it - the hero
   play button on the landing page and the tutorial rows in the portal, which
   loads portal.css instead of site.css.
   ========================================================================= */

html.ts-vbox-open { overflow: hidden; }

.ts-vbox {
	position: fixed;
	inset: 0;
	/* Above the mobile menu (200), which is the tallest thing on either side. */
	z-index: 300;
	display: grid;
	place-items: center;
	padding: 24px;
	background: rgba(26, 26, 35, .86);
	opacity: 0;
	transition: opacity .2s ease;
}

/* Beats the display:grid above - without this the overlay would sit open. */
.ts-vbox[hidden] { display: none; }

.ts-vbox.is-open { opacity: 1; }

.ts-vbox__panel {
	position: relative;
	width: min(1040px, 100%);
}

.ts-vbox__close {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	/* auto left margin pins it to the right edge of the panel; sitting above
	   the frame rather than over it keeps it clear of the video controls. */
	margin: 0 0 12px auto;
	border-radius: var(--ts-r-pill);
	background: rgba(255, 255, 255, .12);
	color: var(--ts-white);
	transition: background-color .15s ease;
}

@media (hover: hover) {
	.ts-vbox__close:hover { background: rgba(255, 255, 255, .24); }
}

.ts-vbox__frame {
	overflow: hidden;
	/* Matches the hero video block it opens from. */
	border-radius: 28px;
	background: #000;
	box-shadow: 0 30px 80px rgba(0, 0, 0, .45);
}

.ts-vbox__video {
	width: 100%;
	height: auto;
	/* Overlay padding (48) + close button and its gap (56) + breathing room. */
	max-height: calc(100vh - 152px);
	object-fit: contain;
	background: #000;
}

/* Mobile browser chrome makes vh overshoot; dvh is the real viewport. */
@supports (height: 100dvh) {
	.ts-vbox__video { max-height: calc(100dvh - 152px); }
}

@media (max-width: 767px) {
	.ts-vbox { padding: 16px; }
	.ts-vbox__frame { border-radius: 20px; }
}

@media (prefers-reduced-motion: reduce) {
	.ts-vbox,
	.ts-vbox__close { transition: none; }
}
