/* ==========================================================================
   Kevin Schade — homepage styles
   Engineering / terminal aesthetic. Dark navy base, blue→teal accents,
   a monospace voice for labels and the {code} brace motif.
   Design tokens first, then base, then one block per page section.
   ========================================================================== */

/* ---- Self-hosted webfonts (latin + latin-ext subsets, font-display: block) ---- */

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/jetbrains-mono-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/sora-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/sora-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/sora-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/sora-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/sora-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/sora-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/assets/fonts/sora-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/assets/fonts/sora-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/assets/fonts/sora-800-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/assets/fonts/sora-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/work-sans-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/work-sans-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/work-sans-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/assets/fonts/work-sans-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/work-sans-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/assets/fonts/work-sans-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Palette (kept from the original Figma design) */
  --bg-0: #04071a; /* page base */
  --bg-1: #0a1130; /* raised navy */
  --navy: #0b1330;
  --accent: #5b86e5; /* primary blue */
  --accent-2: #36d1dc; /* teal */
  --bright: #1fa2ff; /* bright glow blue */
  --green: #9ce37b; /* "available" dot */
  --text: #ffffff;
  --muted: #a6a6a6;
  --light: #dcdcdc;
  --line: rgba(255, 255, 255, 0.12);

  --grad: linear-gradient(100deg, #5b86e5 0%, #36d1dc 100%);
  --grad-bright: linear-gradient(66deg, #1fa2ff 6%, #12d8fa 50%, #a6ffcb 106%);
  /* deep base for the primary CTA — kept dark so the white label keeps
     strong contrast; depth/sheen are layered on top in .btn-primary */
  --grad-cta: linear-gradient(135deg, #1f4fb0 0%, #117885 100%);

  --font-display: "Sora", system-ui, sans-serif;
  --font-body: "Work Sans", system-ui, -apple-system, Segoe UI, Roboto,
    sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --maxw: 1440px;
  --pad-x: 64px;
  --radius: 10px;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  font-family: var(--font-body);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg-0);
  overflow-x: hidden;
  position: relative;
}

/* Faint engineering grid woven over the whole page */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: linear-gradient(
      rgba(91, 134, 229, 0.05) 1px,
      transparent 1px
    ),
    linear-gradient(90deg, rgba(91, 134, 229, 0.05) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(circle at 50% 0%, #000 0%, transparent 80%);
}

body > * {
  position: relative;
  z-index: 1;
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  display: block;
  max-width: 100%;
}

.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: var(--accent-2);
  margin: 0 0 14px;
}

.grad-text {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Name logo: monogram tile + wordmark */
.brand-badge {
  display: inline-block;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  box-shadow: 0 6px 18px -8px rgba(31, 162, 255, 0.7);
}

/* Shared button -------------------------------------------------------------*/
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 16px;
  line-height: 1;
  padding: 13px 20px;
  border-radius: 6px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, filter 0.18s ease,
    background 0.18s ease;
}

.btn-primary {
  position: relative;
  overflow: hidden;
  color: #fff;
  /* top sheen (light from above) layered over the deep base */
  background: linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.16) 0%,
      rgba(255, 255, 255, 0) 46%
    ),
    var(--grad-cta);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28),
    inset 0 -1px 0 rgba(0, 0, 0, 0.22), 0 10px 28px -12px rgba(28, 130, 190, 0.6);
}

/* shine sweep on hover */
.btn-primary::before,
.btn-ghost::before {
  content: "";
  position: absolute;
  top: 0;
  left: -120%;
  width: 60%;
  height: 100%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.35),
    transparent
  );
  transform: skewX(-20deg);
  transition: left 0.6s ease;
  pointer-events: none;
}

.btn-primary:hover::before,
.btn-ghost:hover::before {
  left: 130%;
}

.btn-primary:hover,
.btn-ghost:hover {
  filter: brightness(1.06);
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.32),
    inset 0 -1px 0 rgba(0, 0, 0, 0.22), 0 16px 34px -14px rgba(28, 150, 210, 0.78);
}

.btn .icon {
  width: 18px;
  height: 18px;
  transition: transform 0.18s ease;
}

.btn-primary:hover .icon,
.btn-ghost:hover .icon {
  transform: translateX(3px);
}

.btn-ghost {
  position: relative;
  overflow: hidden;
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--accent);
}

.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* Pills / chips -------------------------------------------------------------*/
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 13px;
  border-radius: 80px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
}

.pill-solid {
  background: #fff;
  color: var(--navy);
  font-weight: 600;
}

.pill-outline {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--accent);
  color: var(--text);
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 0 rgba(156, 227, 123, 0.6);
  animation: pulse 2.4s ease-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(156, 227, 123, 0.55);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(156, 227, 123, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(156, 227, 123, 0);
  }
}

