/* ============================================================================
   NOXFORGE — product site
   ----------------------------------------------------------------------------
   The same system as the app, on a page: one ink at a few opacities, filled
   surfaces rather than outlined ones, inversion as the only emphasis, and no
   colour anywhere. Hand-written, no build step.

   Themes: every colour on this page derives from --ink and --bg, so the whole
   site flips by redefining four values. Dark is the default because the app is
   dark-first; light is a full peer, not an afterthought.
   ========================================================================== */

:root {
  --ink: 255 255 255;
  --bg: #000;
  --surface: #0f0f0f;
  --surface-2: #171717;
  --btn: #1c1c1c;
  --btn-h: #262626;

  --line: rgb(var(--ink) / .1);
  --label: rgb(var(--ink) / 1);
  --label-2: rgb(var(--ink) / .62);
  --label-3: rgb(var(--ink) / .42);
  --label-4: rgb(var(--ink) / .22);
  --r: 20px;
  --pad: 24px;
  color-scheme: dark;
}

/* Light applies from two places: an explicit choice, and the system preference when
   no choice has been made. The two blocks are duplicated on purpose — a selector list
   cannot mix a selector with a media query, and @media inside :root is not a thing. */
:root[data-theme="light"] {
  --ink: 0 0 0;
  --bg: #fff;
  --surface: #f4f4f4;
  --surface-2: #ebebeb;
  --btn: #ededed;
  --btn-h: #e2e2e2;
  --line: rgb(var(--ink) / .12);
  color-scheme: light;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --ink: 0 0 0;
    --bg: #fff;
    --surface: #f4f4f4;
    --surface-2: #ebebeb;
    --btn: #ededed;
    --btn-h: #e2e2e2;
    --line: rgb(var(--ink) / .12);
    color-scheme: light;
  }
}

@font-face {
  font-family: 'Anton';
  src: url('anton.woff2') format('woff2');
  font-weight: 400; font-display: swap;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 88px; }
body {
  background: var(--bg); color: var(--label);
  font: 16px/1.6 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
  letter-spacing: -.011em;
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
  transition: background .2s ease, color .2s ease;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

/* height:auto is load-bearing, not tidiness: the <img> tags carry width/height attributes so
   the browser reserves the right box before the image arrives (no layout shift). Without this
   the attribute height wins over the CSS width and every screenshot renders at its intrinsic
   1688px tall inside a 250px column. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--label); outline-offset: 3px; border-radius: 4px; }

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 var(--pad); }

/* The one shared micro-label, exactly as the app does it. */
.eyebrow {
  font-size: 11px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--label-3);
}
.mono {
  font: 400 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .2em; text-transform: uppercase; color: var(--label-3);
}
.word {
  font-family: 'Anton', Impact, system-ui, sans-serif;
  font-weight: 400; text-transform: uppercase; letter-spacing: -.01em; line-height: .86;
}

/* ---------------------------------------------------------------- nav ---- */
.nav {
  position: sticky; top: 0; z-index: 20;
  background: rgb(var(--ink) / 0);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  background-color: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid var(--line);
}
.nav .wrap { display: flex; align-items: center; gap: 20px; height: 64px; }
.nav .brand { display: flex; align-items: center; gap: 10px; margin-right: auto; }
.nav .brand svg { width: 22px; height: 22px; fill: currentColor; }
.nav .brand .word { font-size: 20px; }
.nav .links { display: flex; gap: 24px; align-items: center; }
.nav .links a { font-size: 14px; color: var(--label-2); transition: color .13s }
.nav .links a:hover { color: var(--label); }

/* Theme toggle. Two glyphs, one visible per theme — no JS needed to pick which,
   which keeps the button correct even before the script runs. */
.themebtn {
  display: grid; place-items: center;
  width: 34px; height: 34px; flex: none;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--btn); color: var(--label);
  transition: background .13s;
}
.themebtn:hover { background: var(--btn-h); }
.themebtn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.themebtn .sun { display: none; }
.themebtn .moon { display: block; }
:root[data-theme="light"] .themebtn .sun { display: block; }
:root[data-theme="light"] .themebtn .moon { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .themebtn .sun { display: block; }
  :root:not([data-theme="dark"]) .themebtn .moon { display: none; }
}

