/* vexlabs.com.au, built from scratch (BK, 2026-09-24: "create your own ... 3D laid out one from
   scratch, similar design to the door ... dark mood").

   The page is plain HTML over a fixed 3D room (js/room3d.js). Each .vx-station is one camera
   position in that room: on wide screens the words sit beside the subject (the room frames it on
   the other side), on phones and portrait tablets underneath it. Without WebGL the same page shows
   on a dark background with the app marks as images. */

:root {
  --bg: #030407;
  --ink: #eef2fa;
  --muted: #9ba7c0;
  --dim: #66728c;
  --blue: #2860de;
  --blue-hi: #3a78f2;
  --cyan: #5fd4fc;
  --line: rgba(255, 255, 255, .1);
  --panel: rgba(9, 12, 20, .74);
  --font: 'Urbanist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --gutter: clamp(20px, 5vw, 64px);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { background: var(--bg); color: var(--ink); scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; font: 400 17px/1.6 var(--font); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  /* the page without the room: night-blue light pooled where the room would be */
  background:
    radial-gradient(60% 45% at 72% 30%, rgba(40, 96, 222, .16), transparent 70%),
    radial-gradient(50% 40% at 20% 85%, rgba(95, 212, 252, .06), transparent 70%),
    var(--bg);
  background-attachment: fixed;
}
html.vx-3d body { background: var(--bg); }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.03em; text-wrap: balance; }
p { margin: 0; }
::selection { background: rgba(58, 120, 242, .45); color: #fff; }
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 6px; }

.vx-skip-link {
  position: fixed; top: 12px; left: 12px; z-index: 40; padding: 10px 16px; border-radius: 999px; background: var(--blue); color: #fff;
  font-weight: 600; text-decoration: none; transform: translateY(-160%); transition: transform .2s;
}
.vx-skip-link:focus { transform: none; }

/* ---------- the room behind the page ---------- */
.vx-room { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; opacity: 0; transition: opacity 1.2s ease; pointer-events: none; }
html.vx-3d .vx-room { opacity: 1; }

