/* ============================================================
   NEBULAFORGE — Futuristic 3D Interactive Stylesheet
   ============================================================ */

:root {
  /* Royal luxury palette — midnight plum, gold, champagne, royal amethyst */
  --bg: #08060f;
  --bg-soft: #161129;
  --panel: rgba(26, 19, 42, 0.55);
  --panel-border: rgba(212, 175, 55, 0.55);
  --royal: #7b5fc0;
  --gold: #d4af37;
  --champagne: #f0dfaf;
  --text: #f3edde;
  --text-dim: #a99e86;
  --font-display: 'Cinzel', serif;
  --font-script: 'Great Vibes', cursive;
  --font-body: 'Cormorant Garamond', serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 19.5px;
  font-weight: 500;
  line-height: 1.65;
  overflow-x: hidden;
  cursor: none;
}

@media (hover: none), (max-width: 768px) {
  body { cursor: auto; }
  .cursor-dot, .cursor-ring { display: none; }
}

::selection { background: var(--royal); color: #fff; }

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--royal), var(--gold));
  border-radius: 5px;
}

/* ============ LOADER ============ */
#loader {
  position: fixed; inset: 0; z-index: 10000;
  background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 28px;
  transition: opacity 0.8s ease, visibility 0.8s;
}
#loader.done { opacity: 0; visibility: hidden; }

.loader-core { position: relative; width: 140px; height: 140px; display: grid; place-items: center; }
.loader-logo-img {
  width: 56px; height: 56px;
  filter: drop-shadow(0 0 14px rgba(212, 175, 55, 0.7));
}
.loader-ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--royal);
  animation: spin 1.2s linear infinite;
}
.loader-ring.r2 { inset: 14px; border-top-color: var(--gold); animation-duration: 1.8s; animation-direction: reverse; }
.loader-ring.r3 { inset: 28px; border-top-color: var(--champagne); animation-duration: 2.4s; }
@keyframes spin { to { transform: rotate(360deg); } }

.loader-text {
  font-family: var(--font-display); letter-spacing: 4px; font-size: 0.8rem; color: var(--text-dim);
}
.loader-bar {
  width: 220px; height: 3px; background: rgba(123, 95, 192, 0.2); border-radius: 3px; overflow: hidden;
}
.loader-bar-fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--royal), var(--gold));
  transition: width 0.3s ease;
}

/* ============ CUSTOM CURSOR ============ */
.cursor-dot {
  position: fixed; width: 8px; height: 8px; border-radius: 50%;
  background: var(--gold); pointer-events: none; z-index: 9999;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 12px var(--gold);
}
.cursor-ring {
  position: fixed; width: 36px; height: 36px; border-radius: 50%;
  border: 1.5px solid rgba(123, 95, 192, 0.7); pointer-events: none; z-index: 9998;
  transform: translate(-50%, -50%);
  transition: width 0.25s, height 0.25s, border-color 0.25s;
}
.cursor-ring.hovering { width: 64px; height: 64px; border-color: var(--gold); }
.cursor-ring.constellation-hover {
  width: 74px; height: 74px;
  border-color: var(--champagne);
  box-shadow: 0 0 24px rgba(212, 175, 55, 0.55), inset 0 0 14px rgba(212, 175, 55, 0.25);
}

/* ============ 3D BACKGROUND ============ */
#bg3d {
  position: fixed; inset: 0; z-index: -1; display: block;
}

.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0%;
  background: linear-gradient(90deg, var(--royal), var(--gold), var(--champagne));
  z-index: 1001;
  box-shadow: 0 0 10px var(--royal);
}

/* ============ NAVBAR ============ */
.navbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 5vw;
  transition: background 0.4s, backdrop-filter 0.4s, padding 0.4s, box-shadow 0.4s;
}
.navbar.scrolled {
  background: rgba(8, 6, 15, 0.75);
  backdrop-filter: blur(16px);
  padding: 12px 5vw;
  box-shadow: 0 4px 30px rgba(123, 95, 192, 0.15);
  border-bottom: 1px solid var(--panel-border);
}

.nav-logo { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.logo-mark {
  width: 42px; height: 42px; display: block;
  filter: drop-shadow(0 0 8px rgba(212, 175, 55, 0.55));
  animation: logo-glow 3.5s ease-in-out infinite;
  transition: transform 0.5s ease;
}
.nav-logo:hover .logo-mark { transform: rotate(90deg) scale(1.08); }
@keyframes logo-glow {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(212, 175, 55, 0.45)); }
  50% { filter: drop-shadow(0 0 16px rgba(212, 175, 55, 0.85)); }
}
.logo-icon {
  font-size: 1.6rem; color: var(--gold);
  animation: pulse-glow 3s ease-in-out infinite;
}
@keyframes pulse-glow {
  0%, 100% { text-shadow: 0 0 8px var(--gold); }
  50% { text-shadow: 0 0 24px var(--gold), 0 0 40px var(--royal); }
}
.logo-text {
  font-family: var(--font-display); font-weight: 800; font-size: 1.15rem;
  letter-spacing: 2px; color: var(--text);
}
.logo-text em {
  font-style: normal;
  background: linear-gradient(90deg, var(--royal), var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Gap tightens as the viewport narrows so the eight items (seven links + the
   CTA) still clear the logo at the 1200px drawer breakpoint, and stays at a
   roomy 30px on large screens. */
.nav-links { display: flex; align-items: center; gap: clamp(18px, 1.6vw, 30px); list-style: none; }
.nav-links a {
  color: var(--text-dim); text-decoration: none; font-weight: 600;
  font-size: 0.95rem; letter-spacing: 1px; text-transform: uppercase;
  transition: color 0.3s;
  position: relative;
  /* Never let a link (especially the CTA) wrap mid-label — wrapping silently
     inflates the navbar height instead of showing that space has run out. */
  white-space: nowrap;
}
.nav-links a::after {
  content: ''; position: absolute; bottom: -6px; left: 0; width: 0%; height: 2px;
  background: linear-gradient(90deg, var(--royal), var(--gold));
  transition: width 0.3s;
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after { width: 100%; }

.nav-cta {
  padding: 10px 22px; border: 1px solid var(--royal); border-radius: 30px;
  color: var(--text) !important;
  background: rgba(123, 95, 192, 0.12);
  transition: background 0.3s, box-shadow 0.3s !important;
}
.nav-cta:hover { background: rgba(123, 95, 192, 0.3); box-shadow: 0 0 20px rgba(123, 95, 192, 0.5); }
.nav-cta::after { display: none; }

.nav-toggle {
  display: none; background: none; border: none; flex-direction: column; gap: 6px; cursor: pointer;
}
.nav-toggle span { width: 26px; height: 2px; background: var(--text); transition: 0.3s; }

/* The inline nav needs ~1160px before the links collide with the logo, so the
   drawer has to take over well above the usual tablet breakpoint — below this
   the CTA used to wrap to two or three lines and, under ~960px, get pushed off
   the right edge entirely with no scrollbar to reveal it. */
@media (max-width: 1199px) {
  .nav-toggle { display: flex; }
  .nav-links {
    position: fixed; top: 0; right: -100%; height: 100vh; width: min(320px, 80vw);
    background: rgba(15, 11, 26, 0.97); backdrop-filter: blur(20px);
    flex-direction: column; justify-content: center;
    gap: 28px; /* vertical rhythm in the drawer, independent of the inline clamp */
    transition: right 0.4s ease;
    border-left: 1px solid var(--panel-border);
  }
  .nav-links.open { right: 0; }
}

/* ============ SHARED SECTION LAYOUT ============ */
.section { position: relative; padding: 120px 5vw; max-width: 1400px; margin: 0 auto; }

.section-head { text-align: center; margin-bottom: 70px; }
.section-eyebrow {
  font-family: var(--font-display); font-size: 0.75rem; letter-spacing: 5px;
  color: var(--gold); margin-bottom: 14px;
}
.section-title {
  font-family: var(--font-display); font-size: clamp(2rem, 5vw, 3.4rem);
  font-weight: 800; letter-spacing: 2px;
}
.section-sub { max-width: 640px; margin: 18px auto 0; color: var(--text-dim); font-size: 1.1rem; }

/* Calligraphy accent words — gold gradient script */
.grad-text, .glow-text {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: 1.3em;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1;
  padding: 0 0.12em;
  background: linear-gradient(100deg, var(--gold), var(--champagne) 50%, var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.glow-text { filter: drop-shadow(0 0 18px rgba(212, 175, 55, 0.65)); }

/* ============ BUTTONS ============ */
.btn {
  display: inline-block; padding: 16px 38px; border-radius: 40px;
  font-family: var(--font-display); font-size: 0.85rem; font-weight: 700;
  letter-spacing: 2px; text-transform: uppercase; text-decoration: none;
  cursor: none; border: none; transition: transform 0.3s, box-shadow 0.3s, background 0.3s;
}
@media (hover: none), (max-width: 768px) { .btn { cursor: pointer; } }

.btn-primary {
  background: linear-gradient(135deg, var(--royal), var(--gold));
  color: #1a1206;
  box-shadow: 0 0 25px rgba(123, 95, 192, 0.45);
}
.btn-primary:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 0 45px rgba(212, 175, 55, 0.6); }

.btn-ghost {
  background: transparent; color: var(--text);
  border: 1.5px solid var(--panel-border);
  backdrop-filter: blur(6px);
}
.btn-ghost:hover {
  border-color: var(--gold);
  box-shadow: 0 0 25px rgba(212, 175, 55, 0.35);
  transform: translateY(-3px);
}

/* ============ HERO ============ */
.hero {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding-top: 140px;
}
.hero-eyebrow {
  font-family: var(--font-display); font-size: 0.8rem; letter-spacing: 5px;
  color: var(--gold); margin-bottom: 24px;
}
.hero-title {
  font-family: var(--font-display); font-weight: 900;
  font-size: clamp(2.6rem, 9vw, 6.5rem); line-height: 1.05; letter-spacing: 4px;
}
.hero-title .line { display: block; overflow: hidden; }
.hero-title .line span { display: inline-block; }
.hero-title .grad { line-height: 1.3; }
.hero-title .grad span {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: 1.18em;
  letter-spacing: 0.02em;
  text-transform: none;
  padding: 0 0.18em 0.1em;
  background: linear-gradient(90deg, var(--gold) 0%, var(--champagne) 50%, var(--gold) 100%);
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: shine 5s linear infinite;
}
@keyframes shine { to { background-position: 200% center; } }

.hero-sub { max-width: 680px; margin: 28px auto 0; color: var(--text-dim); font-size: 1.2rem; }

.hero-cta { display: flex; gap: 22px; margin-top: 42px; flex-wrap: wrap; justify-content: center; }

.hero-stats { display: flex; gap: 60px; margin-top: 70px; flex-wrap: wrap; justify-content: center; }
.hstat {
  font-family: var(--font-display); font-size: 2rem; font-weight: 800; color: var(--gold);
  display: flex; flex-direction: column; align-items: center;
}
.hstat small {
  font-family: var(--font-body); font-size: 0.85rem; font-weight: 500;
  color: var(--text-dim); letter-spacing: 2px; text-transform: uppercase; margin-top: 6px;
}

.scroll-hint {
  position: absolute; bottom: 34px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  color: var(--text-dim); font-size: 0.7rem; letter-spacing: 3px; font-family: var(--font-display);
}
.mouse {
  width: 26px; height: 42px; border: 2px solid var(--text-dim); border-radius: 16px;
  display: flex; justify-content: center; padding-top: 8px;
}
.wheel {
  width: 4px; height: 8px; border-radius: 3px; background: var(--gold);
  animation: wheel-drop 1.8s ease-in-out infinite;
}
@keyframes wheel-drop {
  0% { opacity: 1; transform: translateY(0); }
  70% { opacity: 0; transform: translateY(14px); }
  100% { opacity: 0; }
}

/* ============ STORY CHAPTERS ============ */
.story { position: relative; }
.story-chapter {
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center; padding: 100px 6vw;
  position: relative;
}
.story-chapter::before {
  content: attr(data-chapter);
  position: absolute; font-family: var(--font-display); font-weight: 900;
  font-size: clamp(10rem, 30vw, 24rem); color: rgba(123, 95, 192, 0.05);
  z-index: -1; pointer-events: none;
}
.chapter-tag {
  font-family: var(--font-display); font-size: 0.75rem; letter-spacing: 6px;
  color: var(--champagne); margin-bottom: 22px;
  border: 1px solid rgba(240, 223, 175, 0.3); border-radius: 30px; padding: 8px 22px;
}
.chapter-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.8rem, 5vw, 3.6rem); max-width: 900px; line-height: 1.2;
}
.chapter-text {
  max-width: 620px; margin-top: 26px; color: var(--text-dim); font-size: 1.2rem;
}
.story-chapter .btn { margin-top: 40px; }

/* ============ SERVICES ============ */
.services-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 28px;
}
/* ---- .tilt: shared pointer-tilt + cursor-spotlight, used by every
   interactive card across the site (services, showreel, testimonials,
   contact) so hover behavior reads as one consistent system ---- */
.tilt {
  position: relative; overflow: hidden;
  transform-style: preserve-3d;
  transition: transform 0.4s ease, border-color 0.4s, box-shadow 0.4s;
}
.tilt::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(600px circle at var(--mx, 50%) var(--my, 50%), rgba(123, 95, 192, 0.18), transparent 40%);
  opacity: 0; transition: opacity 0.4s;
}
.tilt:hover::before { opacity: 1; }
.tilt:hover {
  border-color: rgba(212, 175, 55, 0.5);
  box-shadow: 0 20px 60px rgba(123, 95, 192, 0.25);
}