/* ==========================================================================
   Header / nav
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.25s ease, border-color 0.25s ease,
    backdrop-filter 0.25s ease;
}

.site-header.scrolled {
  background: rgba(5, 8, 24, 0.72);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--line);
}

/* lock page scrolling while the mobile menu is open */
html:has(.nav.open),
body:has(.nav.open) {
  overflow: hidden;
  touch-action: none;
}

/* while the mobile menu is open, use a fully opaque bg so the header
   and dropdown render identically regardless of the content behind
   each (hero gradient vs. dark page body) */
.site-header:has(.nav.open) {
  background: #05081a;
  backdrop-filter: none;
  border-bottom-color: var(--line);
}

/* Pin the header to the viewport while the menu is open. The scroll lock
   above sets overflow:hidden on the scroll container, which un-sticks a
   position:sticky element — so once you'd scrolled, the header (and its close
   button) jumped to the top of the document, off-screen, leaving the menu
   unreachable. Switching to fixed keeps it at the viewport top; the body
   padding fills the 75px the header leaves in normal flow so content doesn't
   shift. (Only reachable on mobile, where the toggle is shown.) */
.site-header:has(.nav.open) {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
}
body:has(.nav.open) {
  padding-top: 75px;
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 75px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
}

.brand-name {
  transition: opacity 0.15s ease;
}

.brand:hover .brand-name {
  opacity: 0.82;
}

.nav {
  display: flex;
  align-items: center;
  gap: 36px;
}

.nav a {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  color: var(--light);
  font-size: 15px;
  transition: color 0.15s ease;
}

.nav .nav-idx {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
}

.nav a:hover {
  color: #fff;
}

/* Language switcher — small group at the end of the nav row */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--font-mono);
  font-size: 15px;
}

.lang-switch a {
  display: inline-flex;
  align-items: center;
  padding: 3px 3px;
  border-radius: 5px;
  color: var(--muted);
  letter-spacing: 0.04em;
  transition: color 0.15s ease;
}

.lang-switch a:hover {
  color: #fff;
}

.lang-switch a[aria-current="true"] {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 8px;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: #fff;
  margin: 4px 0;
  transition: transform 0.3s ease, opacity 0.2s ease;
}

/* hamburger morphs into an X while the menu is open
   (driven by aria-expanded, which the nav toggle JS sets) */
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  overflow: hidden;
  /* Pull the hero gradient up behind the transparent header so the
     top of the page blends instead of showing the dark page base. */
  margin-top: -75px;
  padding-top: 75px;
  /* Engineering grid layered over the hero gradient, matching the page grid
     (64px cells, same blue tint). The body grid sits behind the hero's opaque
     gradient, so we redraw it here to keep the motif continuous. */
  background-image: linear-gradient(
      rgba(91, 134, 229, 0.05) 1px,
      transparent 1px
    ),
    linear-gradient(90deg, rgba(91, 134, 229, 0.05) 1px, transparent 1px),
    linear-gradient(180deg, #0a1334 0%, #0a1024 100%);
  background-size: 64px 64px, 64px 64px, auto;
}

/* soft side glows */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  top: -120px;
  width: 720px;
  height: 720px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(31, 162, 255, 0.28) 0%,
    rgba(31, 162, 255, 0) 70%
  );
  pointer-events: none;
  z-index: 0;
}

.hero::before {
  left: -260px;
}

.hero::after {
  right: -260px;
}

.hero .container {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 648px) 1fr;
  gap: 48px;
  align-items: center;
  min-height: 590px;
  padding-block: 56px;
}

.hero-badges {
  display: flex;
  gap: 12px;
  margin-bottom: 26px;
  animation: rise 0.7s 0.05s both;
}

.hero-eyebrow {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--accent-2);
  margin: 0 0 14px;
  animation: rise 0.7s 0.12s both;
}

.hero h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 56px;
  line-height: 1.1;
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin: 0 0 30px;
  max-width: 14ch;
  animation: rise 0.7s 0.2s both;
}

.hero h1 .grad-text,
.hero h1 .grad-alt {
  font-weight: 700;
}

/* second highlight tone — brighter blue→mint, still within palette */
.grad-alt {
  background: var(--grad-bright);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
  margin-bottom: 30px;
  animation: rise 0.7s 0.26s both;
}

.hero-meta span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--light);
  font-size: 15px;
}

.hero-meta .icon {
  color: var(--accent-2);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  animation: rise 0.7s 0.34s both;
}

.hero-photo {
  position: relative;
  justify-self: end;
  width: 100%;
  max-width: 564px;
  padding: 10px;
  animation: rise 0.8s 0.3s both;
}