/* ---------- header ---------- */
.vx-top {
  position: fixed; top: 0; left: 0; right: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 18px var(--gutter); transition: opacity .9s ease .2s, background-color .35s ease, backdrop-filter .35s ease;
}
.vx-top.scrolled { background-color: rgba(3, 4, 7, .6); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
html:not(.vx-entered) .vx-top { opacity: 0; pointer-events: none; }
.vx-top-logo img { height: 32px; width: auto; }
.vx-top-nav { display: flex; align-items: center; gap: clamp(16px, 3vw, 34px); }
.vx-top-nav > a:not(.vx-btn) { color: var(--muted); font-weight: 600; font-size: 15.5px; text-decoration: none; transition: color .2s; }
.vx-top-nav > a:not(.vx-btn):hover { color: #fff; }

/* ---------- stations ---------- */
main { position: relative; z-index: 1; display: block; }
.vx-station { position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: center; padding: 110px 0 90px; }
.vx-wrap { width: 100%; max-width: 1280px; margin: 0 auto; padding: 0 var(--gutter); }
.vx-copy { max-width: 480px; text-shadow: 0 2px 24px rgba(3, 4, 7, .7); }
.vx-right .vx-copy { margin-left: auto; }

h1 { font-size: clamp(52px, 7.4vw, 112px); line-height: .95; letter-spacing: -0.045em; margin-bottom: 26px; }
h2 { font-size: clamp(38px, 4.8vw, 68px); line-height: 1; margin-bottom: 18px; }
.vx-hero .vx-copy { max-width: 620px; }
.vx-lede { font-size: clamp(17px, 1.5vw, 20px); color: var(--muted); max-width: 30em; }
.vx-kicker { margin-bottom: 14px; font-size: 13px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--cyan); }
.vx-grad {
  background: linear-gradient(95deg, var(--cyan) 0%, #3b86f2 75%); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent; text-shadow: none;
}
.vx-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 36px; }

/* the headline and header come up once you're through the door */
.vx-rise { opacity: 0; transform: translateY(22px); }
html.vx-entered .vx-rise { opacity: 1; transform: none; transition: opacity 1s ease var(--d, 0s), transform 1s cubic-bezier(.2, .75, .2, 1) var(--d, 0s); }

.vx-scroll-cue {
  position: absolute; left: 50%; bottom: 28px; width: 26px; height: 42px; margin-left: -13px; border: 1.5px solid rgba(255, 255, 255, .28); border-radius: 14px;
}
.vx-scroll-cue span { position: absolute; left: 50%; top: 9px; width: 3px; height: 8px; margin-left: -1.5px; border-radius: 2px; background: var(--cyan); animation: vx-cue 2.2s ease-in-out infinite; }
@keyframes vx-cue { 0%, 20% { transform: translateY(0); opacity: 1; } 70% { transform: translateY(12px); opacity: 0; } 100% { opacity: 0; } }

/* ---------- buttons ---------- */
.vx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; height: 52px; padding: 0 26px; border: 0; border-radius: 999px;
  background: var(--blue); color: #fff; font: 600 16px/1 var(--font); text-decoration: none; text-shadow: none; cursor: pointer;
  box-shadow: 0 12px 34px -12px rgba(40, 96, 222, .8), inset 0 1px 0 rgba(255, 255, 255, .18);
  transition: background-color .2s, transform .2s, box-shadow .2s;
}
.vx-btn:hover { background: var(--blue-hi); transform: translateY(-1px); }
.vx-btn svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.vx-btn-ghost { background: rgba(255, 255, 255, .05); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.vx-btn-ghost:hover { background: rgba(255, 255, 255, .1); }
.vx-btn-small { height: 40px; padding: 0 18px; font-size: 14.5px; }
.vx-btn[disabled] { opacity: .6; cursor: default; transform: none; }

/* ---------- apps ---------- */
.vx-app-name { margin-bottom: 18px; }
.vx-app-name img { height: clamp(44px, 4.6vw, 66px); width: auto; }
.vx-app-name.vx-app-wide img { height: clamp(38px, 3.9vw, 56px); }
.vx-app p { font-size: clamp(19px, 1.9vw, 26px); line-height: 1.4; color: #cdd5e6; margin-bottom: 24px; max-width: 19em; letter-spacing: -0.01em; }
.vx-pill {
  display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border-radius: 999px; font-size: 13px; font-weight: 700;
  letter-spacing: .02em; color: var(--cyan); background: rgba(95, 212, 252, .07); box-shadow: inset 0 0 0 1px rgba(95, 212, 252, .3); text-shadow: none;
}
.vx-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 10px var(--cyan); }
/* Without the room (no WebGL, no JavaScript) there is nothing to fill a screen-tall station:
   the sections close up into an ordinary page. */
html:not(.vx-webgl) .vx-station:not(.vx-hero) { min-height: 0; padding: 72px 0; align-items: flex-start; }
html:not(.vx-webgl) .vx-hero { min-height: 82vh; }

/* ---------- contact ---------- */
.vx-contact { align-items: flex-end; padding-top: 42vh; }
.vx-contact-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: clamp(28px, 5vw, 80px); align-items: start; }
.vx-contact .vx-copy { padding-top: 12px; }
.vx-form {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: clamp(20px, 3vw, 32px); border-radius: 22px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line), 0 40px 80px -30px rgba(0, 0, 0, .8);
  -webkit-backdrop-filter: blur(16px) saturate(1.2); backdrop-filter: blur(16px) saturate(1.2);
}
.vx-field { display: grid; gap: 7px; min-width: 0; }
.vx-field > span { font-size: 13.5px; font-weight: 600; color: var(--muted); }
.vx-field-full { grid-column: 1 / -1; }
.vx-field input, .vx-field select, .vx-field textarea {
  width: 100%; min-width: 0; padding: 13px 15px; border: 0; border-radius: 12px; background: rgba(255, 255, 255, .045); color: var(--ink);
  font: 500 16px/1.4 var(--font); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12); transition: box-shadow .2s, background-color .2s;
}
.vx-field textarea { resize: vertical; min-height: 130px; }
.vx-field select {
  appearance: none; -webkit-appearance: none; padding-right: 42px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%239ba7c0' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center;
}
.vx-field select option { background: #0b0e16; color: var(--ink); }
.vx-field input:focus, .vx-field select:focus, .vx-field textarea:focus { outline: none; background-color: rgba(255, 255, 255, .07); box-shadow: inset 0 0 0 1px var(--blue-hi), 0 0 0 4px rgba(58, 120, 242, .22); }
.vx-form-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin-top: 4px; }
.vx-form-status { font-size: 15px; font-weight: 600; min-height: 1.4em; }
.vx-form-status.ok { color: #6fe3a8; }
.vx-form-status.err { color: #ff9a9a; }
.vx-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- footer ---------- */
.vx-foot {
  position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 18px 32px;
  padding: 28px var(--gutter) 34px; background: linear-gradient(to bottom, rgba(3, 4, 7, 0), rgba(3, 4, 7, .92) 45%);
}
.vx-foot-logo img { height: 26px; width: auto; }
.vx-foot-nav { display: flex; gap: 26px; }
.vx-foot-nav a { color: var(--muted); font-weight: 600; font-size: 15px; text-decoration: none; }
.vx-foot-nav a:hover { color: #fff; }
.vx-foot-copy { color: var(--dim); font-size: 14px; font-weight: 500; }

/* ---------- 404 ---------- */
.vx-notfound .vx-copy { max-width: 640px; }

/* ---------- phones and portrait screens: the room frames its subject up top, words below ---------- */
@media (max-aspect-ratio: 9/10), (max-width: 720px) {
  .vx-station { align-items: flex-end; padding: 96px 0 calc(64px + env(safe-area-inset-bottom)); }
  .vx-right .vx-copy { margin-left: 0; }
  .vx-copy { max-width: 560px; }
  .vx-hero { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
  .vx-contact { padding-top: 34vh; }
  .vx-contact-grid { grid-template-columns: 1fr; gap: 26px; }
  .vx-top-nav > a:not(.vx-btn) { display: none; }
  .vx-app-name img { height: 42px; }
  .vx-app-name.vx-app-wide img { height: 36px; }
}
@media (max-width: 520px) {
  .vx-form { grid-template-columns: 1fr; }
  .vx-foot { flex-direction: column; align-items: flex-start; }
  .vx-top-logo img { height: 28px; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .vx-scroll-cue span { animation: none; }
  html.vx-entered .vx-rise { transition-duration: .01s; }
}

/* ---------- the door ----------
   A front door at night, drawn in 3D by js/door3d.js. The overlay stays dark until the scene's
   first frame, then the canvas fades in. Its canvas is transparent only through the doorway, so
   once the door opens the visitor sees the room canvas underneath, drawn from the door's camera. */
html.vx-locked, html.vx-locked body { overflow: hidden; }
.vx-in .vx-door { display: none; }
.vx-door {
  position: fixed; inset: 0; z-index: 2147483000; overflow: hidden; cursor: pointer; background: #020307;
  user-select: none; -webkit-user-select: none; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.vx-door.opening { background: transparent; cursor: default; }
.vx-door.leaving { opacity: 0; transition: opacity .45s ease; }   /* reduced motion: a plain fade */
.vx-door-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0; transition: opacity .9s ease; }
.vx-door.ready .vx-door-canvas { opacity: 1; }
.vx-door-copy {
  position: absolute; left: 0; right: 0; bottom: max(3.5vh, 18px); display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center; pointer-events: none; opacity: 0; transition: opacity .6s ease .45s;
}
.vx-door.ready .vx-door-copy { opacity: 1; }
.vx-door.opening .vx-door-copy { opacity: 0; transition: opacity .3s ease; }
.vx-door-say { margin: 0; font-size: clamp(22px, 3.6vh, 30px); font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; color: #fff; text-shadow: 0 2px 12px rgba(0, 0, 0, .6); }
/* for screen readers and keyboards: the door itself is a picture */
.vx-door-knock { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.vx-door-skip {
  position: absolute; top: 16px; right: 16px; z-index: 2; padding: 8px 14px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .3);
  background: rgba(255, 255, 255, .08); color: #fff; font: 600 14px/1 var(--font);
  clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; white-space: nowrap;
}
.vx-door-skip:focus-visible { clip-path: none; width: auto; height: auto; overflow: visible; outline: 2px solid var(--cyan); }