.service-card {
  padding: 40px 32px; border-radius: 20px;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(12px);
}
.service-icon { font-size: 2.6rem; margin-bottom: 20px; display: inline-block; }

/* ---- Animated service icons: each gets a small looping motion matching
   its theme, and speeds up on hover for a reactive feel ---- */
@keyframes icon-orbit {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  50% { transform: translateY(-8px) rotate(6deg); }
}
@keyframes icon-flicker {
  0%, 18%, 22%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(255, 200, 80, 0)); }
  20% { transform: scale(1.18); filter: drop-shadow(0 0 10px rgba(255, 200, 80, 0.85)); }
}
@keyframes icon-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes icon-roll {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  25% { transform: translateX(-3px) rotate(-8deg); }
  75% { transform: translateX(3px) rotate(8deg); }
}
@keyframes icon-scan {
  0%, 100% { transform: rotate(-16deg); }
  50% { transform: rotate(16deg); }
}
@keyframes icon-tighten {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-14deg); }
  50% { transform: rotate(0deg); }
  75% { transform: rotate(14deg); }
}
@keyframes icon-think {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(212, 175, 55, 0)); }
  50% { transform: scale(1.12); filter: drop-shadow(0 0 12px rgba(212, 175, 55, 0.65)); }
}
.services-grid .service-card:nth-child(1) .service-icon { animation: icon-orbit 4s ease-in-out infinite; }
.services-grid .service-card:nth-child(2) .service-icon { animation: icon-flicker 3.4s ease-in-out infinite; }
.services-grid .service-card:nth-child(3) .service-icon { animation: icon-spin 9s linear infinite; }
.services-grid .service-card:nth-child(4) .service-icon { animation: icon-roll 2.6s ease-in-out infinite; }
.services-grid .service-card:nth-child(5) .service-icon { animation: icon-scan 3s ease-in-out infinite; transform-origin: 65% 70%; }
.services-grid .service-card:nth-child(6) .service-icon { animation: icon-tighten 3.2s ease-in-out infinite; }
.services-grid .service-card:nth-child(7) .service-icon { animation: icon-think 2.8s ease-in-out infinite; }
.services-grid .service-card:hover .service-icon { animation-duration: 1.1s; }
@media (prefers-reduced-motion: reduce) {
  .service-icon { animation: none !important; }
}

.service-card h3 {
  font-family: var(--font-display); font-size: 1.15rem; letter-spacing: 1px; margin-bottom: 14px;
}
.service-card p { color: var(--text-dim); font-size: 1rem; }
.service-num {
  position: absolute; top: 22px; right: 26px;
  font-family: var(--font-display); font-weight: 900; font-size: 1.6rem;
  background-image: linear-gradient(160deg, var(--champagne) 0%, var(--gold) 55%, #a97e1f 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 0 18px rgba(212, 175, 55, 0.55);
}

/* ============ SHOWREEL ============ */
.video-tile {
  border-radius: 20px;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--panel-border);
  background: var(--bg-soft);
}
.video-tile:hover {
  box-shadow: 0 25px 70px rgba(123, 95, 192, 0.35);
}
.video-tag {
  font-family: var(--font-display); font-size: 0.6rem; letter-spacing: 3px;
  color: var(--gold); margin-bottom: 8px;
}
.play-badge {
  position: absolute; top: 20px; right: 20px;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(123, 95, 192, 0.25); backdrop-filter: blur(8px);
  border: 1px solid var(--panel-border);
  display: grid; place-items: center; color: var(--gold); font-size: 0.85rem;
  transition: background 0.3s, transform 0.3s;
}
.video-tile:hover .play-badge { background: var(--royal); color: #fff; transform: scale(1.1); }

/* ---- reel-tile: a case-study card that opens the live site ---- */
.reel-tile {
  background: #0a0607; border-color: rgba(212, 175, 55, 0.55); cursor: pointer;
  display: block; color: inherit; text-decoration: none;
}
.reel-tile:hover { border-color: rgba(212, 175, 55, 0.85); }
.reel-tile:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.reel-tile .play-badge { color: var(--champagne); }
.visit-hint {
  flex: none; margin-top: 14px;
  font-family: var(--font-display); font-size: 0.7rem; letter-spacing: 1.5px;
  color: #08060f; background: var(--gold);
  padding: 8px 20px; border-radius: 30px;
  transition: background 0.3s, transform 0.3s;
}
.reel-tile:hover .visit-hint, .reel-tile:focus-visible .visit-hint { transform: scale(1.05); }

/* ============ SHOWREEL — CIRCULAR GALLERY ============
   Cards on a 3D ring (driven by main.js). Everything 3D is gated on
   .cg-ready, which the script adds: before it runs — or if it never does —
   the same cards lay out as an ordinary grid, and the tall scroll track that
   the ring turns across does not exist to leave a gap. */
.cg {
  /* 3:4 cards. The ring is pushed back so the front card lands at exactly
     1:1 (see main.js), which means these are the sizes you actually see —
     and text is drawn at the size it is shown. The original component
     instead magnified a 300px card by perspective, which scales an
     already-rasterised card up and leaves every caption soft. Capped by
     viewport height so the card still fits a short laptop screen. */
  --cg-w: min(400px, 78vw, 54vh);
  --cg-h: calc(var(--cg-w) * 4 / 3);
}
.cg-ring {
  display: grid; gap: 26px; justify-content: center;
  grid-template-columns: repeat(auto-fill, var(--cg-w));
}
.cg-item { width: var(--cg-w); height: var(--cg-h); }
.cg-card {
  position: relative; width: 100%; height: 100%;
  aspect-ratio: auto; border-radius: 1.1em; overflow: hidden;
  /* Everything inside is sized in em off this, so the caption scales with
     the card: 16px at the original 300px card width. */
  font-size: calc(var(--cg-w) / 300 * 16);
}
.cg-media {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: saturate(1.05) brightness(0.8);
  transition: filter 0.5s, transform 0.8s;
}
.cg-card:hover .cg-media, .cg-card:focus-visible .cg-media {
  filter: saturate(1.2) brightness(0.95); transform: scale(1.04);
}
.cg-play {
  position: absolute; left: 50%; top: 40%; z-index: 2;
  width: 4em; height: 4em; border-radius: 50%;
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  background: rgba(123, 95, 192, 0.3); backdrop-filter: blur(8px);
  border: 1px solid var(--panel-border); color: var(--champagne);
  transition: background 0.3s, color 0.3s, transform 0.3s, box-shadow 0.3s;
}
/* A triangle's visual centre sits right of its box centre; nudge it. */
.cg-play svg { width: 1.4em; height: 1.4em; margin-left: 0.18em; }
.cg-card:hover .cg-play, .cg-card:focus-visible .cg-play {
  background: var(--royal); color: #fff;
  transform: translate(-50%, -50%) scale(1.1);
  box-shadow: 0 0 0 0.6em rgba(123, 95, 192, 0.18);
}
.cg-caption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  padding: 3.75em 1.15em 1.15em;
  background: linear-gradient(to top, rgba(8, 6, 15, 0.96) 0%, rgba(8, 6, 15, 0.78) 55%, transparent);
}
.cg-caption h3 { font-family: var(--font-display); font-size: 1.05em; letter-spacing: 0.06em; line-height: 1.25; }
.cg-caption p { color: var(--text-dim); font-size: 0.92em; line-height: 1.35; margin-top: 0.25em; }
.cg-caption .video-tag { display: block; margin-bottom: 0.6em; font-size: 0.62em; letter-spacing: 0.3em; }
.cg-caption .visit-hint { display: inline-block; margin-top: 0.75em; padding: 0.55em 1.3em; font-size: 0.64em; letter-spacing: 0.12em; }
.cg-card .play-badge { z-index: 2; top: 0.9em; right: 0.9em; width: 2.4em; height: 2.4em; font-size: 0.85em; }
.cg-hint { display: none; }