.hero-photo img {
  width: 100%;
  /* Lock the frame shape in CSS so the image's intrinsic dimensions (set as
     width/height attributes by eleventy-img) can't force a stretched box. */
  height: auto;
  aspect-ratio: 4 / 5;
  border-radius: 12px;
  object-fit: cover;
  border: 1px solid var(--line);
}

/* Engineering corner brackets that frame portrait + about photo */
.frame-corner {
  position: absolute;
  width: 22px;
  height: 22px;
  border: 2px solid var(--accent-2);
  pointer-events: none;
}
.frame-corner.tl {
  top: 0;
  left: 0;
  border-right: 0;
  border-bottom: 0;
}
.frame-corner.tr {
  top: 0;
  right: 0;
  border-left: 0;
  border-bottom: 0;
}
.frame-corner.bl {
  bottom: 0;
  left: 0;
  border-right: 0;
  border-top: 0;
}
.frame-corner.br {
  bottom: 0;
  right: 0;
  border-left: 0;
  border-top: 0;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  stroke: currentColor;
}

/* ==========================================================================
   Marquee
   ========================================================================== */
.marquee {
  border-block: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.02);
  overflow: hidden;
  padding-block: 22px;
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 28s linear infinite;
}

.marquee {
  cursor: pointer;
}

.marquee-track span {
  display: inline-flex;
  align-items: center;
  gap: 40px;
  /* spacing lives on each item (not a flex gap) so translateX(-50%)
     lands exactly on the duplicate and the loop is seamless */
  margin-right: 40px;
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--light);
  white-space: nowrap;
}

.marquee-track span::after {
  content: "✦";
  color: var(--accent-2);
  font-size: 14px;
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track {
    animation: none;
  }
  .hero-badges,
  .hero-eyebrow,
  .hero h1,
  .hero-meta,
  .hero-actions,
  .hero-photo,
  .back-link,
  .project-hero h1,
  .project-lead,
  .project-hero-copy .card-tags,
  .project-hero-copy .hero-actions,
  .project-hero-shot {
    animation: none;
  }
  .dot {
    animation: none;
  }
}

/* ==========================================================================
   Portfolio
   ========================================================================== */
.portfolio {
  position: relative;
  padding-block: 88px 100px;
  overflow: hidden;
}

.portfolio::before {
  content: "";
  position: absolute;
  top: 120px;
  left: 50%;
  transform: translateX(-50%);
  width: 1066px;
  height: 957px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(31, 162, 255, 0.14) 0%,
    rgba(31, 162, 255, 0) 65%
  );
  pointer-events: none;
}

.section-head {
  position: relative;
  margin-bottom: 46px;
}

.section-head h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 38px;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}

.section-head .brace {
  color: var(--accent-2);
  font-family: var(--font-mono);
  font-weight: 500;
}

.section-head .section-sub {
  margin: 0;
  color: var(--light);
  font-size: 16px;
}

.portfolio-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: linear-gradient(
    180deg,
    rgba(28, 36, 78, 0.55) 0%,
    rgba(10, 16, 40, 0.55) 100%
  );
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Full-card overlay link — covers the whole card (including the arrow), so
   clicking anywhere does the same thing: open the live site (simple cards) or
   the case-study subpage (detail cards). The arrow is purely decorative. */
.card-link {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--radius);
}

.card:hover {
  transform: translateY(-4px);
  border-color: rgba(54, 209, 220, 0.55);
  box-shadow: 0 22px 44px -24px rgba(31, 162, 255, 0.55);
}

/* faux browser window for each project */
.card-frame {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #060a1e;
}

.card-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.04);
  border-bottom: 1px solid var(--line);
}

.card-bar .dots {
  display: inline-flex;
  gap: 6px;
  flex-shrink: 0;
}

.card-bar .dots i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}

.card-bar .url {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--light);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-bar .go {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--muted);
  transition: color 0.15s ease, transform 0.15s ease;
}

/* The arrow isn't its own click target, so its hover effect follows the card. */
.card:hover .card-bar .go {
  color: var(--accent-2);
  transform: translate(1px, -1px);
}

.card-shot {
  height: 210px;
  background: radial-gradient(120% 120% at 0% 0%, #1b2350, #0c1130 70%);
  position: relative;
  overflow: hidden;
}

.card-shot::before {
  content: "</>";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 40px;
  font-weight: 600;
  color: rgba(91, 134, 229, 0.22);
}

.card-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
      rgba(91, 134, 229, 0.08) 1px,
      transparent 1px
    ),
    linear-gradient(90deg, rgba(91, 134, 229, 0.08) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* Real screenshot inside a shot frame: fill it and drop the placeholder art. */
.card-shot.has-shot::before,
.card-shot.has-shot::after {
  display: none;
}

.card-shot.has-shot :is(picture, img) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchor to the top so the bottom is cropped when the frame is shorter. */
  object-position: top;
}

