/* ==========================================================================
   ROBOXCEL INNOVATION — Industrial Precision Theme
   Design system + components for a dark, technical Industry 4.0 site.
   ========================================================================== */

/* ---------- Design tokens ---------- */
:root {
  /* Surfaces (dark navy-charcoal) */
  --bg:          #0A1521;
  --bg-2:        #0E1C2B;
  --surface:     #122639;
  --surface-2:   #18324A;
  --surface-3:   #1F3E5A;

  /* Brand */
  --teal:        #1B4D6E;
  --teal-light:  #2A6A8F;
  --cyan:        #4FB8DD;   /* primary accent  */
  --cyan-bright: #74D6F7;   /* glow / hover    */
  --silver:      #9FB2BE;

  /* Text */
  --text:        #E8F0F5;
  --text-soft:   #B7C7D1;
  --muted:       #7E93A1;

  /* Lines */
  --border:      rgba(159, 178, 190, 0.14);
  --border-soft: rgba(159, 178, 190, 0.08);
  --grid-line:   rgba(79, 184, 221, 0.05);

  /* Effects */
  --glow:        0 0 0 1px rgba(79,184,221,.35), 0 8px 30px rgba(79,184,221,.18);
  --shadow:      0 18px 50px rgba(0, 0, 0, 0.45);
  --radius:      14px;
  --radius-sm:   9px;

  /* Type */
  --font-display: 'Outfit', sans-serif;
  --font-body:    'DM Sans', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;

  --maxw: 1200px;
  --nav-h: 70px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text-soft);
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Blueprint grid backdrop for the whole page */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 80%);
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }

/* ---------- Layout helpers ---------- */
.container { width: min(100% - 48px, var(--maxw)); margin-inline: auto; }
.section   { position: relative; z-index: 1; padding: 96px 0; }
.section--tight { padding: 64px 0; }
.bg-alt    { background: var(--bg-2); }
.center    { text-align: center; }

/* Mono kicker / section label */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 18px;
}
.kicker::before {
  content: "";
  width: 26px;
  height: 1px;
  background: var(--cyan);
  opacity: .7;
}

/* Headings */
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--text); line-height: 1.12; font-weight: 700; }
.h-xl { font-size: clamp(2.4rem, 5.2vw, 4.1rem); font-weight: 800; letter-spacing: -1px; }
.h-lg { font-size: clamp(1.9rem, 3.6vw, 2.8rem); letter-spacing: -.5px; }
.h-md { font-size: clamp(1.3rem, 2vw, 1.6rem); }
.accent { color: var(--cyan); }
.lead   { font-size: clamp(1rem, 1.4vw, 1.18rem); color: var(--text-soft); max-width: 60ch; }

.section-head { max-width: 720px; margin-bottom: 56px; }
.section-head.center { margin-inline: auto; }

/* ---------- Buttons ---------- */
.btn {
  --b: var(--cyan);
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.97rem;
  padding: 14px 26px;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .2s ease, box-shadow .25s ease, background .25s ease, border-color .25s;
  white-space: nowrap;
}
.btn svg { width: 17px; height: 17px; }
.btn--primary {
  background: linear-gradient(135deg, var(--cyan), var(--teal-light));
  color: #06141f;
}
.btn--primary:hover { transform: translateY(-2px); box-shadow: var(--glow); }
.btn--ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text);
}
.btn--ghost:hover { border-color: var(--cyan); color: var(--cyan); transform: translateY(-2px); }
.btn--block { width: 100%; justify-content: center; }

/* ---------- Navigation ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: rgba(10, 21, 33, 0.78);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border-soft);
}
.nav .container { display: flex; align-items: center; justify-content: space-between; }
.nav-logo { display: flex; align-items: center; gap: 11px; }
.nav-logo img { height: 34px; width: auto; }
.nav-logo-text { font-family: var(--font-display); font-weight: 800; font-size: 1.15rem; letter-spacing: 1px; color: #fff; }
.nav-logo-text small { display: block; font-family: var(--font-mono); font-weight: 400; font-size: .54rem; letter-spacing: 3px; color: var(--cyan); }

.nav-links { display: flex; align-items: center; gap: 6px; }
.nav-links a {
  position: relative;
  font-size: .94rem;
  font-weight: 500;
  color: var(--text-soft);
  padding: 9px 14px;
  border-radius: 8px;
  transition: color .2s, background .2s;
}
.nav-links a:hover { color: var(--text); }
.nav-links a.active { color: var(--cyan); }
.nav-links a.active::after {
  content: "";
  position: absolute;
  left: 14px; right: 14px; bottom: 2px;
  height: 2px;
  background: var(--cyan);
  border-radius: 2px;
}
.nav-cta { margin-left: 10px; }

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 8px;
}
.nav-toggle span { width: 24px; height: 2px; background: var(--text); border-radius: 2px; transition: .3s; }
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero { position: relative; z-index: 1; padding: clamp(70px, 11vw, 130px) 0 90px; overflow: hidden; }
.hero::after {
  content: "";
  position: absolute;
  top: -10%; right: -5%;
  width: 620px; height: 620px;
  background: radial-gradient(circle, rgba(79,184,221,.16), transparent 60%);
  filter: blur(20px);
  z-index: -1;
}
.hero-inner { display: grid; grid-template-columns: 1.15fr .85fr; gap: 50px; align-items: center; }
.hero h1 { margin: 6px 0 22px; }
.hero .lead { margin-bottom: 34px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }

/* Corner brackets decoration */
.bracket-frame { position: relative; }
.bracket-frame::before, .bracket-frame::after {
  content: ""; position: absolute; width: 26px; height: 26px; border: 2px solid var(--cyan); opacity: .6;
}
.bracket-frame::before { top: -14px; left: -14px; border-right: 0; border-bottom: 0; }
.bracket-frame::after  { bottom: -14px; right: -14px; border-left: 0; border-top: 0; }

/* Hero visual: rotating tech ring */
.hero-visual { display: flex; justify-content: center; align-items: center; }
.tech-ring {
  position: relative;
  width: min(380px, 80vw);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.tech-ring .ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--border);
}
.tech-ring .ring.r2 { inset: 14%; border-style: dashed; border-color: rgba(79,184,221,.25); animation: spin 28s linear infinite; }
.tech-ring .ring.r3 { inset: 30%; border-color: rgba(79,184,221,.18); }
.tech-ring .ring.r1 { animation: spinrev 60s linear infinite; }
.tech-ring .dot { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 14px var(--cyan); }
.tech-ring .dot.d1 { top: -5px; left: 50%; }
.tech-ring .dot.d2 { bottom: 8%; right: 6%; background: var(--cyan-bright); }
.tech-ring .core {
  width: 54%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--surface-2), var(--bg-2));
  border: 1px solid var(--border);
  display: grid; place-items: center;
  box-shadow: inset 0 0 40px rgba(79,184,221,.12);
}
.tech-ring .core img { width: 58%; opacity: .92; animation: spin 26s linear infinite; transform-origin: center; }
@keyframes spin    { to { transform: rotate(360deg); } }
@keyframes spinrev { to { transform: rotate(-360deg); } }

/* ---------- Stats bar ---------- */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--border-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.stat { background: var(--bg-2); padding: 30px 24px; text-align: center; }
.stat .num { font-family: var(--font-display); font-size: clamp(1.8rem, 3.4vw, 2.6rem); font-weight: 800; color: #fff; }
.stat .num .accent { color: var(--cyan); }
.stat .lbl { font-family: var(--font-mono); font-size: .72rem; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-top: 6px; }

/* ---------- Cards / grids ---------- */
.grid { display: grid; gap: 22px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  position: relative;
  background: linear-gradient(160deg, var(--surface), var(--bg-2));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
  overflow: hidden;
}
.card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--cyan), transparent);
  transform: scaleX(0); transform-origin: left; transition: transform .3s ease;
}
.card:hover { transform: translateY(-5px); border-color: rgba(79,184,221,.4); box-shadow: var(--shadow); }
.card:hover::before { transform: scaleX(1); }
.card .idx { font-family: var(--font-mono); font-size: .78rem; color: var(--cyan); letter-spacing: 2px; }
.card h3 { margin: 12px 0 10px; font-size: 1.22rem; }
.card p  { font-size: .95rem; color: var(--text-soft); }

.icon-badge {
  width: 48px; height: 48px; border-radius: 12px;
  display: grid; place-items: center;
  background: rgba(79,184,221,.1);
  border: 1px solid rgba(79,184,221,.25);
  color: var(--cyan);
  margin-bottom: 16px;
}
.icon-badge svg { width: 24px; height: 24px; }

/* Tag chips */
.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.tag {
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--silver);
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255,255,255,.02);
}