/* --- the ring, once main.js has taken over --- */
.cg.cg-ready { height: 320vh; position: relative; }
.cg-ready .cg-stage {
  position: sticky; top: 0; height: 100vh;
  /* full-bleed, so the ring is not clipped to the section's padded column */
  width: 100vw; margin-left: calc(50% - 50vw);
  padding-top: 64px; /* the fixed navbar */
  overflow: hidden; perspective: 2000px;
}
.cg-ready .cg-ring {
  display: block; position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d; will-change: transform;
}
.cg-ready .cg-item {
  position: absolute; left: 50%; top: 50%;
  margin-left: calc(var(--cg-w) / -2); margin-top: calc(var(--cg-h) / -2);
  transition: opacity 0.3s linear;
  /* The original lets the far side of the ring show through, dimmed. Here
     those cards are site captures and captions, and seen from behind they
     read as mirrored text ("ATOYOT") in the gaps between the front cards,
     so the far half is culled and the ring reads as a front-facing arc. */
  backface-visibility: hidden;
}
/* A card past the side of the ring is culled above, but culling does not
   stop it catching a click meant for the card in front of it. Keyboard
   focus still reaches it — and turns it to the front. */
.cg-item.is-behind { pointer-events: none; }
.cg-ready .cg-hint {
  display: block; position: absolute; left: 0; right: 0; bottom: 26px;
  text-align: center; font-family: var(--font-display);
  font-size: 0.62rem; letter-spacing: 3px; text-transform: uppercase;
  color: var(--text-dim);
}
@media (max-width: 640px) {
  .cg-ready .cg-hint { letter-spacing: 2px; padding: 0 16px; }
}

/* ============ PRICING — PACKAGE PICKER ============
   Layout and motion from the 21st.dev pricing section, recoloured from its
   white-and-blue into this site's palette. Hidden-until-revealed states are
   gated on .pz-js (added by main.js), so if the script never runs the
   section simply shows, fully laid out, instead of staying invisible. */
.pricing { overflow: visible; }
.pz { isolation: isolate; }
/* The template's radial wash, as a royal glow behind the heading.
   closest-side makes the ellipse reach zero exactly at the box's edges.
   Centred on the box's top edge (as first written), the glow was at full
   strength along that edge and cut off in a hard horizontal line where the
   section begins. */
.pz::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 640px; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(123, 95, 192, 0.22), transparent);
}
.pz-head { text-align: center; margin-bottom: 64px; }
.pz-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display); font-size: 0.75rem; letter-spacing: 5px; text-transform: uppercase;
  color: var(--gold); margin-bottom: 14px;
}
.pz-eyebrow svg { width: 16px; height: 16px; fill: var(--gold); filter: drop-shadow(0 0 6px rgba(212, 175, 55, 0.6)); }

/* Vertical cut reveal: each word slides down out of its own mask. The mask
   is padded (and the padding cancelled with margins) so the script "Orbit"
   keeps its swashes instead of being sheared off at the line box. */
.pz-word {
  display: inline-block; overflow: hidden; vertical-align: bottom;
  padding: 0.12em 0.18em 0.28em; margin: -0.12em -0.18em -0.28em;
}
.pz-word > .pz-word-in { display: inline-block; }
.pz-js .pz-word > .pz-word-in { transform: translateY(-110%); }
.pz-js.pz-live .pz-word > .pz-word-in {
  transform: none;
  transition: transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(0.4s + var(--w) * 0.15s);
}

/* Blur-rise reveal (the template's TimelineContent), staggered by --i. */
.pz-js .pz-reveal { opacity: 0; transform: translateY(-20px); filter: blur(10px); }
.pz-js.pz-live .pz-reveal {
  opacity: 1; transform: none; filter: none;
  transition: opacity 0.5s, transform 0.5s, filter 0.5s;
  transition-delay: calc(var(--i) * 0.3s);
}