.card-quote {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.92);
  margin: 0;
  padding-inline: 4px;
}

/* SIMPLE cards have no quote/author, so the tag row drops its top divider. */
.card-simple .card-tags {
  border-top: none;
  padding-top: 0;
}

.card-author {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-inline: 4px;
  /* Pin the author + tag rows to the bottom so they line up across cards
     regardless of quote length. */
  margin-top: auto;
}

.card-author .avatar {
  width: 44px;
  height: 44px;
  border-radius: 100px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid var(--line);
}

.card-author .who {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.card-author .who strong {
  display: block;
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
}

.card-author .who span {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

.card-tags {
  display: flex;
  gap: 16px;
  padding: 12px 4px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.card-tags span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--light);
}

.card-tags span::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-2);
}

/* ==========================================================================
   About
   ========================================================================== */
.about {
  padding-block: 96px;
}

.about .container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}

.about h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 38px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
}

.about-bio {
  display: flex;
  flex-direction: column;
  gap: 32px;
  align-items: flex-start;
}

.about-bio .lead {
  color: rgba(255, 255, 255, 0.82);
  font-size: 16px;
  margin: 0;
}

.about-bio .lead p {
  margin: 0 0 16px;
}

.about-bio .lead p:last-child {
  margin-bottom: 0;
}

.about-bio .lead strong {
  color: #fff;
  font-weight: 600;
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.tags .pill-outline {
  color: var(--accent-2);
  font-weight: 500;
  font-family: var(--font-mono);
  font-size: 12px;
}

.about-visual {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.about-photo {
  position: relative;
  padding: 10px;
}

/* <picture> wrappers (from eleventy-img) shouldn't generate a box — let the
   inner <img> lay out as a direct child of its container. */
picture {
  display: contents;
}

.about-photo img {
  width: 100%;
  height: 462px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--line);
}

.stats {
  display: flex;
  gap: 18px;
}

.stat {
  flex: 1;
  padding: 18px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.stat:hover {
  border-color: rgba(54, 209, 220, 0.5);
  transform: translateY(-3px);
}

.stat strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 34px;
  line-height: 1.1;
}

.stat span {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--accent-2);
}

/* ==========================================================================
   Contact
   ========================================================================== */
/* Standalone contact page: make the layout fill at least the full viewport so
   the footer sits at the bottom and the contact section is vertically centred
   instead of leaving a short page on tall desktop screens. */
body:has(.contact-main) {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

.contact-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Clip the decorative glow horizontally (so it can't add a sideways
     scrollbar on mobile) while still letting it bleed vertically below. */
  overflow-x: clip;
}

/* Let the decorative glow fade out downward instead of being hard-clipped
   where the centred section is shorter than the 660px circle. */
.contact-main .contact {
  overflow: visible;
}

.contact {
  position: relative;
  padding-block: 96px;
  overflow: hidden;
}

.contact::before {
  content: "";
  position: absolute;
  top: -40px;
  left: -120px;
  width: 735px;
  height: 660px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(31, 162, 255, 0.16) 0%,
    rgba(31, 162, 255, 0) 65%
  );
  pointer-events: none;
}

.contact .container {
  position: relative;
  display: grid;
  grid-template-columns: 390px 1fr;
  gap: 72px;
  align-items: start;
}

.contact h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 38px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
}

.contact-intro .note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 24px 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-size: 16px;
}

.contact-intro .note .icon {
  color: #fff;
  /* Keep the icon from squashing and align it with the first line of text
     (rather than centring against the whole wrapped block on mobile). */
  flex: none;
  margin-top: 0.3em;
}

.contact-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.contact-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  transition: background 0.18s ease, transform 0.18s ease,
    border-color 0.18s ease;
  font-family: inherit;
  text-align: left;
  width: 100%;
  color: inherit;
  cursor: pointer;
}

.contact-row:hover {
  background: rgba(255, 255, 255, 0.08);
  transform: translateY(-2px);
  border-color: rgba(91, 134, 229, 0.6);
}

.contact-row.is-highlighted {
  background: rgba(31, 162, 255, 0.08);
  border: 1px solid var(--bright);
  box-shadow: 0 0 0 1px rgba(31, 162, 255, 0.3),
    0 18px 40px -26px rgba(31, 162, 255, 0.8);
}

.contact-row .left {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}

.contact-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--accent);
  color: #fff;
}

.contact-icon .icon {
  width: 20px;
  height: 20px;
}

.contact-row .title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  margin: 0;
}