/* ---------- IR4.0 Pillars (home) accordion ---------- */
.pillars-progress {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 14px; margin-bottom: 14px; position: relative;
}
.pillar-step {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  cursor: pointer;
  transition: .25s;
}
.pillar-step .pnum { font-family: var(--font-mono); color: var(--muted); font-size: .82rem; }
.pillar-step .pname { font-family: var(--font-display); font-weight: 600; color: var(--text); margin-top: 4px; font-size: 1.02rem; }
.pillar-step.active { border-color: var(--cyan); background: var(--surface); }
.pillar-step.active .pnum { color: var(--cyan); }

.pillar-panel { display: none; animation: fade .35s ease; }
.pillar-panel.active { display: block; }
@keyframes fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.pillar-panel .panel-head { margin: 26px 0 22px; }
.pillar-panel .panel-head p { color: var(--text-soft); max-width: 60ch; }

/* ---------- Split / feature section ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.feature-list { display: grid; gap: 18px; margin-top: 26px; }
.feature-item { display: flex; gap: 14px; }
.feature-item .ck {
  flex: none; width: 26px; height: 26px; border-radius: 7px;
  background: rgba(79,184,221,.12); border: 1px solid rgba(79,184,221,.3);
  color: var(--cyan); display: grid; place-items: center; font-size: .8rem; margin-top: 2px;
}
.feature-item b { color: var(--text); }

/* ---------- CTA band ---------- */
.cta-band {
  position: relative; z-index: 1;
  text-align: center;
  padding: 80px 0;
  background:
    radial-gradient(ellipse 60% 120% at 50% 0%, rgba(79,184,221,.14), transparent 70%),
    var(--bg-2);
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}
.cta-band h2 { margin-bottom: 14px; }
.cta-band p { margin: 0 auto 28px; max-width: 52ch; }

/* ---------- Page hero (inner pages) ---------- */
.page-hero { position: relative; z-index: 1; padding: clamp(60px, 9vw, 110px) 0 60px; text-align: center; }
.page-hero .lead { margin: 18px auto 0; }

/* ---------- Mission / Vision ---------- */
.mv-card { padding: 36px; }
.mv-card .mv-tag { font-family: var(--font-mono); font-size: .8rem; letter-spacing: 2px; color: var(--cyan); text-transform: uppercase; }
.mv-card h3 { margin: 12px 0 14px; font-size: 1.5rem; }

/* ---------- Contact ---------- */
.contact-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: 40px; align-items: start; }
.contact-info .info-row { display: flex; gap: 16px; padding: 18px 0; border-bottom: 1px solid var(--border-soft); }
.contact-info .info-row:last-child { border-bottom: 0; }
.contact-info .info-row .icon-badge { margin: 0; width: 42px; height: 42px; }
.contact-info .info-row .lbl { font-family: var(--font-mono); font-size: .72rem; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }
.contact-info .info-row .val { color: var(--text); font-weight: 500; }
.socials { display: flex; gap: 12px; margin-top: 26px; }
.socials a {
  width: 42px; height: 42px; border-radius: 10px; display: grid; place-items: center;
  border: 1px solid var(--border); color: var(--text-soft); transition: .25s;
}
.socials a:hover { border-color: var(--cyan); color: var(--cyan); transform: translateY(-3px); }

.form-card { padding: 32px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: .82rem; font-weight: 500; color: var(--text-soft); margin-bottom: 7px; }
.field label .req { color: var(--cyan); }
.field input, .field select, .field textarea {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 12px 14px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: .95rem;
  transition: border-color .2s, box-shadow .2s;
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--cyan); box-shadow: 0 0 0 3px rgba(79,184,221,.15);
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }
.form-note { font-size: .8rem; color: var(--muted); margin-top: 10px; }

/* ---------- Footer ---------- */
.footer { position: relative; z-index: 1; background: var(--bg-2); border-top: 1px solid var(--border-soft); padding: 64px 0 28px; }
.footer-top { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 36px; }
.footer-brand img { width: 150px; height: auto; max-width: 100%; margin-bottom: 16px; }
.footer-brand p { font-size: .9rem; max-width: 34ch; }
.footer h4 { font-size: .82rem; font-family: var(--font-mono); letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; }
.footer ul li { margin-bottom: 10px; }
.footer ul a { font-size: .92rem; color: var(--text-soft); transition: color .2s; }
.footer ul a:hover { color: var(--cyan); }
.footer-bottom {
  margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--border-soft);
  display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  font-size: .85rem; color: var(--muted);
}
.footer-bottom a:hover { color: var(--cyan); }

/* ---------- Scroll reveal ---------- */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .6s ease, transform .6s ease; }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-d="1"] { transition-delay: .08s; }
.reveal[data-d="2"] { transition-delay: .16s; }
.reveal[data-d="3"] { transition-delay: .24s; }

/* ---------- Responsive ---------- */
@media (max-width: 980px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero-visual { order: -1; }
  .split, .contact-grid { grid-template-columns: 1fr; gap: 36px; }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .footer-top { grid-template-columns: 1fr 1fr; }
  .pillars-progress { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .nav-links {
    position: fixed; inset: var(--nav-h) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: rgba(14, 28, 43, 0.98); backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--border);
    padding: 12px 22px 26px;
    box-shadow: 0 24px 44px rgba(0, 0, 0, 0.45);
    max-height: calc(100vh - var(--nav-h)); overflow-y: auto;
    transform: translateY(-12px); opacity: 0; visibility: hidden; pointer-events: none;
    transition: transform .3s cubic-bezier(.22,.61,.36,1), opacity .26s ease, visibility .3s;
    z-index: 99;
  }
  .nav-links.open { transform: none; opacity: 1; visibility: visible; pointer-events: auto; }
  .nav-links > li { border-bottom: 1px solid var(--border-soft); }
  .nav-links > li:last-child { border-bottom: 0; }
  .nav-links > li > a {
    display: block; padding: 16px 4px; font-size: 1.06rem; font-weight: 500; color: var(--text);
  }
  .nav-links > li > a.active, .nav-links .dd-trigger.active { color: var(--cyan); }
  .nav-links a.active::after { display: none; }
  .nav-links .dd-trigger { width: 100%; }
  .nav-cta { margin-top: 18px; }
  .nav-cta a.btn { width: 100%; justify-content: center; padding: 15px; font-size: 1rem; }
  .nav-toggle { display: flex; }
  .stats, .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .section { padding: 64px 0; }
  .footer-top { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; }
}

/* Reduced motion */
/* Animations are intentionally always on (per client request). */

/* ==========================================================================
   ROXPHERE — flagship product page additions
   Module accent colours + product components (reuse base .card/.grid/.btn).
   ========================================================================== */

/* Module accent colours */
:root {
  --m-stor:   #4F9DF5;  /* RoxStor  — warehouse  */
  --m-care:   #1FB6A6;  /* RoxCare  — maintenance*/
  --m-make:   #E0922F;  /* RoxMake  — production */
  --m-check:  #8B6CE8;  /* RoxCheck — quality    */
  --m-people: #5B9BF0;  /* RoxPeople— HR         */
  --m-trade:  #2FC089;  /* RoxTrade — trading   */
}

/* Roxphere wordmark in nav / hero */
.rox-logo { display: flex; align-items: center; gap: 12px; }
.rox-logo img { width: 42px; height: 42px; }
.rox-logo .wm { display: flex; flex-direction: column; line-height: 1; font-family: var(--font-display); font-weight: 800; letter-spacing: 1px; color: #fff; font-size: 1.32rem; }
.rox-logo .wm small { font-family: var(--font-mono); font-weight: 400; font-size: .56rem; letter-spacing: 2.4px; color: var(--cyan); margin-top: 6px; }

/* Roxphere lockup animation: mark spins in + breathes, tagline letter-spacing reveal */
.rox-logo img { animation: rxMarkIn .9s cubic-bezier(.22,.61,.36,1) .1s both, rxMarkGlow 4s ease-in-out 1.1s infinite; transform-origin: center; }
.rox-logo .wm { animation: rxWordIn .8s cubic-bezier(.22,.61,.36,1) .25s both; }
.rox-logo .wm small { animation: rxTagIn 1s ease .5s both; }
@keyframes rxMarkIn { from { opacity: 0; transform: rotate(-120deg) scale(.4); } to { opacity: 1; transform: none; } }
@keyframes rxMarkGlow { 0%, 100% { filter: drop-shadow(0 0 1px rgba(79,184,221,.25)); } 50% { filter: drop-shadow(0 0 11px rgba(116,214,247,.75)); } }
@keyframes rxWordIn { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
@keyframes rxTagIn { from { opacity: 0; letter-spacing: 9px; } to { opacity: 1; letter-spacing: 2.4px; } }
.rox-logo .wm small b { color: var(--cyan-bright); font-weight: 500; }

/* Module "chips" row (hero) */
.module-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; }
.module-chips .chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: .8rem; color: var(--text-soft);
  padding: 8px 14px; border: 1px solid var(--border); border-radius: 30px;
  background: rgba(255,255,255,.02);
}
.module-chips .chip::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--cyan)); box-shadow: 0 0 10px var(--c, var(--cyan)); }