.pz-grid {
  max-width: 1100px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center;
}
.pz-inside h3 { font-family: var(--font-display); font-size: clamp(1.35rem, 2.4vw, 1.8rem); letter-spacing: 1px; margin-bottom: 22px; }
.pz-inside-pkg {
  font-family: var(--font-script); font-size: 1.35em; font-weight: 400; letter-spacing: 0;
  background: linear-gradient(100deg, var(--gold), var(--champagne) 50%, var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pz-features { list-style: none; display: flex; flex-direction: column; gap: 14px; }
.pz-features[hidden] { display: none; }
.pz-features li { display: flex; align-items: center; gap: 14px; font-size: 1.08rem; }
.pz-ico {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--royal), var(--gold));
  box-shadow: 0 0 14px rgba(212, 175, 55, 0.4);
}
.pz-ico svg { width: 15px; height: 15px; fill: none; stroke: #1a1206; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.pz-features li.pz-no { color: var(--text-dim); }
.pz-no .pz-ico { background: transparent; border: 1px solid var(--panel-border); box-shadow: none; }
.pz-no .pz-ico svg { stroke: var(--text-dim); }
/* Feature rows re-run their stagger each time the package changes. */
.pz-js .pz-features li { opacity: 0; transform: translateY(-20px); filter: blur(10px); }
.pz-js .pz-features.pz-show li {
  opacity: 1; transform: none; filter: none;
  transition: opacity 0.5s, transform 0.5s, filter 0.5s;
  transition-delay: calc(var(--i) * 0.1s);
}

.pz-config { display: flex; flex-direction: column; gap: 30px; }
.pz-block h4 {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  font-family: var(--font-display); font-size: 0.95rem; letter-spacing: 2px; text-transform: uppercase;
  margin-bottom: 6px;
}
.pz-badge {
  font-size: 0.6rem; letter-spacing: 2px; padding: 4px 10px; border-radius: 20px;
  color: var(--champagne); background: rgba(240, 223, 175, 0.1); border: 1px solid rgba(240, 223, 175, 0.35);
}
.pz-block > p { color: var(--text-dim); font-size: 0.98rem; margin-bottom: 12px; min-height: 1.6em; }

.pz-switch {
  position: relative; display: grid; grid-template-columns: repeat(3, 1fr);
  padding: 4px; border-radius: 999px;
  background: rgba(26, 19, 42, 0.7); border: 1px solid var(--panel-border);
}
.pz-switch button {
  position: relative; z-index: 1; height: 52px; border: 0; background: none; border-radius: 999px;
  font-family: var(--font-display); font-size: 0.8rem; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--text-dim); transition: color 0.3s;
}
.pz-switch button:hover { color: var(--text); }
.pz-switch button[aria-checked="true"] { color: #1a1206; }
.pz-switch button:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* The sliding selection (the template's layoutId pill). Before the script
   positions it, it simply sits on the checked button via the fallback rule. */
.pz-pill {
  position: absolute; top: 4px; bottom: 4px; left: 0; width: 0; border-radius: 999px;
  background: linear-gradient(to top, var(--gold), var(--champagne) 55%, var(--gold));
  box-shadow: 0 0 22px rgba(212, 175, 55, 0.45), inset 0 0 0 3px rgba(26, 18, 6, 0.35);
  transition: transform 0.5s cubic-bezier(0.34, 1.4, 0.64, 1), width 0.5s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.pz-switch:not(.pz-ready) button[aria-checked="true"] {
  background: linear-gradient(to top, var(--gold), var(--champagne) 55%, var(--gold));
}

.pz-glance { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pz-glance div {
  padding: 12px 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid rgba(212, 175, 55, 0.25);
}
.pz-glance dt { font-family: var(--font-display); font-size: 0.6rem; letter-spacing: 2px; text-transform: uppercase; color: var(--text-dim); }
.pz-glance dd { margin: 4px 0 0; font-size: 1.02rem; font-weight: 600; }

/* Price takes what it needs, the button the rest — at an even split
   "Start with Premium ⟶" wraps its arrow onto a second line. */
.pz-buy { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 16px 28px; }
.pz-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
/* The price owns its line, so the old price and "/ project" always sit on
   the one below — otherwise they hop between lines as the width changes
   from 6,999 to 14,999 and the whole row jumps. */
.pz-now {
  flex-basis: 100%;
  font-family: var(--font-display); font-weight: 800; line-height: 1.1;
  font-size: clamp(2.2rem, 4vw, 3rem); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pz-now sup { font-size: 0.5em; margin-right: 2px; color: var(--gold); }
.pz-was { color: var(--text-dim); font-size: 1.15rem; text-decoration-thickness: 2px; text-decoration-color: rgba(212, 175, 55, 0.8); }
.pz-price small { color: var(--text-dim); font-size: 0.85rem; }
.pz-cta { width: 100%; text-align: center; padding: 18px 20px; white-space: nowrap; letter-spacing: 1.5px; }

/* Rolling digits (the template's NumberFlow): each digit is a 0–9 strip in a
   one-digit window, slid to the right figure. Commas stay put. */
.pz-num { display: inline-flex; }
.pz-d { display: inline-block; height: 1.1em; overflow: hidden; transition: width 0.4s, opacity 0.4s; }
.pz-d-strip { display: flex; flex-direction: column; transition: transform 0.7s cubic-bezier(0.34, 1.25, 0.64, 1); }
.pz-d-strip > span { height: 1.1em; line-height: 1.1em; text-align: center; }
.pz-d.pz-enter, .pz-d.pz-leave { opacity: 0; }

.pz-custom { color: var(--text-dim); font-size: 0.95rem; line-height: 1.6; }
.pz-link {
  border: 0; background: none; padding: 0; font: inherit; font-weight: 600; color: var(--gold);
  text-decoration: underline; text-underline-offset: 3px;
}
.pz-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 860px) {
  .pz-grid { grid-template-columns: 1fr; gap: 44px; }
}
@media (max-width: 520px) {
  .pz-switch button { height: 42px; font-size: 0.68rem; letter-spacing: 1px; }
  .pz-glance { grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
  .pz-glance div { padding: 10px; }
  .pz-glance dd { font-size: 0.88rem; }
  .pz-buy { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .pz-js .pz-reveal, .pz-js .pz-features li, .pz-js .pz-word > .pz-word-in { opacity: 1; transform: none; filter: none; transition: none; }
  .pz-pill, .pz-d-strip, .pz-d { transition: none; }
}

/* ============ PROCESS TIMELINE ============ */
.timeline { position: relative; max-width: 800px; margin: 0 auto; padding-left: 40px; }
.timeline-line {
  position: absolute; left: 20px; top: 0; width: 3px; height: 100%;
  background: rgba(123, 95, 192, 0.15);
  overflow: hidden;
}
.timeline-line::after {
  content: ''; position: absolute; top: 0; left: 0; width: 100%; height: var(--fill, 0%);
  background: linear-gradient(180deg, var(--royal), var(--gold));
  box-shadow: 0 0 12px var(--royal);
  transition: height 0.2s linear;
}
.timeline-item { position: relative; display: flex; gap: 30px; padding: 30px 0; }
.timeline-dot {
  position: absolute; left: -40px; top: 34px;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 800;
  background: var(--bg-soft); border: 2px solid var(--royal);
  color: var(--gold);
  transform: translateX(1px);
  z-index: 2;
}
.timeline-card {
  flex: 1; padding: 26px 30px; border-radius: 16px;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(10px);
  margin-left: 26px;
}
.timeline-card h3 { font-family: var(--font-display); letter-spacing: 1px; margin-bottom: 8px; font-size: 1.05rem; }
.timeline-card p { color: var(--text-dim); font-size: 0.98rem; }

/* ============ TESTIMONIALS ============ */
.testi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 26px; }
.testi-card {
  padding: 36px 30px; border-radius: 20px;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(12px);
  font-size: 1.05rem;
}
.testi-card p::before { content: '“'; color: var(--gold); font-size: 1.6rem; }
.testi-card p::after { content: '”'; color: var(--gold); font-size: 1.6rem; }
.testi-card footer {
  margin-top: 20px; font-family: var(--font-display); font-size: 0.85rem; color: var(--gold);
}
.testi-card footer span { display: block; font-family: var(--font-body); color: var(--text-dim); font-size: 0.85rem; margin-top: 4px; }

/* ============ FAQ ============ */
.faq-list { max-width: 820px; margin: 0 auto; display: flex; flex-direction: column; gap: 18px; }

.faq-item {
  border-radius: 18px;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(12px);
  overflow: hidden;
  transition: border-color 0.4s, box-shadow 0.4s;
}
.faq-item.active { border-color: rgba(212, 175, 55, 0.55); box-shadow: 0 16px 50px rgba(212, 175, 55, 0.12); }

.faq-question {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 26px 30px;
  background: none; border: none; cursor: none;
  text-align: left;
  font-family: var(--font-display); font-size: 1.05rem; letter-spacing: 0.5px;
  color: var(--text);
}
@media (hover: none), (max-width: 768px) { .faq-question { cursor: pointer; } }

.faq-icon {
  flex-shrink: 0; color: var(--gold); font-size: 1.1rem;
  transition: transform 0.4s ease;
}
.faq-item.active .faq-icon { transform: rotate(135deg); }

.faq-answer {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s ease;
}
.faq-item.active .faq-answer { grid-template-rows: 1fr; }
.faq-answer > p {
  overflow: hidden;
  padding: 0 30px;
  color: var(--text-dim); font-size: 1.05rem;
}
.faq-item.active .faq-answer > p { padding: 0 30px 26px; }

.faq-cta { text-align: center; margin-top: 44px; color: var(--text-dim); font-size: 1.05rem; }
.faq-cta a { color: var(--gold); text-decoration: none; border-bottom: 1px solid rgba(212, 175, 55, 0.4); transition: border-color 0.3s; }
.faq-cta a:hover { border-color: var(--gold); }

/* ============ ENQUIRY FORM ============ */
.enquiry-form {
  max-width: 860px; margin: 0 auto;
  padding: 50px clamp(24px, 5vw, 60px);
  border-radius: 26px;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(16px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }

.form-field { display: flex; flex-direction: column; margin-bottom: 24px; }
.form-field label {
  font-family: var(--font-display); font-size: 0.72rem; letter-spacing: 2px;
  color: var(--gold); margin-bottom: 10px; text-transform: uppercase;
}
.form-field input,
.form-field select,
.form-field textarea {
  background: rgba(8, 6, 15, 0.6);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 15px 18px;
  color: var(--text);
  font-family: var(--font-body); font-size: 1.05rem;
  outline: none;
  transition: border-color 0.3s, box-shadow 0.3s;
  resize: vertical;
}
.form-field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--gold) 50%), linear-gradient(135deg, var(--gold) 50%, transparent 50%); background-position: calc(100% - 22px) 50%, calc(100% - 16px) 50%; background-size: 6px 6px; background-repeat: no-repeat; }
.form-field select option { background: var(--bg-soft); color: var(--text); }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  border-color: var(--gold);
  box-shadow: 0 0 18px rgba(212, 175, 55, 0.25);
}
.form-field input::placeholder, .form-field textarea::placeholder { color: rgba(169, 158, 134, 0.5); }

/* ---- dual-handle price range slider ---- */
.price-range { position: relative; height: 36px; display: flex; align-items: center; margin-top: 6px; }
.price-range-track {
  position: absolute; left: 0; right: 0; height: 4px; border-radius: 4px;
  background: rgba(169, 158, 134, 0.25);
}
.price-range-fill {
  position: absolute; height: 100%; border-radius: 4px;
  background: linear-gradient(90deg, var(--royal), var(--gold));
}
.form-field input.price-range-thumb {
  position: absolute; left: 0; right: 0; width: 100%;
  margin: 0; padding: 0; background: none; border: none;
  -webkit-appearance: none; appearance: none;
  pointer-events: none;
  outline: none;
}
.price-range-thumb::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  pointer-events: auto;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--champagne);
  border: 2px solid var(--gold);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
}
.price-range-thumb::-webkit-slider-thumb:hover,
.price-range-thumb::-webkit-slider-thumb:active {
  transform: scale(1.15);
  box-shadow: 0 0 16px rgba(212, 175, 55, 0.6);
}
.price-range-thumb::-moz-range-thumb {
  pointer-events: auto;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--champagne);
  border: 2px solid var(--gold);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
.price-range-thumb::-webkit-slider-runnable-track { background: transparent; }
.price-range-thumb::-moz-range-track { background: transparent; }
.price-range-value {
  margin-top: 14px; text-align: center;
  font-family: var(--font-display); font-size: 1.05rem; letter-spacing: 1px;
  color: var(--gold);
}

.btn-launch { width: 100%; font-size: 1rem; padding: 20px; }
.btn-launch:disabled { opacity: 0.6; pointer-events: none; }