.contact-row .sub {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.78);
  margin: 4px 0 0;
}

.contact-row .cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 14px;
  color: var(--accent-2);
}

.contact-row.is-highlighted .cta {
  color: transparent;
  background: var(--grad-bright);
  -webkit-background-clip: text;
  background-clip: text;
}

.contact-row .cta .icon {
  width: 18px;
  height: 18px;
  color: var(--accent-2);
}

/* ==========================================================================
   Project subpage — hero
   ========================================================================== */
.project-hero {
  position: relative;
  overflow: hidden;
  margin-top: -75px;
  padding-top: 75px;
  background: linear-gradient(180deg, #0a1334 0%, #0a1024 100%);
}

/* soft side glow, echoing the home hero */
.project-hero::before {
  content: "";
  position: absolute;
  top: -120px;
  right: -240px;
  width: 720px;
  height: 720px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(31, 162, 255, 0.26) 0%,
    rgba(31, 162, 255, 0) 70%
  );
  pointer-events: none;
  z-index: 0;
}

.project-hero .container {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
  gap: 56px;
  align-items: center;
  padding-block: 64px 72px;
}

.project-hero-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 24px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent-2);
  transition: gap 0.18s ease, color 0.18s ease;
  animation: rise 0.7s 0.05s both;
}

.back-link .icon {
  width: 16px;
  height: 16px;
}

.back-link:hover {
  gap: 12px;
  color: #fff;
}

.project-hero h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 52px;
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin: 0 0 22px;
  animation: rise 0.7s 0.12s both;
}

.project-lead {
  color: rgba(255, 255, 255, 0.82);
  font-size: 17px;
  line-height: 1.65;
  margin: 0 0 26px;
  max-width: 52ch;
  animation: rise 0.7s 0.2s both;
}

.project-hero-copy .card-tags {
  border-top: 0;
  padding: 0;
  flex-wrap: wrap;
  margin-bottom: 32px;
  animation: rise 0.7s 0.26s both;
}

.project-hero-copy .hero-actions {
  animation: rise 0.7s 0.34s both;
}

.project-hero-shot {
  position: relative;
  justify-self: end;
  width: 100%;
  max-width: 560px;
  padding: 10px;
  animation: rise 0.8s 0.28s both;
}

.card-shot-lg {
  height: 360px;
}

/* The hero screenshot shows in full: the frame takes the image's own aspect
   ratio (driven by the img's width/height attrs) instead of cropping to a
   fixed height. */
.card-shot-lg.has-shot {
  height: auto;
}

.card-shot-lg.has-shot picture {
  position: static;
  display: block;
}

.card-shot-lg.has-shot img {
  position: static;
  width: 100%;
  height: auto;
  object-fit: contain;
  object-position: center;
}

/* Whole hero image links to the live site */
.shot-link {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
}

.project-hero-shot {
  transition: transform 0.2s ease;
}

.project-hero-shot .card-frame {
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.project-hero-shot:hover {
  transform: translateY(-4px);
}

.project-hero-shot:hover .card-frame {
  border-color: rgba(54, 209, 220, 0.55);
  box-shadow: 0 22px 44px -24px rgba(31, 162, 255, 0.55);
}

.project-hero-shot:hover .go {
  color: var(--accent-2);
}

/* ==========================================================================
   Project subpage — testimonial
   ========================================================================== */
.testimonial {
  position: relative;
  padding-block: 88px;
  overflow: hidden;
}

.testimonial::before {
  content: "";
  position: absolute;
  top: -60px;
  left: 50%;
  transform: translateX(-50%);
  width: 900px;
  height: 700px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(31, 162, 255, 0.12) 0%,
    rgba(31, 162, 255, 0) 65%
  );
  pointer-events: none;
}

.testimonial-card {
  position: relative;
  max-width: 880px;
  margin: 0 auto;
  padding: 48px;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: linear-gradient(
    180deg,
    rgba(28, 36, 78, 0.55) 0%,
    rgba(10, 16, 40, 0.55) 100%
  );
}

.quote-mark {
  position: absolute;
  top: 8px;
  left: 30px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 120px;
  line-height: 1;
  color: rgba(54, 209, 220, 0.16);
  pointer-events: none;
}

.testimonial-quote {
  position: relative;
  margin: 0 0 32px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  line-height: 1.55;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.74);
}

/* Highlight single words / phrases inside the review. Wrap text in
   <span class="hl"> … </span> in the testimonial quote to emphasise it. */
.testimonial-quote .hl {
  font-weight: 600;
  color: #fff;
}

.testimonial-author {
  display: flex;
  align-items: center;
  gap: 14px;
}

.testimonial-author .avatar {
  width: 56px;
  height: 56px;
  border-radius: 100px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid var(--line);
}