/* Platform module list rows */
.module-rows { display: grid; gap: 12px; }
.module-row {
  display: grid; grid-template-columns: auto 150px 1fr; align-items: center; gap: 20px;
  background: linear-gradient(160deg, var(--surface), var(--bg-2));
  border: 1px solid var(--border); border-left: 3px solid var(--c, var(--cyan));
  border-radius: var(--radius); padding: 20px 26px; transition: transform .2s, box-shadow .25s;
}
.module-row:hover { transform: translateX(4px); box-shadow: var(--shadow); }
.module-row .rdot { width: 11px; height: 11px; border-radius: 50%; background: var(--c, var(--cyan)); box-shadow: 0 0 12px var(--c, var(--cyan)); }
.module-row .rname { font-family: var(--font-display); font-weight: 700; color: #fff; font-size: 1.1rem; }
.module-row .rname small { display: block; font-family: var(--font-mono); font-weight: 400; font-size: .66rem; letter-spacing: 2px; color: var(--c, var(--cyan)); text-transform: uppercase; margin-top: 2px; }
.module-row .rdesc { color: var(--text-soft); font-size: .95rem; }

/* Module deep-dive cards (coloured top accent) */
.module-card { border-top: 3px solid var(--c, var(--cyan)); }
.module-card::before { background: linear-gradient(90deg, var(--c, var(--cyan)), transparent); }
.showcase .m-tag { font-family: var(--font-mono); font-size: .72rem; letter-spacing: 2px; text-transform: uppercase; color: var(--c, var(--cyan)); }
.module-card h3 { margin: 8px 0 6px; }
.showcase .m-sub { color: var(--text-soft); font-size: .95rem; margin-bottom: 16px; }
.showcase .m-feats { display: grid; gap: 9px; margin-top: 4px; }
.showcase .m-feats li { display: flex; gap: 10px; font-size: .92rem; color: var(--text-soft); }
.showcase .m-feats li::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--c, var(--cyan)); margin-top: 8px; }
.showcase .m-stats { display: flex; gap: 22px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border-soft); }
.showcase .m-stats .ms { }
.showcase .m-stats .ms b { display: block; font-family: var(--font-display); font-size: 1.45rem; font-weight: 800; color: var(--c, var(--cyan)); }
.showcase .m-stats .ms span { font-family: var(--font-mono); font-size: .62rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--muted); }

/* Big stat row (why / proof) */
.bigstats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.bigstat { border-top: 1px solid var(--border); padding-top: 22px; }
.bigstat .bs-num { font-family: var(--font-display); font-size: clamp(2.2rem, 4.5vw, 3.2rem); font-weight: 800; color: var(--cyan); line-height: 1; }
.bigstat .bs-lbl { color: var(--text-soft); margin-top: 8px; }

/* Pricing / licensing cards */
.price-card { display: flex; flex-direction: column; }
.price-card.featured { border-color: rgba(79,184,221,.5); box-shadow: var(--glow); }
.price-card .p-badge {
  align-self: flex-start; font-family: var(--font-mono); font-size: .68rem; letter-spacing: 2px; text-transform: uppercase;
  color: #06141f; background: var(--cyan); padding: 5px 12px; border-radius: 20px; margin-bottom: 14px;
}
.price-card h3 { font-size: 1.5rem; }
.price-card .p-meta { font-family: var(--font-mono); font-size: .72rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--muted); margin: 6px 0 18px; }
.price-card .p-list { display: grid; gap: 11px; margin-bottom: 22px; }
.price-card .p-list li { display: flex; gap: 10px; font-size: .94rem; color: var(--text-soft); }
.price-card .p-list li::before { content: "+"; color: var(--cyan); font-weight: 700; }
.price-card .btn { margin-top: auto; }

/* Cross-sell band (hardware link from Roxphere/home) */
.crosssell { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 30px; }
@media (max-width: 760px) { .crosssell { grid-template-columns: 1fr; } }

@media (max-width: 760px) {
  .module-row { grid-template-columns: auto 1fr; }
  .module-row .rdesc { grid-column: 1 / -1; }
  .bigstats { grid-template-columns: 1fr; gap: 18px; }
}

/* ==========================================================================
   FINESSE — professional animations & micro-interactions
   ========================================================================== */

/* Sticky-nav offset for in-page anchors (e.g. #modules) */
html { scroll-padding-top: 90px; }

/* --- Focus-visible accessibility ring --- */
a:focus-visible, .btn:focus-visible, button:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 6px;
}

/* --- Scroll progress bar --- */
.scroll-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--cyan), var(--cyan-bright));
  box-shadow: 0 0 12px rgba(79,184,221,.7);
  z-index: 200; will-change: transform;
}

/* --- Nav elevation on scroll --- */
.nav { transition: height .3s ease, background .3s ease, box-shadow .35s ease; }
.nav.scrolled {
  height: 60px;
  background: rgba(10, 21, 33, 0.94);
  box-shadow: 0 12px 34px rgba(0,0,0,.45);
}

/* --- Refined scroll-reveal (easing + soft blur) --- */
.reveal {
  opacity: 0; transform: translateY(28px); filter: blur(6px);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1),
              filter .7s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
.reveal.in { opacity: 1; transform: none; filter: none; }

/* --- Hero entrance (staggered on load) --- */
@keyframes loadUp { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes loadFade { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
.hero .hero-inner > div:first-child > * { animation: loadUp .75s cubic-bezier(.22,.61,.36,1) both; }
.hero .hero-inner > div:first-child > *:nth-child(1) { animation-delay: .05s; }
.hero .hero-inner > div:first-child > *:nth-child(2) { animation-delay: .13s; }
.hero .hero-inner > div:first-child > *:nth-child(3) { animation-delay: .21s; }
.hero .hero-inner > div:first-child > *:nth-child(4) { animation-delay: .29s; }
.hero .hero-inner > div:first-child > *:nth-child(5) { animation-delay: .37s; }
.hero .hero-visual { animation: loadFade 1s ease .25s both; }
.page-hero .container > * { animation: loadUp .75s cubic-bezier(.22,.61,.36,1) both; }
.page-hero .container > *:nth-child(2) { animation-delay: .1s; }
.page-hero .container > *:nth-child(3) { animation-delay: .2s; }
.page-hero .container > *:nth-child(4) { animation-delay: .3s; }

/* --- Animated gradient on hero accent word --- */
.h-xl .accent {
  background: linear-gradient(100deg, var(--cyan) 10%, var(--cyan-bright) 50%, var(--cyan) 90%);
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: shimmer 7s linear infinite;
}
@keyframes shimmer { to { background-position: 200% center; } }

/* --- Primary button: light sweep on hover + press feedback --- */
.btn--primary { position: relative; overflow: hidden; }
.btn--primary::after {
  content: ""; position: absolute; top: 0; left: -120%; width: 55%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.4), transparent);
  transform: skewX(-20deg); pointer-events: none;
}
.btn--primary:hover::after { animation: sheen .85s ease; }
@keyframes sheen { to { left: 150%; } }
.btn:active { transform: translateY(0) scale(.98); }

/* --- Card pointer spotlight --- */
.card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), rgba(79,184,221,.12), transparent 45%);
  opacity: 0; transition: opacity .35s ease; pointer-events: none; z-index: 0;
}
.card:hover::after { opacity: 1; }
.card > * { position: relative; z-index: 1; }

/* --- Hero tech-ring: gentle float + core pulse --- */
.tech-ring { animation: floatY 6s ease-in-out infinite; }
@keyframes floatY { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
.tech-ring .core { animation: corePulse 4.5s ease-in-out infinite; }
@keyframes corePulse {
  0%, 100% { box-shadow: inset 0 0 40px rgba(79,184,221,.12); }
  50% { box-shadow: inset 0 0 64px rgba(79,184,221,.24), 0 0 34px rgba(79,184,221,.16); }
}

/* --- Module chip dots: soft pulse --- */
.module-chips .chip { transition: border-color .25s, transform .25s; }
.module-chips .chip:hover { border-color: var(--c, var(--cyan)); transform: translateY(-2px); }
.module-chips .chip::before { animation: dotPulse 2.6s ease-in-out infinite; }
@keyframes dotPulse {
  0%, 100% { box-shadow: 0 0 9px var(--c, var(--cyan)); opacity: .85; }
  50% { box-shadow: 0 0 16px var(--c, var(--cyan)); opacity: 1; }
}

/* --- Module rows: animated trailing arrow --- */
.module-row { position: relative; }
.module-row::after {
  content: "→"; position: absolute; right: 22px; top: 50%; transform: translateY(-50%) translateX(-6px);
  color: var(--c, var(--cyan)); opacity: 0; transition: opacity .25s, transform .25s; font-size: 1.1rem;
}
.module-row:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }

/* --- Nav link hover underline grow --- */
.nav-links a:not(.btn)::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: 2px; height: 2px;
  background: var(--cyan); border-radius: 2px; transform: scaleX(0); transform-origin: left;
  transition: transform .28s cubic-bezier(.22,.61,.36,1);
}
.nav-links a:not(.btn):hover::after { transform: scaleX(1); }
.nav-links a.active::after { transform: scaleX(1); }

/* --- Reduced motion: keep content visible, drop motion --- */

/* --- Roxphere module dashboard screenshots --- */
.module-shot {
  margin: -4px -4px 20px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg);
  box-shadow: 0 14px 36px rgba(0,0,0,.38);
  position: relative; z-index: 1;
  transition: transform .35s cubic-bezier(.22,.61,.36,1), box-shadow .35s;
}
.module-shot img { width: 100%; display: block; }
.module-card:hover .module-shot { transform: translateY(-3px); box-shadow: 0 20px 48px rgba(0,0,0,.5); }

/* --- Roxphere module showcase rows (large, legible screenshots) --- */
.showcase { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.showcase > * { min-width: 0; }            /* prevent the image from blowing out its grid track */
.showcase + .showcase { margin-top: 30px; }
.showcase .sc-media {
  border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  box-shadow: var(--shadow); background: var(--bg);
  border-top: 3px solid var(--c, var(--cyan));
  transition: transform .35s cubic-bezier(.22,.61,.36,1), box-shadow .35s;
}
.showcase .sc-media img { width: 100%; height: auto; display: block; }
.showcase:hover .sc-media { transform: translateY(-4px); box-shadow: 0 24px 56px rgba(0,0,0,.55); }
.showcase.rev .sc-media { order: 2; }
.showcase .m-tag { font-family: var(--font-mono); font-size: .72rem; letter-spacing: 2px; text-transform: uppercase; color: var(--c, var(--cyan)); }
.showcase h3 { margin: 8px 0 8px; font-size: 1.6rem; }
.showcase .m-sub { color: var(--text-soft); margin-bottom: 16px; }
@media (max-width: 880px) {
  .showcase { grid-template-columns: 1fr; gap: 22px; }
  .showcase.rev .sc-media { order: 0; }
}

/* CTA brand sign-off line */
.cta-sign {
  margin-top: 24px;
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: 3px;
  color: var(--muted);
}
.cta-sign b { color: var(--cyan-bright); font-weight: 500; }

/* Footer Roxphere column hashtag */
.footer h4 .rbx-tag { color: var(--cyan); }

/* --- Hero "RBX → acronym" morph (Roxphere hero visual) --- */
.hero-visual { flex-direction: column; gap: 26px; }
.rbx-acronym {
  position: relative; width: 100%; min-height: 30px;
  display: grid; place-items: center; text-align: center;
}
.rbx-acronym > span {
  grid-area: 1 / 1;            /* stack both states in the same cell */
  font-family: var(--font-mono);
  white-space: nowrap;
}
.rbx-acronym .rbx-short {
  font-size: 1.7rem; font-weight: 500; letter-spacing: 10px;
  color: var(--cyan-bright); text-indent: 10px;
  animation: rbxShort 7s ease-in-out infinite;
}
.rbx-acronym .rbx-long {
  font-size: .82rem; letter-spacing: 2.5px; color: var(--muted);
  animation: rbxLong 7s ease-in-out infinite;
}
.rbx-acronym .rbx-long b { color: var(--cyan-bright); font-weight: 600; }
.rbx-acronym .rbx-short i { color: var(--cyan); opacity: .65; font-style: normal; }
@keyframes rbxShort {
  0%, 38%   { opacity: 1; letter-spacing: 10px; }
  48%, 90%  { opacity: 0; letter-spacing: 26px; }
  100%      { opacity: 1; letter-spacing: 10px; }
}
@keyframes rbxLong {
  0%, 40%   { opacity: 0; transform: scale(.92); }
  52%, 88%  { opacity: 1; transform: scale(1); }
  100%      { opacity: 0; transform: scale(.92); }
}

/* --- Nav dropdown (Products → Roxphere) --- */
.has-dropdown { position: relative; }
.dd-trigger { display: inline-flex; align-items: center; gap: 5px; }
.dd-caret { width: 13px; height: 13px; opacity: .7; transition: transform .25s ease; }
.has-dropdown:hover .dd-caret,
.has-dropdown:focus-within .dd-caret { transform: rotate(180deg); }

.dropdown {
  position: absolute; top: 100%; left: 0; padding-top: 10px;   /* padding = hover bridge */
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s;
  z-index: 120;
}
.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown { opacity: 1; visibility: visible; transform: none; }

.dropdown-inner {
  min-width: 240px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px;
  box-shadow: var(--shadow);
}
.dropdown-inner li a {
  display: flex; flex-direction: column; gap: 2px;
  padding: 11px 13px; border-radius: 8px; border-left: 2px solid transparent;
}
.dropdown-inner li a::after { display: none; }   /* cancel nav underline */
.dropdown-inner li a:hover { background: rgba(79,184,221,.10); border-left-color: var(--cyan); }
.dropdown-inner .dd-title { font-family: var(--font-display); font-weight: 600; color: var(--text); }
.dropdown-inner .dd-sub { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .5px; color: var(--muted); }

/* Mobile: show submenu inline, indented */
@media (max-width: 720px) {
  .dropdown { position: static; opacity: 1; visibility: visible; transform: none; padding: 0 0 12px; }
  .dropdown-inner { background: transparent; border: 0; box-shadow: none; padding: 0; min-width: 0; }
  .dropdown-inner li a {
    display: flex; flex-direction: column; gap: 3px;
    padding: 10px 4px 10px 16px; margin-left: 4px;
    border-left: 2px solid var(--border); border-radius: 0;
  }
  .dropdown-inner li a:hover { background: transparent; border-left-color: var(--cyan); }
  .dropdown-inner .dd-title { font-family: var(--font-display); font-weight: 600; color: var(--text); font-size: .98rem; }
  .dropdown-inner .dd-sub { display: block; font-family: var(--font-mono); font-size: .68rem; letter-spacing: .5px; color: var(--muted); }
  .dd-caret { display: none; }
}

/* --- RoxTrade "coming soon" styling --- */
.module-chips .chip.soon { opacity: .85; }
.module-chips .chip.soon em {
  font-style: normal; font-family: var(--font-mono); font-size: .58rem; letter-spacing: 1px;
  text-transform: uppercase; color: #06141f; background: var(--c, var(--cyan));
  padding: 1px 6px; border-radius: 10px; margin-left: 7px;
}
.module-row.soon { opacity: .72; }
.soon-tag {
  font-family: var(--font-mono); font-size: .62rem; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--c, var(--cyan)); border: 1px solid var(--c, var(--cyan)); border-radius: 20px;
  padding: 2px 8px; margin-left: 8px; white-space: nowrap;
}
.soon-badge {
  display: inline-block; vertical-align: middle; font-family: var(--font-mono);
  font-size: .6rem; letter-spacing: 1.5px; text-transform: uppercase;
  color: #06141f; background: var(--c, var(--cyan)); padding: 3px 9px; border-radius: 10px; margin-left: 10px;
}
.sc-media.sc-soon {
  border-style: dashed; box-shadow: none;
  background: linear-gradient(160deg, var(--surface), var(--bg-2));
  display: grid; place-items: center; min-height: 320px;
}
.sc-soon .soon-inner { text-align: center; }
.sc-soon .soon-inner svg { width: 46px; height: 46px; color: var(--c, var(--cyan)); opacity: .85; margin-bottom: 14px; }
.sc-soon .soon-label { font-family: var(--font-mono); letter-spacing: 4px; text-transform: uppercase; font-size: .82rem; color: var(--c, var(--cyan)); }
.sc-soon:hover { transform: none; }