.form-status {
  margin-top: 20px; text-align: center; font-weight: 600; min-height: 1.4em;
  letter-spacing: 0.5px;
  opacity: 1;
  transition: opacity 0.6s ease;
}
.form-status.ok { color: #4ade80; }
.form-status.err { color: #f87171; }
.form-status.fade-out { opacity: 0; }

/* ============ CONTACT ============ */
.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; }
.contact-card {
  display: block; padding: 36px 28px; border-radius: 20px; text-align: center;
  background: var(--panel); border: 1px solid var(--panel-border);
  backdrop-filter: blur(12px); text-decoration: none; color: var(--text);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.contact-card:hover {
  border-color: rgba(212, 175, 55, 0.5);
  box-shadow: 0 18px 50px rgba(123, 95, 192, 0.25);
}
.contact-icon { font-size: 2.2rem; display: block; margin-bottom: 16px; }
.contact-card h3 { font-family: var(--font-display); font-size: 0.9rem; letter-spacing: 2px; color: var(--gold); margin-bottom: 8px; }
.contact-card p { color: var(--text-dim); word-break: break-word; }

/* ============ FOOTER ============ */
.footer {
  border-top: 1px solid var(--panel-border);
  background: rgba(8, 6, 15, 0.8);
  backdrop-filter: blur(14px);
  padding: 70px 5vw 0;
}
.footer-inner {
  max-width: 1300px; margin: 0 auto;
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 40px 32px;
}
@media (max-width: 1080px) { .footer-inner { grid-template-columns: 1fr 1fr 1fr; } }
@media (max-width: 800px) { .footer-inner { grid-template-columns: 1fr 1fr; } }
@media (max-width: 500px) { .footer-inner { grid-template-columns: 1fr; } }

.footer-brand p { color: var(--text-dim); margin-top: 16px; max-width: 320px; font-size: 0.98rem; }
.footer-brand .logo-mark {
  display: inline-block; vertical-align: middle;
  width: 36px; height: 36px; margin-right: 10px;
  animation: none;
}
.footer-col h4 {
  font-family: var(--font-display); font-size: 0.8rem; letter-spacing: 3px;
  color: var(--gold); margin-bottom: 18px;
}
.footer-col a, .footer-col p {
  display: block; color: var(--text-dim); text-decoration: none;
  margin-bottom: 10px; transition: color 0.3s; font-size: 0.98rem;
}
.footer-col a:hover { color: var(--gold); }

.footer-bottom {
  max-width: 1300px; margin: 50px auto 0; padding: 24px 0;
  border-top: 1px solid rgba(123, 95, 192, 0.12);
  text-align: center; color: var(--text-dim); font-size: 0.85rem;
}

/* ============ PARALLAX SPARKLE LAYER ============ */
.sparkle-layer {
  position: fixed; inset: 0; z-index: 1;
  pointer-events: none; overflow: hidden;
}
.sparkle {
  position: absolute; top: 0; left: 0;
  color: var(--gold);
  text-shadow: 0 0 8px rgba(212, 175, 55, 0.8);
  animation: twinkle var(--tw, 3s) ease-in-out infinite;
  will-change: transform, opacity;
  line-height: 1;
}
.sparkle.spark-dot {
  border-radius: 50%;
  background: radial-gradient(circle, var(--champagne) 0%, var(--gold) 70%);
  box-shadow: 0 0 10px rgba(212, 175, 55, 0.9);
}
@keyframes twinkle {
  0%, 100% { opacity: 0.15; }
  50% { opacity: 0.85; }
}

/* ============ SCROLL REVEAL DEFAULTS ============ */
.reveal { opacity: 0; }

/* ============ CHAT WIDGET ============ */
.nf-chat { position: fixed; right: 24px; bottom: 24px; z-index: 1200; font-family: var(--font-body); }

/* The UA's [hidden] rule is a bare attribute selector, so any class rule that
   sets display beats it. Without this the phone row and chip tray stayed
   visible at every step and crowded the message box. */
.nf-chat [hidden] { display: none !important; }

/* Lyra herself is the launcher — no label, no icon. The button is a dark well
   for her to glow out of, so the light comes from the creature rather than
   from a gradient behind her. */
.nf-chat-launcher {
  display: grid; place-items: center; padding: 0; cursor: pointer;
  width: 82px; height: 82px; border-radius: 50%;
  border: 1px solid rgba(212, 175, 55, 0.45);
  background: radial-gradient(circle at 50% 45%, rgba(123, 95, 192, 0.38), rgba(8, 6, 15, 0.92) 72%);
  box-shadow: 0 10px 34px rgba(123, 95, 192, 0.45);
  transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
  -webkit-tap-highlight-color: transparent;
}
.nf-chat-launcher:hover {
  transform: translateY(-3px) scale(1.04);
  border-color: var(--gold);
  box-shadow: 0 16px 44px rgba(212, 175, 55, 0.42);
}
.nf-chat-launcher:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* A standing label, because the orb does not say it is a button.
   The session hint below says so once and then leaves, which helps the visitor
   who happens to be looking during those twelve seconds and nobody else. On a
   page whose background is a drifting starfield, a glowing star in the corner
   reads as part of the scenery -- and now that the support assistant sits
   directly above wearing a permanent pill of her own, an unlabelled Lyra loses
   the comparison on every single visit.

   It lives inside the button, so a click on the label opens her, and the
   button's aria-label repeats the visible words -- a control whose spoken name
   omits its printed name is one a voice user cannot ask for. */
.nf-chat-launcher { position: relative; }

.nf-launcher-label {
  position: absolute; right: calc(100% + 12px); top: 50%;
  transform: translateY(-50%);
  white-space: nowrap; cursor: pointer;
  font-family: var(--font-display); font-size: 0.78rem;
  letter-spacing: 0.6px; color: var(--champagne);
  padding: 7px 15px; border-radius: 999px;
  background: rgba(15, 11, 26, 0.94);
  border: 1px solid rgba(212, 175, 55, 0.45);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
  transition: border-color 0.3s, opacity 0.3s, transform 0.3s;
}
.nf-chat-launcher:hover .nf-launcher-label { border-color: var(--gold); }

/* The panel occupies this space once open, and the launcher becomes the
   collapse control -- a "Sales" tab hanging off the button that now closes an
   open conversation is labelling the wrong action. */
.nf-chat.nf-open .nf-launcher-label {
  opacity: 0; pointer-events: none;
  transform: translateY(-50%) translateX(8px);
}

@media (prefers-reduced-motion: reduce) {
  .nf-launcher-label { transition: none; }
}
/* The launcher stays put while the panel is open — it is the collapse control,
   so hiding it left the × as the only way to close. The panel sits above it. */
.nf-chat.nf-open .nf-chat-launcher { box-shadow: 0 8px 26px rgba(212, 175, 55, 0.34); }

.nf-lyra { display: grid; place-items: center; width: 100%; height: 100%; }
.nf-lyra-canvas { width: 100%; height: 100%; display: block; }
/* Shown only until the WebGL canvas takes over — if Three.js is missing or the
   context fails, this is what the button keeps. */
.nf-lyra-fallback {
  font-style: normal; font-size: 1.7rem; color: var(--gold);
  filter: drop-shadow(0 0 10px rgba(212, 175, 55, 0.65));
  animation: nf-lyra-breathe 3.4s ease-in-out infinite;
}
.nf-lyra-live .nf-lyra-fallback { display: none; }
@keyframes nf-lyra-breathe {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.12); }
}

/* First-visit nudge. Without the old text label, nothing says she is clickable. */
.nf-lyra-hint {
  position: absolute; right: 6px; bottom: 96px; width: 232px; cursor: pointer;
  padding: 13px 30px 13px 15px; border-radius: 14px 14px 4px 14px;
  background: rgba(15, 11, 26, 0.97); border: 1px solid rgba(212, 175, 55, 0.45);
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.55);
  animation: nf-hint-in 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.nf-lyra-hint-name {
  font-family: var(--font-display); font-weight: 700; color: var(--champagne);
  font-size: 0.92rem; letter-spacing: 0.5px; margin-bottom: 3px;
}
.nf-lyra-hint-sub { color: var(--text-dim); font-size: 0.82rem; line-height: 1.45; }
.nf-lyra-hint-x {
  position: absolute; top: 5px; right: 7px; background: none; border: none;
  color: var(--text-dim); font-size: 1.15rem; line-height: 1; cursor: pointer;
  padding: 3px 6px; border-radius: 6px; transition: color 0.25s, background 0.25s;
}
.nf-lyra-hint-x:hover { color: var(--gold); background: rgba(212, 175, 55, 0.14); }
@keyframes nf-hint-in {
  from { opacity: 0; transform: translateY(8px) scale(0.96); }
  to { opacity: 1; transform: none; }
}

/* Clears the 82px launcher plus a gap. Tied to it by hand: at the old 60px the
   panel's bottom corner sat over Lyra's head. */
.nf-chat-panel {
  position: absolute; right: 0; bottom: 98px;
  display: flex; flex-direction: column;
  width: min(420px, calc(100vw - 32px)); height: min(600px, calc(100vh - 146px));
  background: rgba(15, 11, 26, 0.97); backdrop-filter: blur(20px);
  border: 1px solid var(--panel-border); border-radius: 18px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
}
/* Dragging a file anywhere over the panel. */
.nf-chat-panel.nf-drag { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.3), 0 24px 60px rgba(0, 0, 0, 0.6); }
.nf-chat-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--panel-border);
  background: linear-gradient(120deg, rgba(123, 95, 192, 0.25), rgba(212, 175, 55, 0.12));
}
.nf-chat-ident { flex: 1; min-width: 0; }

/* Lyra's portrait in the header — the flat twin of the creature on the
   launcher. Both eye shapes ship in the markup; the data-mood attribute picks
   one, which keeps mood changes to a single attribute write. */
.nf-mark { flex: none; display: block; line-height: 0; filter: drop-shadow(0 0 7px rgba(212, 175, 55, 0.35)); }
.nf-mark svg { display: block; }
.nf-mark .nf-mark-happy { display: none; }
.nf-mark[data-mood="happy"] .nf-mark-open { display: none; }
.nf-mark[data-mood="happy"] .nf-mark-happy { display: block; }
/* Thinking narrows her; alert widens her. Transform-origin is the eye line, so
   they close toward the middle rather than sliding upward. */
.nf-mark .nf-mark-open ellipse { transition: transform 0.25s ease; transform-origin: 20px 19.5px; }
.nf-mark[data-mood="thinking"] .nf-mark-open ellipse { transform: scaleY(0.45); }
.nf-mark[data-mood="concerned"] .nf-mark-open ellipse { transform: scaleY(0.72); }
.nf-mark[data-mood="alert"] .nf-mark-open ellipse,
.nf-mark[data-mood="curious"] .nf-mark-open ellipse { transform: scaleY(1.15); }
.nf-mark[data-mood="thinking"] .nf-mark-open circle { opacity: 0; }
.nf-mark-mote { animation: nf-mote 4.5s ease-in-out infinite; }
.nf-mark-mote:nth-of-type(2) { animation-delay: 1.6s; }
@keyframes nf-mote {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

/* Live-connection dot beside "Signed in as …". Never colour alone — each state
   carries a title, and the shapes differ by animation, not just hue. */
.nf-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 6px; vertical-align: baseline; flex: none;
}
.nf-dot-online { background: #4ade80; box-shadow: 0 0 0 2px rgba(74, 222, 128, 0.22); }
.nf-dot-connecting { background: #fbbf24; animation: nf-dot-pulse 1.1s ease-in-out infinite; }
.nf-dot-offline { background: #6b6455; box-shadow: 0 0 0 2px rgba(107, 100, 85, 0.2); }
@keyframes nf-dot-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.8); }
}