/* --------------------------------------------------------------- hero ---- */
.hero { padding: 92px var(--pad) 72px; }   /* var(--pad): .hero is also .wrap, and this shorthand wins */
.hero .marks { display: flex; align-items: center; gap: 22px; margin-bottom: 34px; }
.hero .marks svg { width: 42px; height: 42px; fill: currentColor; }
.hero .marks .split { width: 1px; height: 42px; background: var(--line); }
.hero .rule { height: 2px; background: currentColor; margin-bottom: 26px; }
.hero h1 { font-size: clamp(58px, 12vw, 132px); }
.hero .lede {
  margin-top: 26px; font-size: clamp(17px, 2.4vw, 21px);
  color: var(--label-2); max-width: 46ch; letter-spacing: -.015em;
}
.cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 38px; }
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--btn); color: var(--label);
  padding: 13px 22px; border-radius: 999px;
  font-size: 15px; font-weight: 600; letter-spacing: -.012em;
  transition: background .13s, transform .08s;
}
.btn:hover { background: var(--btn-h); }
.btn:active { transform: scale(.98); }
.btn svg { width: 17px; height: 17px; fill: currentColor; }
.btn.primary { background: var(--label); color: var(--bg); }
.btn.primary:hover { background: rgb(var(--ink) / .86); }
.freeline { margin-top: 18px; font-size: 13.5px; color: var(--label-3); }

.split-2 {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px; margin: 8px 0 24px;
}
.split-2 > div { background: var(--surface); padding: 38px 32px; border-radius: var(--r); }
.split-2 svg { width: 34px; height: 34px; fill: currentColor; margin-bottom: 22px; }
.split-2 h3 { font-size: 21px; font-weight: 700; letter-spacing: -.022em; margin: 8px 0 10px; }
.split-2 p { color: var(--label-2); font-size: 15px; }

/* ----------------------------------------------------------- sections ---- */
section { padding: 88px 0; border-top: 1px solid var(--line); }
section > .wrap > .eyebrow { margin-bottom: 14px; }
section h2 {
  font-size: clamp(30px, 5vw, 46px); font-weight: 700;
  letter-spacing: -.035em; line-height: 1.06; max-width: 20ch;
}
section .sub { margin-top: 16px; color: var(--label-2); max-width: 56ch; }

.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); gap: 12px; margin-top: 44px; }
.card { background: var(--surface); border-radius: var(--r); padding: 26px; }
.card .num { color: var(--label-4); font-size: 12px; margin-bottom: 14px; }
.card h4 { font-size: 16px; font-weight: 600; margin-bottom: 8px; letter-spacing: -.012em; }
.card p { color: var(--label-2); font-size: 14.5px; line-height: 1.55; }

/* --------------------------------------------------------- screenshots --- */
/* A carousel that slides on its own, in one row.
   ------------------------------------------------------------------------------
   The track holds the six figures twice. The animation travels exactly one set
   plus one gap — so at the instant it wraps, the second set is sitting where the
   first began and the reset is invisible. That distance is what --gap encodes:
   the track is (2 x set + gap) wide, and 50% of that is (set + gap/2), so the
   remaining gap/2 has to be subtracted by hand. Change the gap and that
   calc has to change with it, which is why it is one variable.

   It sits inside .wrap, so it starts and ends on the same line as the heading
   above it and the cards below. The mask is what keeps that from looking like a
   hard crop: figures dissolve into the background at both ends instead of being
   sliced, which reads as motion continuing past the edge rather than stopping
   at it. */
.marquee {
  --gap: 18px;
  --shot: 240px;
  overflow: hidden;
  padding: 44px 0 4px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.track {
  display: flex; gap: var(--gap); width: max-content;
  animation: slide 46s linear infinite;
}
.set { display: flex; gap: var(--gap); }
.marquee figure { flex: none; width: var(--shot); }
/* Hovering to read one is a reason to stop, not to keep moving it away. */
.marquee:hover .track, .marquee:focus-within .track { animation-play-state: paused; }

@keyframes slide {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - var(--gap) / 2)); }
}