/* --- Module showcase body: aligned feature list + stat row finesse --- */
.showcase .sc-body .m-feats { display: grid; gap: 11px; margin-top: 6px; }
.showcase .sc-body .m-feats li { display: flex; gap: 12px; align-items: flex-start; font-size: .96rem; line-height: 1.5; color: var(--text-soft); }
.showcase .sc-body .m-feats li::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 2px; background: var(--c, var(--cyan)); margin-top: 8px; box-shadow: 0 0 8px var(--c, var(--cyan)); }
.showcase .sc-body .m-stats {
  display: flex; gap: 36px; margin-top: 24px; padding-top: 20px;
  border-top: 1px solid var(--border-soft);
}
.showcase .sc-body .m-stats .ms { display: flex; flex-direction: column; gap: 6px; }
.showcase .sc-body .m-stats .ms b {
  font-family: var(--font-display); font-size: 1.7rem; font-weight: 800;
  line-height: 1; color: var(--c, var(--cyan));
}
.showcase .sc-body .m-stats .ms span {
  font-family: var(--font-mono); font-size: .64rem; letter-spacing: 1.5px;
  text-transform: uppercase; color: var(--muted);
}
@media (max-width: 520px) {
  .showcase .sc-body .m-stats { gap: 22px; }
  .showcase .sc-body .m-stats .ms b { font-size: 1.4rem; }
}

/* --- WhatsApp floating button --- */
.wa-float {
  position: fixed; right: 22px; bottom: 22px; width: 56px; height: 56px;
  border-radius: 50%; background: #25D366; color: #fff;
  display: grid; place-items: center; z-index: 300;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
  transition: transform .2s ease, box-shadow .2s ease;
  animation: waPulse 2.8s ease-in-out infinite;
}
.wa-float svg { width: 30px; height: 30px; }
.wa-float:hover { transform: scale(1.08); box-shadow: 0 12px 30px rgba(37,211,102,.5); }
@keyframes waPulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(0,0,0,.4), 0 0 0 0 rgba(37,211,102,.45); }
  50%      { box-shadow: 0 8px 24px rgba(0,0,0,.4), 0 0 0 13px rgba(37,211,102,0); }
}
@media (max-width: 520px) { .wa-float { width: 52px; height: 52px; right: 16px; bottom: 16px; } }

/* --- Legal / privacy page --- */
.legal { color: var(--text-soft); }
.legal .legal-updated { font-family: var(--font-mono); font-size: .8rem; color: var(--muted); margin-bottom: 26px; }
.legal h2 { margin: 30px 0 12px; color: var(--text); }
.legal p { margin-bottom: 14px; line-height: 1.75; }
.legal ul { margin: 0 0 16px; padding-left: 0; display: grid; gap: 10px; }
.legal ul li { display: flex; gap: 11px; line-height: 1.65; }
.legal ul li::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); margin-top: 9px; }
.legal a { color: var(--cyan); }
.legal a:hover { color: var(--cyan-bright); }
.legal .legal-note { margin-top: 30px; padding: 16px 18px; border: 1px solid var(--border); border-left: 3px solid var(--cyan); border-radius: 10px; font-size: .9rem; color: var(--muted); background: rgba(255,255,255,.02); }

/* --- Phone field with country-code dropdown --- */
.phone-group { display: flex; gap: 8px; }
.phone-group input { flex: 1; min-width: 0; }

/* --- Brand strip: logo-as-R "RUN BETTER · EXECUTE SMARTER" lockup --- */
.brandstrip {
  position: relative; z-index: 1; text-align: center; padding: 76px 0;
  border-top: 1px solid var(--border-soft); border-bottom: 1px solid var(--border-soft);
  background: radial-gradient(ellipse 55% 130% at 50% 50%, rgba(79,184,221,.07), transparent 70%), var(--bg);
}
.rbx-lockup { display: inline-flex; flex-direction: column; align-items: center; gap: 10px; max-width: 100%; }
.rbx-lockup .l1, .rbx-lockup .l2 {
  display: flex; align-items: center;
  font-family: var(--font-display); font-weight: 800;
  /* em-based tracking scales with the font; fixed px overflowed narrow screens */
  letter-spacing: .135em; line-height: 1;
  font-size: clamp(1rem, 4.6vw, 2.8rem);
  margin-right: -.135em;  /* trim the trailing letter-space so the line stays optically centred */
}
.rbx-lockup .l1 { color: #fff; }
.rbx-lockup .l2 { color: var(--cyan); }
.rbx-lockup .l1 img { height: 1.18em; width: auto; margin-right: 4px; transform: translateY(1px); }
.rbx-lockup .dot { color: var(--cyan); padding: 0 2px; }

/* emphasised X in the brand-strip "eXecute" */
.rbx-lockup .l2 .x { color: var(--cyan-bright); }


/* --- Custom country-code dropdown --- */
.cc { position: relative; flex: none; }
.cc-btn {
  display: flex; align-items: center; gap: 7px; width: 100px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 12px 12px; color: var(--text); font-family: var(--font-body);
  font-size: .95rem; cursor: pointer; transition: border-color .2s, box-shadow .2s;
}
.cc-btn .cc-flag { font-size: 1.05rem; line-height: 1; }
.cc-btn .cc-code { font-weight: 600; }
.cc-btn svg { width: 13px; height: 13px; margin-left: auto; opacity: .65; transition: transform .25s; }
.cc.open .cc-btn { border-color: var(--cyan); box-shadow: 0 0 0 3px rgba(79,184,221,.15); }
.cc.open .cc-btn svg { transform: rotate(180deg); }
.cc-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.cc-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 80;
  width: 320px; max-width: 80vw;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow); padding: 8px;
  display: none;
}
.cc.open .cc-panel { display: block; }
.cc-search {
  width: 100%; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; color: var(--text);
  font-family: var(--font-body); font-size: .9rem; margin-bottom: 8px;
}
.cc-search:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 0 3px rgba(79,184,221,.15); }
.cc-search::placeholder { color: var(--muted); }
.cc-list { max-height: 264px; overflow-y: auto; display: grid; gap: 1px; margin: 0; }
.cc-head {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: 1.5px;
  text-transform: uppercase; color: var(--muted);
  padding: 10px 10px 5px; pointer-events: none;
}
.cc-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 7px; cursor: pointer; font-size: .92rem; color: var(--text-soft);
}
.cc-item span { margin-left: auto; font-family: var(--font-mono); font-size: .8rem; color: var(--muted); }
.cc-item:hover, .cc-item.active { background: rgba(79,184,221,.12); color: #fff; }
.cc-item.hide, .cc-head.hide { display: none; }
.cc-list::-webkit-scrollbar { width: 9px; }
.cc-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 9px; }
.cc-list::-webkit-scrollbar-track { background: transparent; }

/* --- AI & API Integration "coming soon" highlight card --- */
.ai-soon { border-color: rgba(116,214,221,.38); background: linear-gradient(160deg, rgba(116,214,221,.06), var(--bg-2)); }
.ai-soon-inner { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.ai-soon .ai-soon-body { flex: 1; min-width: 260px; }
.ai-soon h3 { margin: 2px 0 8px; }
.ai-soon p { color: var(--text-soft); font-size: .98rem; max-width: 70ch; }

/* --- Overview video frame --- */
.video-frame {
  max-width: 940px; margin: 0 auto;
  border: 1px solid var(--border); border-top: 3px solid var(--cyan);
  border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); background: #000;
}
.video-frame video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: #000; }

/* Module page screenshot uses the video frame */
.video-frame img { display: block; width: 100%; height: auto; }
/* Long product dropdown stays usable */
.dropdown-inner { max-height: 72vh; overflow-y: auto; }

/* --- FAQ accordion --- */
.faq { display: grid; gap: 12px; }
.faq details {
  border: 1px solid var(--border); border-radius: 12px;
  background: linear-gradient(160deg, var(--surface), var(--bg-2));
  padding: 0 20px; transition: border-color .25s;
}
.faq details[open] { border-color: rgba(79,184,221,.4); }
.faq summary {
  cursor: pointer; list-style: none; padding: 18px 0;
  font-family: var(--font-display); font-weight: 600; font-size: 1.04rem; color: var(--text);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; flex: none; color: var(--cyan); font-size: 1.4rem; font-weight: 400;
  line-height: 1; transition: transform .25s;
}
.faq details[open] summary::after { content: "−"; }
.faq details p { padding: 0 0 20px; color: var(--text-soft); line-height: 1.75; max-width: 78ch; }

/* Linked industry cards */
a.card { display: flex; flex-direction: column; color: inherit; text-decoration: none; }
.ind-more { display: inline-block; margin-top: 14px; font-family: var(--font-mono); font-size: .72rem; letter-spacing: 1.5px; text-transform: uppercase; color: var(--cyan); }
a.card .ind-more { margin-top: auto; padding-top: 16px; }  /* pin to card bottom regardless of copy length */
a.card:hover .ind-more { color: var(--cyan-bright); }

/* <picture> wrappers behave like the img they replace */
.sc-media picture, .video-frame picture, .module-shot picture { display: block; }