/* Options menu, anchored to the kebab at the head's left edge. */
.nf-menu-wrap { position: relative; flex: none; }
.nf-chat-kebab {
  background: none; border: none; cursor: pointer; color: var(--text-dim);
  font-size: 1.35rem; line-height: 1; padding: 2px 6px; border-radius: 6px;
  transition: color 0.3s, background 0.3s;
}
.nf-chat-kebab:hover { color: var(--gold); background: rgba(212, 175, 55, 0.12); }
.nf-menu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 5;
  display: flex; flex-direction: column; min-width: 190px; overflow: hidden;
  background: rgba(15, 11, 26, 0.99); border: 1px solid var(--panel-border);
  border-radius: 12px; box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55);
}
.nf-menu button {
  background: none; border: none; cursor: pointer; text-align: left;
  padding: 11px 14px; color: var(--text); font-family: var(--font-body);
  font-size: 0.9rem; transition: background 0.2s;
}
.nf-menu button:hover:not(:disabled) { background: rgba(212, 175, 55, 0.14); color: var(--champagne); }
.nf-menu button:disabled { opacity: 0.38; cursor: default; }
.nf-menu button + button { border-top: 1px solid rgba(212, 175, 55, 0.18); }
.nf-chat-title { font-family: var(--font-display); font-weight: 700; letter-spacing: 2px; color: var(--text); font-size: 0.95rem; }
.nf-chat-sub { color: var(--text-dim); font-size: 0.8rem; }
/* A downward chevron rather than a cross: this collapses the panel, it does
   not discard the conversation, and the arrow says so. */
.nf-chat-close {
  background: none; border: none; color: var(--text-dim); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none; border-radius: 8px;
  padding: 0; transition: color 0.3s, background 0.3s;
}
.nf-chat-close svg { display: block; }
.nf-chat-close:hover { color: var(--gold); background: rgba(212, 175, 55, 0.12); }

/* Links the assistant sends. */
.nf-link {
  color: var(--gold); text-decoration: underline;
  text-underline-offset: 2px; word-break: break-all;
}
.nf-link:hover { color: var(--champagne); }

.nf-chat-log { flex: 1; overflow-y: auto; padding: 18px 16px; display: flex; flex-direction: column; gap: 12px; }

/* Cloud bubbles.
   ----------------------------------------------------------------------------
   Lyra is made of nebula, so her speech should be too. Three things do the
   work: a very large asymmetric radius so no corner reads as a corner, a soft
   radial fill that is brighter where the light would fall, and a diffuse glow
   instead of a hard border. The result is closer to a lit cloud than a box.
   The `nf-cloud-*` pseudo-elements add two smaller puffs at the tail so the
   silhouette is lumpy rather than a perfect pill. */
.nf-bubble {
  position: relative;
  max-width: 84%; padding: 12px 17px;
  font-size: 0.95rem; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  border: none;
  animation: nf-cloud-in 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}
.nf-bubble::before, .nf-bubble::after {
  content: ''; position: absolute; bottom: 1px; border-radius: 50%;
}

.nf-bubble-bot {
  align-self: flex-start; color: var(--text);
  border-radius: 22px 22px 22px 7px;
  background:
    radial-gradient(120% 140% at 22% 8%, rgba(151, 122, 224, 0.34), rgba(123, 95, 192, 0.16) 62%, rgba(76, 58, 122, 0.14) 100%);
  box-shadow:
    0 0 0 1px rgba(151, 122, 224, 0.22),
    0 6px 22px rgba(76, 45, 138, 0.34),
    inset 0 1px 0 rgba(220, 205, 255, 0.16);
}
/* Two puffs trailing off the tail corner. */
.nf-bubble-bot::before {
  left: -5px; width: 13px; height: 13px;
  background: rgba(129, 101, 198, 0.3); box-shadow: 0 0 0 1px rgba(151, 122, 224, 0.18);
}
.nf-bubble-bot::after {
  left: -12px; bottom: -3px; width: 7px; height: 7px;
  background: rgba(129, 101, 198, 0.24);
}

.nf-bubble-visitor {
  align-self: flex-end; color: var(--champagne);
  border-radius: 22px 22px 7px 22px;
  background:
    radial-gradient(120% 140% at 78% 8%, rgba(240, 210, 130, 0.32), rgba(212, 175, 55, 0.15) 62%, rgba(150, 118, 30, 0.12) 100%);
  box-shadow:
    0 0 0 1px rgba(212, 175, 55, 0.3),
    0 6px 22px rgba(140, 105, 20, 0.28),
    inset 0 1px 0 rgba(255, 240, 200, 0.18);
}
.nf-bubble-visitor::before {
  right: -5px; width: 13px; height: 13px;
  background: rgba(212, 175, 55, 0.24); box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.24);
}
.nf-bubble-visitor::after {
  right: -12px; bottom: -3px; width: 7px; height: 7px;
  background: rgba(212, 175, 55, 0.2);
}

/* Drifts up and settles, like something condensing out of the nebula. */
@keyframes nf-cloud-in {
  from { opacity: 0; transform: translateY(9px) scale(0.94); }
  to { opacity: 1; transform: none; }
}

.nf-bubble-pending { opacity: 0.6; font-style: italic; }
.nf-bubble-text { display: block; }

/* ---- Replies ---- */

/* The reply control sits inside the bubble rather than appearing on hover:
   hover does not exist on a phone, and a long-press would fight the browser's
   own text selection. Faint until the bubble is hovered or focused. */
.nf-reply-btn {
  position: absolute; top: 6px; padding: 0; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; cursor: pointer; opacity: 0.28;
  background: rgba(8, 6, 15, 0.55); border: 1px solid rgba(212, 175, 55, 0.3);
  color: var(--champagne); transition: opacity 0.2s, background 0.2s, border-color 0.2s;
}
.nf-bubble-bot .nf-reply-btn { right: -9px; }
.nf-bubble-visitor .nf-reply-btn { left: -9px; }
.nf-bubble:hover .nf-reply-btn, .nf-reply-btn:focus-visible { opacity: 1; }
.nf-reply-btn:hover { background: rgba(212, 175, 55, 0.22); border-color: var(--gold); }
/* No hover on touch, so the control is always legible there. */
@media (hover: none) { .nf-reply-btn { opacity: 0.6; } }

/* The quoted original, at the top of a reply. */
.nf-quote {
  display: block; margin: -2px 0 8px; padding: 6px 10px; cursor: pointer;
  border-left: 3px solid var(--gold); border-radius: 8px;
  background: rgba(8, 6, 15, 0.4);
}
.nf-quote-bot { border-left-color: rgba(151, 122, 224, 0.85); }
.nf-quote:hover { background: rgba(8, 6, 15, 0.62); }
.nf-quote-who {
  display: block; font-size: 0.72rem; letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 2px;
}
.nf-quote-text {
  display: block; font-size: 0.85rem; color: var(--text-dim); line-height: 1.4;
  white-space: normal;
}

/* Brief highlight when you jump to a quoted original. */
.nf-flash { animation: nf-flash 1.2s ease-out; }
@keyframes nf-flash {
  0%, 40% { box-shadow: 0 0 0 2px var(--gold), 0 6px 22px rgba(0, 0, 0, 0.4); }
  100% { box-shadow: none; }
}

/* The strip above the composer while a reply is pending. */
.nf-reply-strip {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 16px 0; border-top: 1px solid var(--panel-border);
}
.nf-reply-bar { flex: none; width: 3px; align-self: stretch; min-height: 30px; border-radius: 2px; background: var(--gold); }
.nf-reply-bot .nf-reply-bar { background: rgba(151, 122, 224, 0.9); }
.nf-reply-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.nf-reply-who { font-size: 0.72rem; letter-spacing: 1px; text-transform: uppercase; color: var(--text-dim); }
.nf-reply-text {
  font-size: 0.85rem; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nf-reply-x {
  flex: none; background: none; border: none; cursor: pointer; color: var(--text-dim);
  font-size: 1.1rem; line-height: 1; padding: 3px 7px; border-radius: 50%;
  transition: color 0.2s, background 0.2s;
}
.nf-reply-x:hover { color: var(--gold); background: rgba(212, 175, 55, 0.16); }
/* Whichever of these is showing draws the divider; the others stack under it. */
.nf-reply-strip:not([hidden]) + .nf-attach-tray:not([hidden]),
.nf-reply-strip:not([hidden]) + .nf-attach-tray[hidden] + .nf-chat-form,
.nf-reply-strip:not([hidden]) + .nf-chat-form { border-top: none; }

/* "Lyra is typing" — three dots in a bot bubble, shown between her lines. */
.nf-typing { display: inline-flex; gap: 5px; align-items: center; padding: 14px; }
.nf-typing span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--champagne);
  opacity: 0.4; animation: nf-blink 1.2s infinite ease-in-out;
}
.nf-typing span:nth-child(2) { animation-delay: 0.18s; }
.nf-typing span:nth-child(3) { animation-delay: 0.36s; }
@keyframes nf-blink {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* The verification card. Six boxes rather than one field: it is the only point
   in the flow where something has to be copied exactly, and separate boxes
   make a transposed digit visible at a glance. */
.nf-otp-card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px; border-radius: 14px;
  background: rgba(123, 95, 192, 0.12); border: 1px solid rgba(212, 175, 55, 0.4);
}
.nf-otp-label {
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  letter-spacing: 2px; text-transform: uppercase; color: var(--champagne);
}
.nf-otp-boxes { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.nf-otp-boxes input {
  width: 100%; aspect-ratio: 3 / 4; min-width: 0; padding: 0; text-align: center;
  border-radius: 10px; background: rgba(8, 6, 15, 0.9);
  border: 1px solid rgba(212, 175, 55, 0.4); color: var(--champagne);
  font-family: var(--font-display); font-size: 1.25rem; font-weight: 700;
}
.nf-otp-boxes input:focus {
  outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.25);
}
.nf-otp-boxes input:disabled { opacity: 0.55; }
.nf-otp-error { color: #f87171; font-size: 0.85rem; }
.nf-otp-actions { display: flex; flex-direction: column; gap: 8px; }
.nf-otp-submit {
  padding: 11px 18px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--panel-border); color: var(--bg);
  background: linear-gradient(120deg, var(--royal), var(--gold));
  font-family: var(--font-display); font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; font-size: 0.85rem; transition: transform 0.2s;
}
.nf-otp-submit:hover:not(:disabled) { transform: translateY(-1px); }
.nf-otp-submit:disabled { opacity: 0.55; cursor: default; }
.nf-otp-resend {
  background: none; border: none; cursor: pointer; padding: 2px;
  color: var(--text-dim); font-family: var(--font-body); font-size: 0.88rem;
  text-decoration: underline; text-underline-offset: 3px; transition: color 0.25s;
}
.nf-otp-resend:hover:not(:disabled) { color: var(--gold); }
.nf-otp-resend:disabled { opacity: 0.45; cursor: default; text-decoration: none; }

