/* ==========================================================================
   RPLAY.LT — BASE
   Font loading, reset, document defaults, typography, layout primitives,
   accessibility utilities and the shared motion language.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts — self-hosted WOFF2, subsetted to Latin + Lithuanian.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Big Shoulders";
  src: url("../fonts/bigshoulders-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("../fonts/instrumentsans-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("../fonts/instrumentsans-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrainsmono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrainsmono-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor targets clear the fixed header instead of hiding under it. */
  scroll-padding-top: 96px;
}

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

body {
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Nothing may push the page sideways. Enforced globally, not per-section. */
  overflow-x: clip;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

img { height: auto; }

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button { background: none; border: 0; }

p,
h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

ul[class],
ol[class] { list-style: none; padding: 0; }

a { color: inherit; }

:target { scroll-margin-top: 96px; }

/* --------------------------------------------------------------------------
   3. Atmosphere

   Two layers, and between them every page is lit continuously from the very
   top of the document — including the strip the sticky header floats in.
   Getting this wrong is what produces a black band under the header, so the
   rule is: no section may own its own top-of-page background.

     body::before  fixed to the viewport, so the room stays lit while scrolling
     body::after   anchored to the top of the *document*, reaching up behind
                   the header, so page one begins in light rather than in black

   Both are pointer-events:none and paint at z-index -1 over the body
   background, which the root canvas has already painted.
   -------------------------------------------------------------------------- */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(120vw 80vh at 14% -12%, rgba(51, 162, 255, 0.028), transparent 64%),
    radial-gradient(96vw 62vh at 88% 0%, rgba(255, 166, 64, 0.015), transparent 62%),
    radial-gradient(100vw 70vh at 50% 108%, rgba(51, 162, 255, 0.025), transparent 67%);
}

/* The document-top light. It starts above the header, not below it, so the
   header sits inside the glow rather than on top of a darker rectangle. */
body::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: clamp(420px, 62vh, 680px);
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(8, 12, 24, 0.44), rgba(8, 12, 24, 0.12) 46%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 58%, transparent 100%);
}

/* --------------------------------------------------------------------------
   4. Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }

/* h3/h4 drop back to the body face: the condensed display face is for
   headline scale only and gets hard to read below roughly 24px. */
h3 {
  font-size: var(--fs-h3);
  font-family: var(--font-body);
  line-height: var(--lh-snug);
  letter-spacing: -0.01em;
}
h4 {
  font-size: 1.0625rem;
  font-family: var(--font-body);
  line-height: var(--lh-snug);
  letter-spacing: -0.005em;
}

p { text-wrap: pretty; }

strong, b { font-weight: 700; color: var(--text); }

small { font-size: var(--fs-sm); }

code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.92em; }

::selection {
  background: var(--accent);
  color: var(--text-on-accent);
}

/* Text utilities -------------------------------------------------------- */
.u-lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-loose);
  color: var(--text-2);
  max-width: 62ch;
}

.u-muted { color: var(--text-muted); }
/* The one gradient in the type system, reserved for a single word per page. */
.u-accent-text {
  background: linear-gradient(96deg, var(--accent-hi) 0%, var(--accent) 45%, var(--gold) 130%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .u-accent-text { color: var(--accent); -webkit-text-fill-color: currentColor; }
}

/* Windows High Contrast strips background-image, which would leave
   gradient-clipped text invisible. Hand those cases a solid system colour. */
@media (forced-colors: active) {
  .u-accent-text {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
  }

  .card,
  .product,
  .step,
  .console,
  .faq__item { border-color: CanvasText; }

  .btn { border-color: ButtonText; }
}

/* Eyebrow — small mono caps label that opens a section. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--accent);
}

.eyebrow--quiet { color: var(--text-faint); }

.eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

/* --------------------------------------------------------------------------
   5. Layout primitives
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * 0.62); }

/* Two stacked sections would otherwise put two full paddings between them,
   which reads as a hole rather than a gap. One section owns the space. */
.section + .section { padding-top: 0; }

/* Section header: eyebrow + title + optional lead. Every section uses this so
   vertical rhythm is identical site-wide and nothing needs local margins. */
.section-head {
  display: grid;
  gap: var(--s-4);
  max-width: 68ch;
  margin-bottom: var(--s-7);
}

.section-head > * { margin: 0; }

.section-head--flush { margin-bottom: 0; }

.section-head--split {
  max-width: none;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  column-gap: var(--s-6);
}

.section-head--split > .eyebrow,
.section-head--split > h2,
.section-head--split > .u-lead { grid-column: 1; }

.section-head--split > .section-head__aside {
  grid-column: 2;
  grid-row: 1 / span 3;
  align-self: end;
}

@media (max-width: 720px) {
  .section-head--split { grid-template-columns: minmax(0, 1fr); }
  .section-head--split > .section-head__aside { grid-column: 1; grid-row: auto; }
}

/* A standalone note that follows a block of content. */
.section-note { margin-top: var(--s-6); max-width: 76ch; }
.stack { display: grid; gap: var(--s-4); }
.stack--lg { gap: var(--s-6); }

/* Auto-fitting card grid. --min is the card floor; every grid on the site
   derives from this one rule instead of redeclaring column counts. */
.grid-auto {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(min(var(--min, 260px), 100%), 1fr));
}

/* --------------------------------------------------------------------------
   6. Accessibility
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

:focus:not(:focus-visible) { outline: none; }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: var(--s-3);
  left: var(--s-3);
  z-index: var(--z-toast);
  padding: var(--s-3) var(--s-5);
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: 700;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
  transform: translateY(-180%);
  transition: transform var(--dur-2) var(--ease-out);
}

.skip-link:focus-visible { transform: translateY(0); }

/* Comfortable touch targets on coarse pointers. */
@media (pointer: coarse) {
  .btn,
  .nav__link,
  .icon-btn,
  .tab { min-height: 44px; }
}

/* --------------------------------------------------------------------------
   7. Motion language
   One entrance pattern, applied by the reveal observer in app.js. Elements
   start displaced and settle. Nothing loops, nothing bounces.
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

[data-reveal="fade"]  { transform: none; }
[data-reveal="left"]  { transform: translate3d(-20px, 0, 0); }
[data-reveal="right"] { transform: translate3d(20px, 0, 0); }
[data-reveal="scale"] { transform: scale(0.97); }

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* If JS never runs, content must not stay invisible. app.js sets .js on <html>
   as its first act; without it every reveal target renders normally. */
html:not(.js) [data-reveal] {
  opacity: 1;
  transform: none;
}

/* The reader's setting wins: no transforms, no delays, nothing gated behind an
   observer that might never fire. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* Print: a readable page, not a black rectangle. */
@media print {
  body::before,
  .site-header,
  .hero__stage,
  .drawer,
  .backdrop,
  .to-top { display: none !important; }

  body { background: #fff; color: #000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
}