/* ==========================================================================
   DEPTH LAYER — real CSS 3D (perspective / preserve-3d). No JS library.

   Two rules for anything added below:
   1. Static depth (framing, tilt, shadow) is unconditional — it is a look,
      not motion, so it is safe for everyone.
   2. Anything that MOVES lives inside `prefers-reduced-motion: no-preference`.
      The pre-existing 2D animation layer above stays always-on by client
      request (2026-06-23); this gate applies only to the new 3D motion.

   Perspective values are deliberately large and tilt angles small: a rotated
   element's near edge scales UP under perspective, which is how a 3D layer
   silently reintroduces horizontal overflow on mobile.
   ========================================================================== */

/* ---- 1. Hero gyroscope — index + roxphere -------------------------------- */
/* The three flat concentric circles become rings orbiting on separate axes.
   Each ring carries a bright top-border arc so its Z-spin is actually visible;
   a plain solid circle rotated about its own axis looks completely static. */
/* The ring tilts live inside the motion gate alongside their animations: the
   pre-existing spin/spinrev rules above still apply when motion is reduced and
   would override a static tilt anyway, so a reduced-motion visitor gets
   precisely the hero that shipped before this layer — not a half-3D hybrid. */
@media (prefers-reduced-motion: no-preference) {
  .tech-ring { perspective: 1500px; perspective-origin: 50% 45%; }
  .tech-ring .ring { transform-origin: 50% 50%; }
  .tech-ring .ring.r1 { border-top-color: rgba(79,184,221,.75); animation: orbitA 20s linear infinite; }
  .tech-ring .ring.r2 { animation: orbitB 15s linear infinite; }
  .tech-ring .ring.r3 { border-top-color: rgba(116,214,247,.6); animation: orbitC 32s linear infinite; }
  /* Replaces the flat floatY bob with a bob + slow yaw, so the rings are seen
     from a shifting angle and the assembly reads as a solid object. */
  .tech-ring { animation: floatY3d 11s ease-in-out infinite; }
}
@keyframes orbitA {
  from { transform: rotateX(62deg) rotateZ(0deg); }
  to   { transform: rotateX(62deg) rotateZ(360deg); }
}
@keyframes orbitB {
  from { transform: rotateY(64deg) rotateZ(0deg); }
  to   { transform: rotateY(64deg) rotateZ(-360deg); }
}
@keyframes orbitC {
  from { transform: rotateX(24deg) rotateY(20deg) rotateZ(0deg); }
  to   { transform: rotateX(24deg) rotateY(20deg) rotateZ(360deg); }
}
@keyframes floatY3d {
  0%, 100% { transform: translateY(0) rotateY(-7deg); }
  50%      { transform: translateY(-12px) rotateY(7deg); }
}

/* ---- 2. Dashboard screenshots in perspective frames — roxphere + modules -- */
/* Angled away from the reader, straightening on hover. Reuses the existing
   WebP assets; costs no bytes. */
.showcase .sc-media {
  transform: perspective(2000px) rotateY(-6deg) rotateX(1.5deg);
  transition: transform .55s cubic-bezier(.22,.61,.36,1), box-shadow .55s ease;
  will-change: transform;
}
.showcase.rev .sc-media { transform: perspective(2000px) rotateY(6deg) rotateX(1.5deg); }
.showcase:hover .sc-media,
.showcase.rev:hover .sc-media {
  transform: perspective(2000px) rotateY(0deg) rotateX(0deg) translateY(-6px);
  box-shadow: 0 30px 70px rgba(0,0,0,.6);
}

/* ---- 3. Section entrance gains depth — every page ------------------------ */
/* Sections rise toward the reader instead of sliding up flat. translateZ is
   negative (receding), so the element is never larger than its resting size. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { transform: perspective(1400px) translate3d(0, 26px, -70px) rotateX(5deg); }
  .reveal.in { transform: none; }
}

/* ---- 4. Card pointer tilt — 9 pages ------------------------------------- */
/* --rx/--ry are set by the pointermove handler in js/main.js and default to
   0deg, so touch devices and no-JS render exactly as before. preserve-3d is
   deliberately NOT used: it would break the .card::after spotlight overlay. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card { transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease; }
  .card:hover {
    transform: perspective(1000px)
               rotateX(var(--rx, 0deg))
               rotateY(var(--ry, 0deg))
               translateY(-5px);
  }
}

/* ---- 5. Module chips lift off the surface — home + roxphere -------------- */
.module-chips { perspective: 800px; }
.module-chips .chip { transition: transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease; }
.module-chips .chip:hover {
  transform: translateZ(18px) rotateX(-8deg);
  box-shadow: 0 10px 24px rgba(0,0,0,.45), 0 0 0 1px var(--c, var(--cyan));
}

/* ---- 6. Blueprint grid gains a second depth plane — every page ----------- */
/* A coarser, dimmer grid sits "behind" the existing one and drifts slowly, so
   the background reads as two planes at different distances rather than one
   flat texture. Fixed + pointer-events:none, same as body::before. */
body::after {
  content: "";
  position: fixed;
  inset: -10%;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(79,184,221,.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(79,184,221,.025) 1px, transparent 1px);
  background-size: 144px 144px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 20%, transparent 75%);
}
@media (prefers-reduced-motion: no-preference) {
  body::after { animation: gridDrift 60s linear infinite; }
}
@keyframes gridDrift {
  from { background-position: 0 0; }
  to   { background-position: 144px 144px; }
}

/* ---- 7. Module orbit — roxphere #modules -------------------------------- */
/* Six module chips on a rotating cylinder around a central core: a literal
   reading of "Six modules. One backbone." Radius is a custom property so the
   mobile override is a single value change — the ring's horizontal extent is
   radius + half a chip, and that has to stay inside the viewport. */
/* Geometry, because the nesting is load-bearing. The ring lies in a plane
   tilted back 64deg (Saturn-style), so the near chip sits BELOW the core and
   the far chip ABOVE it — a vertical-axis cylinder instead parks the near chip
   dead-centre on top of the core, which is what the first attempt did.
   Orientation composes to identity so every label faces the reader square on:
     stage rotateX(64) . ring rotateZ(t) . item rotateZ(i*60)
       . face rotateZ(-t) . b rotateZ(-i*60) rotateX(-64)  ==  identity
   Every level needs preserve-3d or the composition collapses. */
.mod-orbit {
  /* Radius is set by CLEARANCE, not by width. At 64deg the ring's vertical
     radius is only 0.44 * r, so at r=210 the top and bottom chips sat on the
     66px core. There is plenty of unused width (600px of half-container at
     1440), so pushing the ring out fixes the overlap AND deepens the effect:
     a larger radius means more z-spread, so near chips scale up harder. */
  --mo-r: 268px;
  --mo-tilt: 64deg;
  --mo-gap: 78px;   /* core radius (66) + clearance */
  position: relative;
  /* Height must clear the NEAR chip, which perspective scales up, plus its
     box-shadow glow — and getBoundingClientRect excludes shadow, so measured
     overflow understates the visible clipping. The ring is vertically centred
     but reaches further down than up for that reason. Too short here and
     overflow:hidden below slices the bottom chip. */
  height: 420px;
  margin: 8px auto 46px;
  display: grid;
  place-items: center;
  perspective: 1100px;
  /* The chips are abspos boxes inside a preserve-3d chain: their untransformed
     layout origin still contributes to scrollable overflow even though nothing
     paints near the widget's edges, which produced real horizontal page scroll.
     Clipping here contains it. Safe for the 3D scene — this element carries
     `perspective`, not `preserve-3d`, so nothing gets flattened. */
  overflow: hidden;
}
.mo-stage {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  transform: rotateX(var(--mo-tilt));
  transform-style: preserve-3d;
}
/* Positioned explicitly rather than relying on the parent's place-items:center
   — an absolutely positioned child is not a grid item, so that centring does
   not apply to it and the ring anchored to the container's edge instead. With
   width/height 0 and transform-origin 0 0, left/top 50% puts the ring's centre
   exactly at the widget's centre. */
.mo-ring {
  position: absolute;
  left: 50%; top: 50%;
  width: 0; height: 0;
  transform-origin: 0 0;
  transform-style: preserve-3d;
}
/* .mo-item and .mo-face are ZERO-SIZED pivots with transform-origin at 0 0, so
   every rotation happens about the ring's centre. Sized boxes here rotate about
   their own centres instead, which offsets each chip by half its width and
   pushed the ring off-centre enough to cause real horizontal scroll. */