/* Inside the conversation, pulled up against the question bubble above it.
   As a separate tray under the log, the two containers' padding stacked into
   a gap that made the options look unrelated to the question. */
.nf-chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: -6px; }
.nf-chip {
  padding: 6px 12px; border-radius: 20px; cursor: pointer; font-size: 0.85rem;
  background: rgba(212, 175, 55, 0.08); border: 1px solid rgba(212, 175, 55, 0.35);
  color: var(--champagne); font-family: var(--font-body); transition: background 0.3s;
}
.nf-chip:hover { background: rgba(212, 175, 55, 0.22); }

/* ---- Attachments ---- */

/* Files chosen but not yet sent, sitting just above the composer. */
.nf-attach-tray {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 10px 16px 0; border-top: 1px solid var(--panel-border);
}
.nf-attach-chip {
  display: inline-flex; align-items: center; gap: 7px; max-width: 100%;
  padding: 5px 6px 5px 11px; border-radius: 18px;
  background: rgba(212, 175, 55, 0.12); border: 1px solid rgba(212, 175, 55, 0.35);
  font-size: 0.82rem; color: var(--champagne);
}
.nf-attach-busy { opacity: 0.6; }
.nf-attach-name { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nf-attach-size { color: var(--text-dim); font-size: 0.76rem; flex: none; }
.nf-attach-x {
  flex: none; background: none; border: none; cursor: pointer; color: var(--text-dim);
  font-size: 1rem; line-height: 1; padding: 2px 5px; border-radius: 50%;
  transition: color 0.2s, background 0.2s;
}
.nf-attach-x:hover { color: var(--gold); background: rgba(212, 175, 55, 0.2); }

/* Files inside a sent message. */
.nf-file-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.nf-file {
  display: flex; align-items: center; gap: 9px; max-width: 100%;
  padding: 7px 11px 7px 7px; border-radius: 14px; text-decoration: none;
  background: rgba(8, 6, 15, 0.42); border: 1px solid rgba(212, 175, 55, 0.28);
  transition: border-color 0.25s, background 0.25s;
}
a.nf-file:hover { border-color: var(--gold); background: rgba(8, 6, 15, 0.62); }
.nf-file-thumb { width: 42px; height: 42px; border-radius: 9px; object-fit: cover; display: block; flex: none; }
.nf-file-badge {
  width: 42px; height: 42px; border-radius: 9px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg, rgba(123, 95, 192, 0.5), rgba(212, 175, 55, 0.35));
  color: var(--champagne); font-family: var(--font-display); font-weight: 700; font-size: 0.66rem;
  letter-spacing: 0.5px;
}
.nf-file-meta { display: flex; flex-direction: column; min-width: 0; }
.nf-file-name {
  color: var(--text); font-size: 0.85rem; max-width: 168px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nf-file-size { color: var(--text-dim); font-size: 0.75rem; }

.nf-chat-attach {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; padding: 0;
  background: none; border: 1px solid rgba(212, 175, 55, 0.3); color: var(--text-dim);
  transition: color 0.25s, border-color 0.25s, background 0.25s;
}
.nf-chat-attach:hover { color: var(--gold); border-color: var(--gold); background: rgba(212, 175, 55, 0.12); }
.nf-chat-attach svg { display: block; }

.nf-chat-form { display: flex; gap: 8px; padding: 12px 16px 16px; border-top: 1px solid var(--panel-border); align-items: flex-end; }
/* The tray already draws the divider when it is showing. */
.nf-attach-tray:not([hidden]) + .nf-chat-form { border-top: none; }
.nf-chat-input {
  flex: 1 1 auto; min-width: 0; padding: 11px 14px; border-radius: 12px;
  background: rgba(8, 6, 15, 0.85); border: 1px solid rgba(212, 175, 55, 0.35);
  color: var(--text); font-family: var(--font-body); font-size: 0.95rem; line-height: 1.45;
}
.nf-chat-input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.2); }
.nf-chat-input::placeholder { color: rgba(169, 158, 134, 0.6); }
/* Grows with its content up to 120px (set in JS). The panel is a fixed width,
   so there is no horizontal room to give — height is the only axis. */
/* overflow-y is managed in JS: hidden while it can still grow, auto once it
   has hit max-height. Left on `auto` here it shows a scrollbar at every size. */
.nf-chat-textarea { resize: none; overflow-y: hidden; max-height: 120px; }
.nf-chat-send {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--panel-border); color: var(--bg);
  background: linear-gradient(120deg, var(--royal), var(--gold));
  transition: transform 0.2s, opacity 0.2s;
}
.nf-chat-send svg { display: block; }
.nf-chat-send:hover { transform: scale(1.06); }
.nf-chat-send:disabled { opacity: 0.5; cursor: default; transform: none; }
.nf-chat-error { color: #f87171; font-size: 0.85rem; padding: 0 16px 12px; }

@media (max-width: 480px) {
  .nf-chat { right: 12px; bottom: 12px; }
  .nf-chat-launcher { width: 66px; height: 66px; }
  .nf-launcher-label { font-size: 0.72rem; padding: 6px 12px; right: calc(100% + 9px); }
  .nf-lyra-hint { bottom: 80px; width: min(232px, calc(100vw - 40px)); }
  /* 66px launcher + a 12px gap. */
  .nf-chat-panel { bottom: 78px; width: calc(100vw - 24px); height: min(74vh, calc(100vh - 104px)); }
  /* The panel is nearly full-screen on a phone; Lyra behind it is just glare. */
  .nf-chat.nf-open .nf-chat-launcher { opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
  .nf-chat-launcher, .nf-chat-send, .nf-otp-submit { transition: none; }
  .nf-chat-launcher:hover, .nf-chat-send:hover, .nf-otp-submit:hover { transform: none; }
  .nf-typing span, .nf-lyra-fallback { animation: none; }
  .nf-lyra-hint, .nf-bubble { animation: none; }
  .nf-ping { animation: none !important; }
}

/* ---- Signed-in profile ---- */

/* Initials button in the head. Doubles as the way into the tickets sheet, so
   "am I signed in" and "where are my tickets" are the same control. */
.nf-chat-profile {
  flex: none; width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--gold); color: var(--bg);
  background: linear-gradient(120deg, var(--royal), var(--gold));
  font-family: var(--font-display); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.5px; padding: 0;
}
.nf-chat-profile:hover { filter: brightness(1.12); }

/* Pulses once when a status arrives while the sheet is closed, so a live
   update is noticeable without stealing focus from whatever is being typed. */
.nf-ping { animation: nf-ping 1.4s ease-out 2; }
@keyframes nf-ping {
  0% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0.7); }
  70% { box-shadow: 0 0 0 10px rgba(212, 175, 55, 0); }
  100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); }
}

/* ---- Tickets sheet: takes the log's place, keeps the head and the launcher ----
   A flex child rather than an absolutely positioned overlay. Positioned, it had
   to be offset by the head's height as a hard-coded number, and the head is not
   a fixed height — it grows with the "Signed in as …" line and with the user's
   font size, so the sheet sat over the bottom of it. As a flex sibling it
   cannot be wrong. */
.nf-sheet {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  background: rgba(15, 11, 26, 0.99);
}
.nf-sheet-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--panel-border);
}
.nf-sheet-back {
  background: none; border: none; cursor: pointer; color: var(--text-dim);
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px; padding: 0;
  transition: color 0.25s, background 0.25s;
}
.nf-sheet-back:hover { color: var(--gold); background: rgba(212, 175, 55, 0.12); }
.nf-sheet-title {
  font-family: var(--font-display); font-weight: 700; font-size: 0.85rem;
  letter-spacing: 2px; text-transform: uppercase; color: var(--champagne);
}
.nf-sheet-body { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 14px; }
.nf-sheet-empty { color: var(--text-dim); font-size: 0.92rem; line-height: 1.5; }
.nf-sheet-alllink {
  align-self: flex-start; background: none; border: none; cursor: pointer; padding: 2px;
  color: var(--text-dim); font-family: var(--font-body); font-size: 0.88rem;
  text-decoration: underline; text-underline-offset: 3px; transition: color 0.25s;
}
.nf-sheet-alllink:hover { color: var(--gold); }

.nf-profile-card {
  display: flex; align-items: center; gap: 12px;
  padding: 13px; border-radius: 12px;
  background: rgba(123, 95, 192, 0.14); border: 1px solid rgba(212, 175, 55, 0.3);
}
.nf-profile-avatar {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(120deg, var(--royal), var(--gold)); color: var(--bg);
  font-family: var(--font-display); font-weight: 700; font-size: 0.85rem;
}
.nf-profile-name { color: var(--text); font-size: 0.98rem; }
.nf-profile-mail { color: var(--text-dim); font-size: 0.82rem; word-break: break-all; }

/* ---- Ticket list & detail ---- */
.nf-ticket-list { display: flex; flex-direction: column; gap: 9px; }
.nf-ticket {
  display: flex; flex-direction: column; gap: 5px; width: 100%;
  padding: 12px 13px; border-radius: 12px; cursor: pointer; text-align: left;
  background: rgba(123, 95, 192, 0.14); border: 1px solid rgba(212, 175, 55, 0.3);
  font-family: var(--font-body); transition: background 0.25s, border-color 0.25s;
}
.nf-ticket:hover { background: rgba(212, 175, 55, 0.14); border-color: var(--gold); }
.nf-ticket-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.nf-ticket-ref {
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  letter-spacing: 1.5px; color: var(--gold);
}
.nf-ticket-service { color: var(--text); font-size: 0.94rem; }
.nf-ticket-meta { color: var(--text-dim); font-size: 0.8rem; }