.testimonial-author .who strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.2;
}

.testimonial-author .who span {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent-2);
}

/* ==========================================================================
   Project subpage — featured work
   ========================================================================== */
.featured {
  padding-block: 40px 88px;
}

.featured-grid {
  display: grid;
  grid-template-columns: repeat(var(--featured-cols, 3), 1fr);
  gap: 24px;
}

.feature-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: linear-gradient(
    180deg,
    rgba(28, 36, 78, 0.55) 0%,
    rgba(10, 16, 40, 0.55) 100%
  );
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-4px);
  border-color: rgba(54, 209, 220, 0.55);
  box-shadow: 0 22px 44px -24px rgba(31, 162, 255, 0.55);
}

.feature-card .card-shot {
  height: 156px;
  display: grid;
  place-items: center;
}

/* Featured-work glyph: a bracketed "engineering module" tile. The "</>"
   placeholder slot is repurposed as a soft glow halo behind the chip; the
   engineering grid (::after) stays for atmosphere. */
.card-shot.has-icon::before {
  content: "";
  background: radial-gradient(
    circle at 50% 50%,
    rgba(31, 162, 255, 0.26),
    transparent 62%
  );
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.feature-glyph {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  border-radius: 16px;
  /* Crisp gradient hairline via the padding-box / border-box trick, matching
     the site's signature blue→teal --grad. */
  border: 1px solid transparent;
  background: linear-gradient(
        180deg,
        rgba(20, 28, 64, 0.92),
        rgba(8, 13, 34, 0.95)
      )
      padding-box,
    var(--grad) border-box;
  box-shadow: 0 18px 36px -18px rgba(31, 162, 255, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.feature-glyph .feature-icon {
  width: 36px;
  height: 36px;
  filter: drop-shadow(0 2px 7px rgba(31, 162, 255, 0.45));
}

/* Reuse the hero-shot corner-bracket motif, dimmed until hover. */
.card-shot.has-icon .frame-corner {
  width: 15px;
  height: 15px;
  border-color: rgba(54, 209, 220, 0.45);
  transition: border-color 0.25s ease;
}

.feature-card:hover .feature-glyph {
  transform: translateY(-3px);
  box-shadow: 0 26px 48px -16px rgba(31, 162, 255, 0.8),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.feature-card:hover .card-shot.has-icon::before {
  transform: scale(1.08);
}

.feature-card:hover .card-shot.has-icon .frame-corner {
  border-color: var(--accent-2);
}

@media (prefers-reduced-motion: reduce) {
  .feature-glyph,
  .card-shot.has-icon::before {
    transition: none;
  }
}

.feature-card h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.01em;
  margin: 0;
  padding-inline: 4px;
}

.feature-bullets {
  margin: 0;
  padding: 4px 4px 4px 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.feature-bullets li {
  position: relative;
  padding-left: 22px;
  font-size: 15px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.82);
}

.feature-bullets li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 9px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent-2);
}

/* ==========================================================================
   Project subpage — results
   ========================================================================== */
.results {
  padding-block: 0 96px;
}

.results-grid {
  display: grid;
  /* --results-cols is set inline from the actual result count, capped at 4,
     so 2- or 3-result grids stay full width instead of leaving empty tracks */
  grid-template-columns: repeat(var(--results-cols, 4), 1fr);
  gap: 24px;
}

.result-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 28px 24px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.result-card:hover {
  border-color: rgba(54, 209, 220, 0.5);
  transform: translateY(-3px);
}

.result-card strong {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 40px;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.result-card span {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent-2);
}

/* ==========================================================================
   Toasts — terminal-style transient notifications
   ========================================================================== */
.toaster {
  position: fixed;
  z-index: 100;
  right: 24px;
  bottom: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(360px, calc(100vw - 32px));
  pointer-events: none;
}

.toast {
  position: relative;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: linear-gradient(
    180deg,
    rgba(28, 36, 78, 0.92) 0%,
    rgba(10, 16, 40, 0.92) 100%
  );
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px -22px rgba(31, 162, 255, 0.75),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(12px);
  overflow: hidden;
  cursor: pointer;
  animation: toast-in 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.toast.is-leaving {
  animation: toast-out 0.28s ease forwards;
}

/* gradient accent edge, echoing the brand monogram */
.toast::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--grad);
}

.toast-icon {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: rgba(54, 209, 220, 0.12);
  border: 1px solid var(--accent-2);
  color: var(--accent-2);
}

.toast-icon .icon {
  width: 18px;
  height: 18px;
}

.toast-body {
  min-width: 0;
  flex: 1;
}

.toast-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.3;
  margin: 0;
  color: #fff;
}