.mo-item, .mo-face {
  position: absolute;
  width: 0; height: 0;
  transform-origin: 0 0;
  transform-style: preserve-3d;
}
.mo-item {
  transform: rotateZ(calc(var(--i) * 60deg)) translateY(calc(var(--mo-r) * -1));
}
.mo-item b {
  position: absolute;
  display: block;
  transform-origin: 0 0;
  padding: 9px 18px 9px 30px;   /* left room for the status dot */
  border-radius: 999px;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: .76rem;
  letter-spacing: 1.4px;
  color: var(--text);
  /* A hairline top highlight over the surface gradient reads as a machined
     edge catching light. The border is the module colour at low alpha rather
     than full strength, and the shadow is a grounded drop rather than a glow —
     a saturated outline plus bloom reads as neon, not instrumentation. */
  background:
    linear-gradient(180deg, rgba(255,255,255,.07), transparent 42%),
    linear-gradient(180deg, var(--surface-2), var(--bg-2));
  border: 1px solid color-mix(in srgb, var(--c, var(--cyan)) 42%, transparent);
  box-shadow:
    0 6px 18px -8px rgba(0,0,0,.85),
    inset 0 0 0 1px rgba(255,255,255,.03);
  /* translate LAST: transform functions compose left-to-right, so a leading
     translate would be rotated by the counter-rotations that follow it and the
     chip would land off its anchor point. */
  transform: rotateZ(calc(var(--i) * -60deg))
             rotateX(calc(var(--mo-tilt) * -1))
             translate(-50%, -50%);
}
/* No z-index: the core must sit UNDER the chips. Raising it above them makes
   the top chip disappear behind the core whenever the ring is tight, and the
   stage is a flattened stacking context so per-chip depth sorting against the
   core is not available anyway. Clearance is solved by geometry below. */
/* Status dot in the module's own colour — the colour cue moves off the outline
   and onto a small deliberate mark, echoing the hero chips. */
.mo-item b::before {
  content: "";
  position: absolute;
  left: 14px; top: 50%;
  width: 6px; height: 6px;
  margin-top: -3px;
  border-radius: 50%;
  background: var(--c, var(--cyan));
  box-shadow: 0 0 7px -1px var(--c, var(--cyan));
}

/* The orbit path itself. It lies in the tilted plane, so a circle renders as
   the correct ellipse for free — the chips then read as sitting ON a path
   rather than floating near a disc. */
.mo-path {
  position: absolute;
  left: 50%; top: 50%;
  width: calc(var(--mo-r) * 2);
  height: calc(var(--mo-r) * 2);
  margin-left: calc(var(--mo-r) * -1);
  margin-top: calc(var(--mo-r) * -1);
  border-radius: 50%;
  border: 1px solid rgba(79,184,221,.14);
}

/* Hairlines from the core out to each chip: the visual claim that Roxan reads
   from every module. Kept to 1px and faded toward the rim so they read as
   drafting lines rather than decoration. */
/* Starts at the core's RIM, not its centre: --mo-gap is the core radius plus a
   little clearance, so the hairlines never draw across the disc. The rotation
   origin has to be pushed back down to the ring centre by the same amount,
   hence calc(100% + var(--mo-gap)). */
.mo-spoke {
  position: absolute;
  left: 0;
  top: calc(var(--mo-r) * -1);
  width: 1px;
  height: calc(var(--mo-r) - var(--mo-gap));
  transform-origin: 50% calc(100% + var(--mo-gap));
  transform: rotateZ(calc(var(--i) * 60deg));
  background: linear-gradient(to top, rgba(79,184,221,.40), rgba(79,184,221,.04));
}

.mo-core {
  position: relative;
  width: 132px; height: 132px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  text-align: center;
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: 2px;
  color: var(--cyan-bright);
  /* Lifted clear of the page background so the disc reads as a solid object
     rather than a hole — surface-2 to surface, not down into bg-2. */
  background: radial-gradient(circle at 38% 28%, var(--surface-3), var(--surface) 68%);
  border: 1px solid rgba(79,184,221,.34);
  box-shadow:
    inset 0 -14px 30px -18px #000,          /* underside shading -> reads spherical */
    inset 0 0 34px rgba(79,184,221,.12),
    0 0 34px -14px var(--cyan);
}
/* A single travelling arc outside the core. Same rotating-border trick as the
   hero rings, so it needs no mask support and degrades to a static hairline
   arc when motion is reduced. */
.mo-core::before {
  content: "";
  position: absolute;
  inset: -15px;              /* clear of the core edge — overlapping it made
                                the arc, the rim and the dial read as tangle */
  border-radius: 50%;
  border: 1px solid transparent;
  border-top-color: rgba(116,214,247,.5);
  border-right-color: rgba(116,214,247,.14);
}
@media (prefers-reduced-motion: no-preference) {
  .mo-core::before { animation: coreSweep 9s linear infinite; }
}
@keyframes coreSweep { to { transform: rotate(360deg); } }
/* The ring spins; each face counter-spins at the same rate so the labels stay
   upright and readable the whole way round. Under reduced motion both drop
   out and the chips simply rest in a static tilted ring. */
@media (prefers-reduced-motion: no-preference) {
  .mo-ring  { animation: moSpin 34s linear infinite; }
  .mo-face  { animation: moSpinRev 34s linear infinite; }

  /* Aerial perspective: chips fade as they travel behind the core. Perspective
     already scales them, but size alone reads as "some chips are bigger" —
     dimming is what makes it read as distance.

     The phase is derived, not eyeballed. Chip i sits at ring angle (t + i*60)
     and is nearest when that reaches 180deg, i.e. at t = 34s*(180 - i*60)/360
     = 17s - i*5.667s. The keyframe peaks at its own 50% mark (17s in), so the
     delay that lands the peak on the near point is simply -i * 5.667s. */
  .mo-item b {
    animation: moDepth 34s linear infinite;
    animation-delay: calc(var(--i) * -5.667s);
  }
}
@keyframes moDepth {
  0%, 100% { opacity: .50; }
  25%      { opacity: .68; }
  50%      { opacity: 1; }
  75%      { opacity: .60; }
}
@keyframes moSpin {
  from { transform: rotateZ(0deg); }
  to   { transform: rotateZ(360deg); }
}
@keyframes moSpinRev {
  from { transform: rotateZ(0deg); }
  to   { transform: rotateZ(-360deg); }
}

/* ---- 8. Architecture stack — roxphere ----------------------------------- */
/* Three translucent slabs receding into depth. The slab is tilted; the label
   inside is counter-rotated by the same angle so it faces the reader square
   on — tilted text at 58deg is unreadable. */
.stackviz {
  --sv-tilt: 58deg;
  position: relative;
  height: 380px;
  margin: 0 auto 40px;
  max-width: 560px;
  perspective: 1300px;
  transform-style: preserve-3d;
}
.stackviz .sv-plane {
  position: absolute;
  left: 0; right: 0;
  width: min(440px, 88%);
  height: 150px;
  margin-inline: auto;   /* auto margins on a left:0/right:0 abspos box centre it
                            without spending the transform on translateX(-50%) */
  border-radius: 16px;
  transform-style: preserve-3d;
  background: linear-gradient(160deg, rgba(79,184,221,.10), rgba(18,38,57,.72));
  border: 1px solid rgba(79,184,221,.28);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.7);
  display: grid;
  place-items: center;
}
/* A 150px slab tilted 58deg projects to only ~80px tall, so the gaps have to
   clear the LABEL, not the slab box — at 58px apart the subtitles disappeared
   behind the slab in front. */
.stackviz .sv-1 { top: 196px; transform: rotateX(var(--sv-tilt)); }
.stackviz .sv-2 { top: 104px; transform: rotateX(var(--sv-tilt)); border-color: rgba(79,184,221,.4); }
.stackviz .sv-3 { top:  12px; transform: rotateX(var(--sv-tilt)); border-color: rgba(116,214,247,.5); }
.stackviz .sv-face {
  /* translateZ first, so the lift runs along the slab's own normal and the
     label floats clear of the surface rather than sinking into it. */
  transform: translateZ(10px) rotateX(calc(var(--sv-tilt) * -1));
  display: grid;
  gap: 4px;
  text-align: center;
  padding: 0 14px;
}
.stackviz .sv-face b {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 700;
  color: var(--text);
}
.stackviz .sv-face i {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: .66rem;
  letter-spacing: 1.2px;
  color: var(--muted);
}
@media (prefers-reduced-motion: no-preference) {
  .stackviz .sv-plane { animation: svFloat 8s ease-in-out infinite; }
  .stackviz .sv-2 { animation-delay: -.5s; }
  .stackviz .sv-3 { animation-delay: -1s; }
}
/* Animates the independent `translate` property, not `transform` — so the tilt
   stays defined in exactly one place (--sv-tilt) instead of being duplicated
   into the keyframe, where changing the variable would silently desync it. */