.nf-ticket-detail-head { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
/* Without this the pill is a stretched flex child and spans the whole sheet. */
.nf-ticket-detail-head .nf-pill { align-self: flex-start; }
.nf-ticket-blurb { color: var(--text-dim); font-size: 0.88rem; line-height: 1.5; }
.nf-ticket-field { display: flex; flex-direction: column; gap: 3px; }
.nf-ticket-field-label {
  font-size: 0.72rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--text-dim);
}
.nf-ticket-field-value { color: var(--text); font-size: 0.93rem; line-height: 1.55; white-space: pre-wrap; }

/* Status pill. Colour carries meaning here, so each one also reads as words —
   never colour alone. */
.nf-pill {
  flex: none; padding: 3px 10px; border-radius: 20px; font-size: 0.74rem;
  letter-spacing: 1px; text-transform: uppercase; font-family: var(--font-display);
  font-weight: 700; border: 1px solid currentColor;
}
.nf-pill-new { color: #d4af37; background: rgba(212, 175, 55, 0.12); }
.nf-pill-contacted { color: #7dd3fc; background: rgba(125, 211, 252, 0.12); }
.nf-pill-progress { color: #a78bfa; background: rgba(167, 139, 250, 0.14); }
.nf-pill-closed { color: #86efac; background: rgba(134, 239, 172, 0.12); }

/* Progress timeline, newest first — what someone opens a ticket to see is
   what happened last. */
.nf-timeline { display: flex; flex-direction: column; gap: 0; list-style: none; padding-left: 16px; }
.nf-timeline-item {
  position: relative; display: flex; flex-direction: column; gap: 2px;
  padding: 0 0 14px 14px; border-left: 1px solid rgba(212, 175, 55, 0.28);
}
.nf-timeline-item:last-child { border-left-color: transparent; padding-bottom: 0; }
.nf-timeline-item::before {
  content: ''; position: absolute; left: -4.5px; top: 5px;
  width: 8px; height: 8px; border-radius: 50%;
  background: rgba(169, 158, 134, 0.6);
}
.nf-timeline-now::before { background: var(--gold); box-shadow: 0 0 0 3px rgba(212, 175, 55, 0.2); }
.nf-timeline-status { color: var(--text); font-size: 0.9rem; font-weight: 600; }
.nf-timeline-when { color: var(--text-dim); font-size: 0.78rem; }
.nf-timeline-note { color: var(--text-dim); font-size: 0.85rem; line-height: 1.5; margin-top: 3px; white-space: pre-wrap; }

/* ============ PRODUCTS ============
   products.html — one block per product: a video facade, the description,
   and the how-it-works steps. The facade is why there is no YouTube iframe
   in the markup: a cold embed pulls roughly half a megabyte of player and
   sets cookies before anyone has asked to watch anything. Here the tile is
   a local poster and a button, and main.js swaps in the real player on the
   first click — so a visitor who never presses play never touches YouTube. */
.product {
  max-width: 1100px;
  margin: 0 auto 6rem;
  padding: 0 1.25rem;
}
.product + .product { padding-top: 5rem; border-top: 1px solid rgba(255, 255, 255, 0.09); }

.product-head { margin-bottom: 2.25rem; }
.product-eyebrow {
  font-family: var(--font-display); font-size: 0.62rem; letter-spacing: 3px;
  color: var(--gold); text-transform: uppercase;
}
.product-name {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.2rem);
  line-height: 1.1;
  margin: 0.5rem 0 0.4rem;
}
.product-tagline { font-size: clamp(1rem, 2.1vw, 1.2rem); color: var(--text-dim); max-width: 62ch; }
.product-visit {
  display: inline-block; margin-top: 1.1rem;
  font-family: var(--font-display); font-size: 0.72rem; letter-spacing: 1.5px;
  color: #08060f; background: var(--gold);
  padding: 0.6rem 1.4rem; border-radius: 30px; text-decoration: none;
  transition: transform 0.3s, box-shadow 0.3s;
}
.product-visit:hover, .product-visit:focus-visible { transform: scale(1.04); box-shadow: 0 12px 32px rgba(212, 175, 55, 0.3); }

/* ---- video facade ---- */
.pv {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--panel-border);
  background: var(--bg-soft);
}
.pv-btn {
  display: block; width: 100%; height: 100%; padding: 0;
  border: 0; background: none; cursor: pointer; color: inherit;
  font: inherit; position: relative;
}
.pv-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }
.pv-poster { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.6s ease, filter 0.4s; }
.pv-btn:hover .pv-poster, .pv-btn:focus-visible .pv-poster { transform: scale(1.03); filter: brightness(1.08); }

.pv-play {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 74px; height: 74px; border-radius: 50%;
  background: rgba(123, 95, 192, 0.32); backdrop-filter: blur(8px);
  border: 1px solid var(--panel-border);
  display: grid; place-items: center; color: var(--champagne);
  transition: background 0.3s, transform 0.3s, color 0.3s;
}
.pv-play svg { width: 26px; height: 26px; margin-left: 4px; }
.pv-btn:hover .pv-play, .pv-btn:focus-visible .pv-play {
  background: var(--royal); color: #fff; transform: translate(-50%, -50%) scale(1.1);
}

/* Title strip along the foot of the poster, the way a video card reads. */
.pv-strip {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: 0.9rem;
  padding: 2.6rem 1.1rem 0.95rem;
  background: linear-gradient(to top, rgba(8, 6, 15, 0.92), transparent);
  text-align: left;
}
.pv-title { flex: 1; font-size: 0.86rem; line-height: 1.35; color: var(--text); }
.pv-dur {
  flex: none; font-family: var(--font-display); font-size: 0.68rem; letter-spacing: 1px;
  background: rgba(8, 6, 15, 0.75); border: 1px solid rgba(212, 175, 55, 0.4);
  color: var(--champagne); padding: 0.25rem 0.55rem; border-radius: 6px;
}

/* The iframe main.js swaps in, filling the same box the poster occupied. */
.pv iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---- how it works ---- */
.product-how { margin-top: 2.75rem; }
.product-how h3 {
  font-family: var(--font-display); font-size: clamp(1.2rem, 2.6vw, 1.6rem);
  margin-bottom: 0.5rem;
}
.product-how > p { color: var(--text-dim); max-width: 70ch; margin-bottom: 1.75rem; }

.product-steps { list-style: none; display: grid; gap: 1.1rem; counter-reset: pstep; }
@media (min-width: 800px) { .product-steps { grid-template-columns: repeat(2, 1fr); gap: 1.3rem 2rem; } }
.product-steps li {
  counter-increment: pstep;
  position: relative; padding-left: 3.1rem;
}
.product-steps li::before {
  content: '0' counter(pstep);
  position: absolute; left: 0; top: 0.05rem;
  font-family: var(--font-display); font-size: 0.82rem; letter-spacing: 1px;
  color: var(--gold);
  border: 1px solid rgba(212, 175, 55, 0.45); border-radius: 8px;
  padding: 0.2rem 0.45rem;
}
.product-steps li strong { display: block; font-weight: 600; margin-bottom: 0.15rem; }
.product-steps li span { color: var(--text-dim); font-size: 0.95rem; line-height: 1.6; }

/* ---- capability chips ---- */
.product-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 2rem; }
.product-tags li {
  list-style: none;
  font-family: var(--font-display); font-size: 0.62rem; letter-spacing: 1.5px;
  color: var(--text-dim); text-transform: uppercase;
  border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 30px;
  padding: 0.4rem 0.9rem;
}

/* ============ PRODUCTS TEASER (home) ============
   Two cards standing in for products.html. The poster doubles as the link
   target, so the whole tile is clickable without nesting an <a> in an <a>. */
.prod-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 34px;
  max-width: 1240px; margin: 0 auto; padding: 0 1.25rem;
}
@media (max-width: 900px) { .prod-grid { grid-template-columns: 1fr; gap: 28px; } }

.prod-card {
  display: flex; flex-direction: column;
  border-radius: 20px; overflow: hidden;
  border: 1px solid var(--panel-border);
  background: var(--panel); backdrop-filter: blur(6px);
  transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
}
.prod-card:hover {
  border-color: rgba(212, 175, 55, 0.85);
  box-shadow: 0 25px 70px rgba(123, 95, 192, 0.3);
}

.prod-media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg-soft); }
.prod-media img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.6s ease; }
.prod-card:hover .prod-media img { transform: scale(1.04); }
.prod-media:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }

.prod-body { padding: 26px 28px 30px; display: flex; flex-direction: column; flex: 1; }
.prod-tag {
  font-family: var(--font-display); font-size: 0.6rem; letter-spacing: 3px;
  color: var(--gold); text-transform: uppercase;
}
.prod-body h3 {
  font-family: var(--font-display); font-size: 1.9rem; letter-spacing: 1px;
  margin: 10px 0 8px;
}
.prod-desc { color: var(--text-dim); font-size: 1rem; line-height: 1.6; flex: 1; }

.prod-links { display: flex; align-items: center; gap: 22px; margin-top: 22px; }
.prod-cta {
  font-family: var(--font-display); font-size: 0.72rem; letter-spacing: 1.5px;
  color: #08060f; background: var(--gold);
  padding: 10px 22px; border-radius: 30px; text-decoration: none;
  transition: transform 0.3s;
}
.prod-cta:hover, .prod-cta:focus-visible { transform: scale(1.05); }
.prod-out {
  font-family: var(--font-display); font-size: 0.72rem; letter-spacing: 1.5px;
  color: var(--champagne); text-decoration: none;
  border-bottom: 1px solid rgba(240, 223, 175, 0.35); padding-bottom: 2px;
}
.prod-out:hover, .prod-out:focus-visible { border-bottom-color: var(--gold); }