/* With motion suppressed the track would freeze mid-slide and the hidden figures would be
   unreachable, since the marquee clips overflow. Hand it back as a plain scroller. */
@media (prefers-reduced-motion: reduce) {
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .track { animation: none; }
}
@media (max-width: 640px) { .marquee { --shot: 200px; } }
.marquee img {
  border-radius: 26px; width: 100%;
  /* The screenshots are of a dark app. On the light theme they would otherwise sit as
     unexplained black slabs on white, so give them an edge to sit inside. */
  box-shadow: 0 0 0 1px var(--line), 0 18px 40px rgb(0 0 0 / .18);
}
.marquee figcaption { margin-top: 12px; }

/* ------------------------------------------------------------ download --- */
.dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; margin-top: 44px; }
.dl > div {
  background: var(--surface); border-radius: var(--r); padding: 30px 28px;
  display: flex; flex-direction: column;
}
.dl .plat { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.dl .plat svg { width: 20px; height: 20px; fill: currentColor; }
.dl h3 { font-size: 18px; font-weight: 700; letter-spacing: -.02em; margin-bottom: 8px; }
.dl p { color: var(--label-2); font-size: 14.5px; line-height: 1.55; flex: 1; }
.dl .btn { margin-top: 22px; align-self: flex-start; }
.dl .note { margin-top: 14px; font-size: 12.5px; color: var(--label-3); line-height: 1.5; }

/* ----------------------------------------------------------------- faq --- */
.faq { margin-top: 44px; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: 20px 0;
  font-size: 16px; font-weight: 600; letter-spacing: -.015em;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; flex: none; width: 9px; height: 9px;
  border-right: 1.8px solid var(--label-3); border-bottom: 1.8px solid var(--label-3);
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .18s;
}
.faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq p { color: var(--label-2); font-size: 14.5px; padding: 0 0 22px; max-width: 62ch; }

/* -------------------------------------------------------------- footer --- */
footer { border-top: 1px solid var(--line); padding: 56px 0 72px; }
footer .row { display: flex; flex-wrap: wrap; gap: 40px; justify-content: space-between; }
footer p { color: var(--label-3); font-size: 13.5px; max-width: 52ch; line-height: 1.65; }
footer a { color: var(--label-2); text-decoration: underline; text-underline-offset: 3px; }
footer a:hover { color: var(--label); }
footer .word { font-size: 26px; margin-bottom: 12px; }
footer .fine { margin-top: 26px; font-size: 12.5px; color: var(--label-4); }

@media (max-width: 640px) {
  .nav .links a.opt { display: none; }
  .hero { padding: 64px var(--pad) 56px; }
  section { padding: 68px 0; }
}

/* ------------------------------------------------------------- ai coach --- */

/* Wordmarks, not logos. Two reasons, and neither is laziness: reproducing another company's
   mark from memory tends to produce something subtly wrong, which looks worse than no mark
   at all; and both are trademarks whose owners publish brand guidelines. Set in this site's
   own type they read as a compatibility statement, which is exactly what they are. To use the
   official assets instead, drop each vendor's SVG in here — the chip is already the right
   size and inherits currentColor. */
.works { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 34px; }
.works .mono { margin-right: 2px; }
.vendor {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--surface); border-radius: 999px;
  padding: 9px 18px; font-size: 14.5px; font-weight: 600; letter-spacing: -.012em;
}
.vendor svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }

/* Two screens side by side. Not the marquee: these two are a before/after pair and reading
   them in order is the point, which a moving row would take away. */
.shots-pair { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin-top: 44px; }
.shots-pair figure { min-width: 0; }
.shots-pair img {
  border-radius: 26px; width: 100%;
  box-shadow: 0 0 0 1px var(--line), 0 18px 40px rgb(0 0 0 / .18);
}
.shots-pair figcaption { margin-top: 12px; }
@media (max-width: 560px) { .shots-pair { gap: 12px; } }

/* Inline link inside body copy. Underlined rather than coloured, because there is no colour
   in this system to spend on it. */
.ulink { text-decoration: underline; text-underline-offset: 3px; color: var(--label-2); }
.ulink:hover { color: var(--label); }
.faq p a { text-decoration: underline; text-underline-offset: 3px; }