@keyframes svFloat {
  0%, 100% { translate: 0 0 0; }
  50%      { translate: 0 0 16px; }
}

/* ---- 9. Roxan — the AI co-worker band ----------------------------------- */
/* The walkthrough video is 1500x950 (30:19), not 16:9. Without this override
   the shared .video-frame rule letterboxes it inside a 16:9 box. */
.video-frame--roxan video { aspect-ratio: 30 / 19; }
.video-frame--roxan { margin-top: 30px; }

.roxan-band .kicker { display: inline-flex; align-items: center; gap: 10px; }
.roxan-band .mod-orbit { margin-bottom: 34px; }

.roxan-note {
  margin: 24px auto 0;
  max-width: 68ch;
  text-align: center;
  font-size: .95rem;
  color: var(--muted);
}

/* Roxan sits where "ONE DATABASE" sits on the modules ring — same widget, so
   the two read as the same idea seen from different sides. */
/* Roxan reads as the same instrument, marked out rather than lit up: the
   spherical shading is kept and the bloom pulled back. */
.mo-core--roxan {
  border-color: rgba(116,214,247,.42);
  box-shadow:
    inset 0 -14px 30px -18px #000,
    inset 0 0 36px rgba(116,214,247,.14),
    0 0 44px -14px var(--cyan-bright);
  font-size: .66rem;
  letter-spacing: 3px;
  color: var(--cyan-bright);
}
.mo-core--roxan::before { border-top-color: rgba(116,214,247,.68); }
.mo-core--roxan span { display: grid; place-items: center; gap: 6px; }
.mo-core--roxan svg { width: 30px; height: 30px; filter: drop-shadow(0 0 10px rgba(116,214,247,.45)); }

/* The end-to-end arc from the walkthrough: diagnosed -> stocked -> fixed -> checked */
.roxan-flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: 30px;
}
.roxan-flow .rf-step {
  position: relative;
  padding: 20px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: linear-gradient(160deg, rgba(79,184,221,.06), var(--bg-2));
}
.roxan-flow .rf-n {
  display: block;
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: 2px;
  color: var(--cyan);
  margin-bottom: 8px;
}
.roxan-flow b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.08rem;
  color: var(--text);
  margin-bottom: 6px;
}
.roxan-flow i {
  font-style: normal;
  font-size: .87rem;
  line-height: 1.5;
  color: var(--text-soft);
}
@media (max-width: 880px) {
  .roxan-flow { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .roxan-flow { grid-template-columns: 1fr; }
}

/* ---- 10. Entrance-driven depth ------------------------------------------ */
/* The dashboards turn toward the reader as their row enters the viewport,
   settling from a steep angle to the resting tilt, so the page reads as
   dimensional rather than as flat art that happens to be skewed.

   This was first built on animation-timeline: view(), which is the more
   elegant tool — but a scroll timeline cannot be verified in headless Chrome
   (the ViewTimeline's currentTime stays frozen while the element demonstrably
   moves through the viewport), and its failure mode is bad: with fill:both and
   a timeline stuck before its range, the dashboards pin at the steep -14deg
   start angle permanently. So this keys off .in from the existing
   IntersectionObserver instead — one class, no new observer, no scroll
   listener, and it degrades to the resting tilt when JS is unavailable. */
@media (prefers-reduced-motion: no-preference) and (min-width: 881px) {
  .showcase:not(.in) .sc-media {
    transform: perspective(2000px) rotateY(-15deg) rotateX(4deg) translateY(16px);
  }
  .showcase.rev:not(.in) .sc-media {
    transform: perspective(2000px) rotateY(15deg) rotateX(4deg) translateY(16px);
  }
  /* Slower than the row's own reveal, and slightly behind it, so the panel
     settles after the text rather than with it. */
  .showcase .sc-media {
    transition: transform .9s cubic-bezier(.2,.7,.3,1) .12s, box-shadow .55s ease;
  }
}

/* ---- 11. Card contents lift off the surface ----------------------------- */
/* Each child carries its OWN perspective() rather than relying on the card
   having transform-style: preserve-3d — .card sets overflow:hidden, and a
   non-visible overflow forces a preserve-3d context to flatten, so the parent
   route silently does nothing. A self-contained perspective needs no parent
   context and gives true perspective scaling as the element comes forward.
   Different depths per element create the parallax that sells the lift. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card .icon-badge,
  .card h3 {
    transition: transform .3s cubic-bezier(.22,.61,.36,1);
  }
  .card:hover .icon-badge { transform: perspective(600px) translateZ(26px); }
  .card:hover h3          { transform: perspective(600px) translateZ(12px); }
}

/* ---- Mobile: flatten the tilts ------------------------------------------ */
/* Narrow viewports have no room to absorb perspective scale-up, and the
   angled dashboards read as skewed rather than deliberate at one column. */
@media (max-width: 880px) {
  .showcase .sc-media,
  .showcase.rev .sc-media,
  .showcase:hover .sc-media,
  .showcase.rev:hover .sc-media { transform: none; }
  /* Phone geometry has two constraints, not one:
       WIDTH    --mo-r + half a chip must stay inside the container (171px at
                a 390px viewport). "RoxPeople" is the widest at ~83px here.
       CLEARANCE the ring's VERTICAL radius is --mo-r * cos(tilt), and the top
                and bottom chips must clear the core or they overlap it. At
                64deg that radius collapses to 0.44 * r, which put those chips
                straight on top of the core. 44deg keeps 0.72 * r.
     The status dot pushed the widest chip to 110px, so the old 120 radius
     put its left edge 4px outside the clipping box. 110 + 55 = 165 fits,
     and 110 * cos(44) = 79 vertical against a 46px core radius still
     clears comfortably. */
  .mod-orbit { --mo-r: 110px; --mo-tilt: 44deg; --mo-gap: 50px; height: 250px; }
  /* Phones have no spare width to push the ring out (110 + 55 already fills
     the 164px half-container), so clearance has to come from a smaller core.
     Flattening the tilt would also work but costs the depth the ring exists
     for. 80px core = 40px radius against a 65px chip inner edge. */
  /* Targets .mo-item b — the chip itself. The old rule here styled .mo-item,
     which stopped being the chip when the orbit was rebuilt with zero-sized
     pivots, so phones silently rendered full desktop-sized chips. */
  /* Left padding must keep clearing the status dot. A bare `padding: 6px 12px`
     here reset the 30px left inset and the dot landed on the first letter. */
  .mo-item b { font-size: .68rem; padding: 6px 14px 6px 25px; }
  .mo-item b::before { left: 11px; width: 5px; height: 5px; margin-top: -2.5px; }
  .mo-core { width: 80px; height: 80px; font-size: .5rem; letter-spacing: 1.6px; }
  .mo-core--roxan svg { width: 18px; height: 18px; }
  .stackviz { height: 280px; }
  .stackviz .sv-plane { height: 128px; }
  .stackviz .sv-face b { font-size: 1.02rem; }
  .stackviz .sv-face i { font-size: .6rem; }
}
/* Distinct animation names rather than redefining the desktop @keyframes inside
   a media query — a duplicate @keyframes name resolves by source order, not by
   which media query matches, which is a trap. Shallower angles + a longer
   perspective keep the near edge of each ring inside a 390px viewport. */
/* .ring is a SQUARE box drawn circular with border-radius, so rotating it about
   Z grows its bounding box by (|cos t| + |sin t|) — up to 1.414x at 45deg, on
   top of the perspective scale-up. Nothing paints out there (a circle is
   rotationally symmetric) and body already has overflow-x:hidden, but at 80vw
   the box escaped a 390px viewport. 64vw keeps the worst case inside:
   250 * 1.414 * 1.05 = 371 < 390. The same latent growth exists in the original
   spinrev hero; it just took most of its 60s cycle to get there. */
@media (max-width: 880px) {
  .tech-ring { width: min(380px, 64vw); }
}
@media (max-width: 880px) and (prefers-reduced-motion: no-preference) {
  .tech-ring { perspective: 2600px; animation: floatY3dSm 11s ease-in-out infinite; }
  .tech-ring .ring.r1 { animation: orbitASm 20s linear infinite; }
  .tech-ring .ring.r2 { animation: orbitBSm 15s linear infinite; }
}
@keyframes orbitASm {
  from { transform: rotateX(50deg) rotateZ(0deg); }
  to   { transform: rotateX(50deg) rotateZ(360deg); }
}
@keyframes orbitBSm {
  from { transform: rotateY(54deg) rotateZ(0deg); }
  to   { transform: rotateY(54deg) rotateZ(-360deg); }
}
@keyframes floatY3dSm {
  0%, 100% { transform: translateY(0) rotateY(-4deg); }
  50%      { transform: translateY(-8px) rotateY(4deg); }
}