.toast-msg {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  color: var(--light);
  margin: 2px 0 0;
  word-break: break-word;
}

/* countdown bar that drains over the toast's lifetime */
.toast-bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  transform-origin: left center;
  background: var(--grad);
  animation: toast-timer linear forwards;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(16px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes toast-out {
  to {
    opacity: 0;
    transform: translateX(20px);
  }
}

@keyframes toast-timer {
  from {
    transform: scaleX(1);
  }
  to {
    transform: scaleX(0);
  }
}

@media (max-width: 640px) {
  .toaster {
    left: 16px;
    right: 16px;
    bottom: 16px;
    width: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .toast,
  .toast.is-leaving {
    animation: none;
  }
  .toast-bar {
    animation: none;
  }
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  border-top: 1px solid var(--line);
  padding-block: 30px;
}

.site-footer .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.site-footer .company {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
}

.site-footer .addr {
  max-width: 260px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1100px) {
  :root {
    --pad-x: 32px;
  }
  .portfolio-grid,
  .featured-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .results-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 900px) {
  .nav {
    /* fixed (not absolute) so the menu is anchored to the viewport, not the
       document — an absolute menu rendered off-screen once the page was
       scrolled. Capped to the space below the header with its own scroll, so a
       long menu stays reachable even though page scrolling is locked. */
    position: fixed;
    top: 75px;
    left: 0;
    right: 0;
    max-height: calc(100dvh - 75px);
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: #05081a;
    border-bottom: 1px solid var(--line);
    padding: 8px 32px 16px;
    /* animate open/close: display can't transition, so fade + slide
       with visibility, kept in the DOM for a smooth menu reveal */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease,
      visibility 0s linear 0.25s;
  }
  .nav.open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto;
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s;
  }
  .nav a {
    padding: 12px 0;
    width: 100%;
  }
  /* Keep the language switcher a compact pill row inside the stacked menu,
     overriding the full-width .nav a treatment above. */
  .lang-switch {
    margin-top: 10px;
  }
  .lang-switch a {
    width: auto;
    padding: 3px 9px;
  }
  .nav-toggle {
    display: block;
  }
  .hero .container,
  .about .container,
  .contact .container,
  .project-hero .container {
    grid-template-columns: 1fr;
  }
  /* The 72px desktop gap becomes an oversized row gap once stacked. */
  .contact .container {
    gap: 40px;
  }
  .hero h1 {
    font-size: 42px;
  }
  .project-hero h1 {
    font-size: 40px;
  }
  .hero-photo {
    grid-row: 1;
    justify-self: start;
    max-width: 420px;
  }
  /* square portrait once the hero stacks, overriding the img's
     intrinsic 564×538 ratio */
  .hero-photo img {
    aspect-ratio: 1 / 1;
    height: auto;
    object-fit: cover;
  }
  .project-hero-shot {
    justify-self: start;
    max-width: 520px;
  }
  .testimonial-card {
    padding: 36px 28px;
  }
  .testimonial-quote {
    font-size: 19px;
  }
  .contact-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 640px) {
  :root {
    --pad-x: 20px;
  }
  .portfolio-grid,
  .featured-grid,
  .results-grid {
    grid-template-columns: 1fr;
  }
  /* let single-column cards shrink instead of forcing track overflow */
  .card,
  .feature-card,
  .result-card {
    min-width: 0;
  }
  .card-tags {
    flex-wrap: wrap;
  }
  /* tighter top of hero on phones */
  .hero .container {
    padding-block: 28px 44px;
    min-height: 0;
    gap: 32px;
  }
  /* drop the large top padding so these sections sit closer on mobile */
  .about,
  .contact {
    padding-top: 0;
  }
  .hero h1 {
    font-size: 34px;
  }
  .project-hero h1 {
    font-size: 32px;
  }
  .section-head h2,
  .about h2,
  .contact h2 {
    font-size: 30px;
  }
  .stats {
    flex-direction: column;
  }
  .site-footer .container {
    flex-direction: column;
    align-items: flex-start;
  }
  .site-footer .addr {
    text-align: left;
  }
}

/* ==========================================================================
   Motion — scroll reveal, ambient drift, and on-theme flourishes
   All new motion is opt-in: it only runs when the user has not requested
   reduced motion (CSS gates on prefers-reduced-motion; JS checks matchMedia
   before hiding anything). With JS off or reduced motion, the page renders
   fully visible and static — these styles never leave content hidden.
   ========================================================================== */

/* --- #1 Scroll reveal ----------------------------------------------------- */
/* The hidden state is applied by main.js (.reveal-init) only when motion is
   allowed, then .is-visible is toggled on as each element scrolls into view
   via IntersectionObserver. With JS off / reduced motion, nothing is hidden. */
.reveal-init {
  opacity: 0;
  transform: translateY(28px);
}

.reveal-init.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* Let the testimonial settle a beat after it scrolls in so the quote lands
   with a little more weight than the surrounding blocks. */
.testimonial-card.reveal-init.is-visible {
  transition-delay: 0.3s;
}

/* --- #3 Frame-corner draw-in --------------------------------------------- */
/* Each L-bracket grows out from the corner it's anchored to. */
@keyframes draw-corner {
  from {
    opacity: 0;
    transform: scale(0.2);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.hero-photo .frame-corner.tl,
.about-photo .frame-corner.tl {
  transform-origin: top left;
}
.hero-photo .frame-corner.tr,
.about-photo .frame-corner.tr {
  transform-origin: top right;
}
.hero-photo .frame-corner.bl,
.about-photo .frame-corner.bl {
  transform-origin: bottom left;
}
.hero-photo .frame-corner.br,
.about-photo .frame-corner.br {
  transform-origin: bottom right;
}

@media (prefers-reduced-motion: no-preference) {
  /* Hero photo is above the fold → draw in on load, after the photo rises */
  .hero-photo .frame-corner {
    animation: draw-corner 0.5s both;
  }
  .hero-photo .frame-corner.tl {
    animation-delay: 0.55s;
  }
  .hero-photo .frame-corner.tr {
    animation-delay: 0.65s;
  }
  .hero-photo .frame-corner.bl {
    animation-delay: 0.75s;
  }
  .hero-photo .frame-corner.br {
    animation-delay: 0.85s;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* About photo is below the fold → draw in once its block reveals (the
     .is-visible class is toggled by the scroll-reveal observer in main.js) */
  .about-visual.is-visible .frame-corner {
    animation: draw-corner 0.5s both;
  }
  .about-visual.is-visible .frame-corner.tl {
    animation-delay: 0.15s;
  }
  .about-visual.is-visible .frame-corner.tr {
    animation-delay: 0.25s;
  }
  .about-visual.is-visible .frame-corner.bl {
    animation-delay: 0.35s;
  }
  .about-visual.is-visible .frame-corner.br {
    animation-delay: 0.45s;
  }
}

/* --- #6 Hero headline highlight: recurring sheen sweep -------------------- */
/* A light streak crosses the gradient words, then rests off-screen for several
   seconds before sweeping again — a periodic highlight, not the constant
   sliding skeleton-style shimmer. Layer 1 is the moving highlight; layer 2 is
   the existing brand gradient. The band is parked off the text at both ends of
   the cycle, so the loop's restart point is invisible. */
.hero h1 .grad-text,
.hero h1 .grad-alt {
  background-image: linear-gradient(
      105deg,
      transparent 42%,
      rgba(255, 255, 255, 0.85) 50%,
      transparent 58%
    ),
    var(--grad);
  background-size: 300% 100%, 100% 100%;
  background-repeat: no-repeat;
  /* at rest the highlight band sits off to the right, out of the text */
  background-position: 150% center, center;
}

.hero h1 .grad-alt {
  background-image: linear-gradient(
      105deg,
      transparent 42%,
      rgba(255, 255, 255, 0.85) 50%,
      transparent 58%
    ),
    var(--grad-bright);
}

@media (prefers-reduced-motion: no-preference) {
  .hero h1 .grad-text {
    animation: text-sheen 6.5s 0.6s ease-out infinite;
  }
  .hero h1 .grad-alt {
    /* offset so the two words catch the light in sequence, like a wave */
    animation: text-sheen 6.5s 1.4s ease-out infinite;
  }
}

@keyframes text-sheen {
  /* sweep across in the first ~24% of the cycle... */
  0% {
    background-position: 150% center, center;
  }
  24% {
    background-position: -60% center, center;
  }
  /* ...then hold off the left edge (invisible) for the rest before repeating */
  100% {
    background-position: -60% center, center;
  }
}

/* --- #7 Drifting ambient background (hero glows + page grid) -------------- */
@media (prefers-reduced-motion: no-preference) {
  .hero::before {
    animation: glow-drift-l 17s ease-in-out infinite alternate;
  }
  .hero::after {
    animation: glow-drift-r 21s ease-in-out infinite alternate;
  }
  body::before {
    animation: grid-drift 40s linear infinite;
  }
}

@keyframes glow-drift-l {
  to {
    transform: translate(44px, 32px) scale(1.08);
  }
}

@keyframes glow-drift-r {
  to {
    transform: translate(-40px, 26px) scale(1.05);
  }
}

/* background-size is 64px, so a 64px shift loops the grid seamlessly */
@keyframes grid-drift {
  to {
    background-position: 64px 64px;
  }
}
