:root {
  --echo-ink: #f4f4f1;
  --echo-muted: #a3a3a0;
  --echo-line: rgba(244, 244, 241, 0.12);
  --echo-line-strong: rgba(244, 244, 241, 0.24);
  --echo-panel: rgba(13, 13, 13, 0.78);
  --echo-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --echo-x: 50vw;
  --echo-y: 50vh;
  --echo-scroll: 0;
}

html {
  background: #050505;
}

body {
  background:
    linear-gradient(180deg, #050505 0%, #080808 46%, #050505 100%);
}

body::before {
  opacity: 0.58;
  background:
    linear-gradient(rgba(255, 255, 255, 0.018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.014) 1px, transparent 1px);
  background-size: 56px 56px;
}

body::after {
  opacity: 0.12;
}

.fx-aurora,
.scan-beam {
  display: none !important;
}

.fx-crt {
  opacity: 0.16;
}

.hud-corner {
  display: none;
}

.hud-readout {
  bottom: 18px;
  left: 22px;
  letter-spacing: 0.12em;
}

.progress-bar {
  height: 1px;
  background: var(--echo-ink);
  box-shadow: none;
}

.site-header {
  top: 12px;
  width: min(1160px, calc(100% - 48px));
  padding: 10px 12px;
  border: 1px solid rgba(244, 244, 241, 0.1);
  border-radius: 8px;
  background: rgba(7, 7, 7, 0.72);
  backdrop-filter: blur(20px) saturate(1.08);
  -webkit-backdrop-filter: blur(20px) saturate(1.08);
}

.site-header::before {
  display: none;
}

/* Bug fix (2026-07-14): once scrolled off the hero, the floating nav must fully occlude
   content passing under it. At 0.72 alpha with a transparent top gutter, bright reveal
   headings ghosted above/through the pill (a double-image at the nav, visible in QA).
   .is-stuck is toggled on scroll by echo-enhancements.js so the hero-top glass look stays.
   The pill itself goes solid-opaque (no backdrop-filter dependency — WeChat X5 / older
   WKWebView do not support it and would otherwise bleed sharp text through). */
.site-header.is-stuck {
  background: #060606;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* A body-level opaque scrim covers the full top band (top gutter + side gutters) that the
   floating pill leaves uncovered. It must live OUTSIDE the header: the header's own
   backdrop-filter makes it the containing block for a fixed ::after, which would clip the
   scrim to the pill's width. z-index 69 sits just below the header (70) and above page
   content, so nothing scrolls into the top band visibly. Toggled with .is-stuck. */
.echo-nav-scrim {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 69;
  height: calc(env(safe-area-inset-top, 0px) + 72px);
  background: #060606;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

.echo-nav-scrim.is-visible {
  opacity: 1;
}

.brand {
  min-height: 30px;
}

.nav-links {
  gap: 26px;
}

.nav-links a {
  position: relative;
  padding: 8px 0;
}

.nav-links a::after {
  position: absolute;
  right: 0;
  bottom: 3px;
  left: 0;
  height: 1px;
  content: "";
  background: currentColor;
  opacity: 0;
  transform: scaleX(0.35);
  transition:
    opacity 0.3s var(--echo-ease),
    transform 0.55s var(--echo-ease);
}

.nav-links a:hover::after {
  opacity: 0.7;
  transform: scaleX(1);
}

.lang-toggle {
  border-radius: 6px;
}

.lang-toggle button,
.lang-toggle button.active {
  border-radius: 4px;
}

.hero-section {
  min-height: 100svh;
}

.hero-overlay {
  background:
    linear-gradient(180deg, rgba(5, 5, 5, 0.2), rgba(5, 5, 5, 0.06) 48%, rgba(5, 5, 5, 0.94)),
    linear-gradient(90deg, rgba(5, 5, 5, 0.48), rgba(5, 5, 5, 0.14) 50%, rgba(5, 5, 5, 0.48));
}

.hero-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  width: min(1160px, calc(100% - 48px));
  min-height: 100svh;
  padding: 126px 0 142px;
  text-align: left;
}

.hero-copy {
  width: 100%;
  max-width: 680px;
}

.hero-copy .eyebrow {
  margin-bottom: 22px;
  color: rgba(244, 244, 241, 0.7);
  letter-spacing: 0.16em;
}

.hero-copy h1.echo-brand-title,
.echo-hero-copy-layer h1.echo-brand-title,
:lang(en) .hero-copy h1.echo-brand-title,
:lang(en) .echo-hero-copy-layer h1.echo-brand-title {
  max-width: 12ch;
  margin: 0 0 28px;
  font-size: 92px;
  font-weight: 760;
  line-height: 0.98;
  letter-spacing: 0;
  text-wrap: balance;
}

.echo-ready .hero-copy > .eyebrow,
.echo-ready .hero-copy > h1,
.echo-ready .hero-copy > .hero-body {
  visibility: hidden;
}

.echo-hero-copy-layer {
  position: absolute;
  top: 50svh;
  left: max(24px, calc((100vw - 1160px) / 2));
  z-index: 3;
  display: grid;
  justify-items: start;
  width: min(680px, calc(100% - 64px));
  pointer-events: none;
  text-align: left;
  transform: translateY(calc(-50% - 18px));
}

.echo-hero-copy-layer[hidden] {
  display: none;
}

.echo-overlay-eyebrow {
  margin: 0 0 22px;
  color: rgba(244, 244, 241, 0.7);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.echo-overlay-body {
  display: grid;
  gap: 12px;
  max-width: 620px;
  margin: 0;
  color: var(--echo-muted);
  font-size: 17px;
  line-height: 1.65;
  text-wrap: pretty;
}

.echo-overlay-description {
  display: block;
}

.hero-body {
  display: grid;
  gap: 12px;
  max-width: 620px;
  margin: 0 0 34px;
  color: var(--echo-muted);
  font-size: 17px;
  line-height: 1.65;
  text-wrap: balance;
}

.echo-counterline {
  color: var(--echo-ink);
  font-size: 19px;
  font-weight: 680;
  line-height: 1.45;
}

.echo-hero-description {
  display: block;
}

.hero-actions {
  justify-content: flex-start;
}

.button {
  min-height: 44px;
  border-radius: 5px;
}

.button::after {
  position: absolute;
  inset: -1px;
  z-index: -1;
  content: "";
  border: 1px solid rgba(244, 244, 241, 0.34);
  border-radius: inherit;
  opacity: 0;
  transform: scale(1);
  transition:
    opacity 0.2s var(--echo-ease),
    transform 0.6s var(--echo-ease);
}

.button:hover::after {
  opacity: 0.45;
  transform: scale(1.08);
}

.hero-lines {
  position: absolute;
  bottom: 28px;
  left: 50%;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: min(790px, calc(100% - 160px));
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  animation: none !important;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transform: translateX(-50%);
}

.hero-lines-title {
  grid-column: 1 / -1;
  padding-bottom: 9px;
  color: rgba(244, 244, 241, 0.44);
  text-align: center;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hero-line {
  min-height: 72px;
  padding: 14px 18px;
  border: 0;
  border-top: 1px solid var(--echo-line);
  border-radius: 0;
  background: transparent;
}

.hero-line + .hero-line {
  border-left: 1px solid var(--echo-line);
}

.hero-line:hover {
  border-color: var(--echo-line-strong);
  background: rgba(244, 244, 241, 0.035);
  transform: none;
}

.chapter-nav {
  display: none;
}

.signal-hint {
  top: 98px;
  right: max(28px, calc((100vw - 1160px) / 2));
}

.signal-field.has-echo-particle-field > canvas:not(.echo-hero-particle-canvas) {
  opacity: 0;
}

.signal-field.has-echo-particle-field {
  z-index: 2;
}

.echo-hero-particle-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  outline: 0;
  cursor: pointer;
}

.signal-field.has-echo-particle-field .signal-hint {
  z-index: 2;
}

.waveform-wrap.has-echo-particle-wave {
  position: relative;
  min-height: clamp(170px, 14vw, 260px);
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.waveform-wrap.has-echo-particle-wave > canvas.waveform {
  opacity: 0;
}

.echo-particle-waveform {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

@media (max-width: 760px) {
  .waveform-wrap.has-echo-particle-wave {
    min-height: 155px;
  }
}

.section,
.contact-section,
.site-footer,
.vdp-hero,
.ptp-hero,
.abp-hero,
.ctp-hero,
.ctp-response-inner,
.ctp-final {
  width: min(1160px, calc(100% - 48px));
}

.section {
  padding: 132px 0;
}

.section-tag {
  margin-bottom: 28px;
  color: rgba(244, 244, 241, 0.46);
  letter-spacing: 0.18em;
}

.section-intro {
  max-width: 1040px;
}

.section-intro h2,
.section-intro h2.kinetic-heading {
  max-width: 15ch;
  margin-bottom: 28px;
  font-size: 72px;
  font-weight: 710;
  line-height: 1.02;
  text-wrap: balance;
}

.section-body {
  max-width: 700px;
  font-size: 18px;
}

.title-echo {
  color: rgba(244, 244, 241, 0.42);
}

.build-section,
.pipeline-section,
.textile-section,
.why-section,
.experience-section,
.origin-section,
.vision-section {
  border-top: 1px solid var(--echo-line);
}

.pillar-grid {
  gap: 34px;
  margin-top: 68px;
  border: 0;
  background: transparent;
}

.pillar {
  min-height: 340px;
  padding: 26px 4px 42px;
  border-top: 1px solid var(--echo-line-strong);
  background: transparent;
}

.pillar:hover {
  background: transparent;
}

.pillar-key {
  margin-bottom: 104px;
}

.pillar-rule {
  left: 4px;
}

.narrative-section {
  border-top: 1px solid var(--echo-line);
  background: linear-gradient(180deg, #050505, #090909 50%, #050505);
}

.narrative-sticky {
  width: min(1160px, calc(100% - 48px));
}

.narrative-visual,
.textile-field-wrap {
  border-color: var(--echo-line);
  border-radius: 6px;
}

.marquee-band {
  border-color: var(--echo-line);
  background: #070707;
}

.voice-section {
  padding-right: max(24px, calc((100vw - 1160px) / 2));
  padding-left: max(24px, calc((100vw - 1160px) / 2));
  background: linear-gradient(180deg, transparent, rgba(244, 244, 241, 0.025), transparent);
}

.voice-layout {
  grid-template-columns: minmax(300px, 0.72fr) minmax(520px, 1.28fr);
  gap: 72px;
  max-width: 1160px;
}

.voice-copy {
  top: 112px;
}

.main-product,
.workbench-preview {
  border-color: var(--echo-line);
  border-radius: 6px;
  box-shadow: none;
}

.main-product,
.main-product img {
  min-height: 620px;
  height: 620px;
}

.main-product img {
  transform: scale(1.035);
}

.workbench-preview {
  width: 82%;
  margin-top: -104px;
}

.textile-header {
  grid-template-columns: minmax(0, 1fr) minmax(300px, 0.42fr);
  gap: 80px;
}

.textile-field-wrap {
  margin-top: 64px;
  background: #070707;
}

.textile-grid {
  grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.65fr);
  grid-template-rows: repeat(2, 280px);
  gap: 12px;
  margin-top: 28px;
}

.textile-card {
  min-height: 280px;
  border-color: var(--echo-line);
  border-radius: 6px;
  background: #070707;
}

.textile-card:hover {
  border-color: var(--echo-line-strong);
  transform: translateY(-2px);
}

.textile-card img {
  opacity: 0.92;
  filter: grayscale(0.12) contrast(1.04);
}

.textile-card::after {
  background: linear-gradient(180deg, transparent 32%, rgba(5, 5, 5, 0.94));
}

.textile-card h3 {
  margin: 10px 0 8px;
  font-size: 24px;
}

.why-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 48px;
}

.why-grid article {
  min-height: 210px;
  padding: 30px 2px;
  border-top: 1px solid var(--echo-line);
  border-right: 0 !important;
  border-bottom: 0 !important;
  border-left: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
}

.why-grid article:hover {
  transform: none;
  background: transparent !important;
}

.journey {
  gap: 0;
  border: 0;
  background: transparent;
}

.journey-step {
  min-height: 216px;
  padding: 26px 18px;
  border-top: 1px solid var(--echo-line);
  background: transparent;
}

.journey-step:hover {
  background: rgba(244, 244, 241, 0.025);
}

.origin-inner {
  gap: 96px;
}

.vision-media {
  border-radius: 6px;
}

.contact-section {
  padding: 118px 0 86px;
}

.site-footer {
  padding-bottom: 48px;
}

.echo-heading {
  position: relative;
  isolation: isolate;
}

.echo-heading.is-echo-visible {
  animation: echo-heading-recede 1.6s var(--echo-ease) 0.12s both;
}

@keyframes echo-heading-recede {
  0% {
    text-shadow:
      0 0 0 rgba(244, 244, 241, 0),
      0 0 0 rgba(244, 244, 241, 0);
  }
  28% {
    text-shadow:
      0 10px 8px rgba(244, 244, 241, 0.16),
      0 22px 20px rgba(244, 244, 241, 0.08);
  }
  100% {
    text-shadow:
      0 30px 24px rgba(244, 244, 241, 0),
      0 52px 42px rgba(244, 244, 241, 0);
  }
}

.echo-media {
  position: relative;
  transition:
    border-color 0.45s var(--echo-ease),
    box-shadow 0.65s var(--echo-ease),
    transform 0.55s var(--echo-ease);
}

.echo-media:hover {
  box-shadow:
    7px 7px 0 rgba(244, 244, 241, 0.055),
    14px 14px 0 rgba(244, 244, 241, 0.025);
}

.echo-media img {
  transition:
    transform 0.8s var(--echo-ease),
    filter 0.8s var(--echo-ease);
}

.echo-cursor-layer {
  position: fixed;
  inset: 0;
  z-index: 99;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
}

.echo-trace {
  position: fixed;
  top: var(--echo-y);
  left: var(--echo-x);
  display: block;
  width: 12px;
  height: 12px;
  border: 1px solid rgba(244, 244, 241, 0.24);
  border-radius: 50%;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.55);
  animation: echo-cursor-ring 0.82s var(--echo-ease) forwards;
}

.echo-trace.is-burst {
  width: 20px;
  height: 20px;
  border-color: rgba(244, 244, 241, 0.48);
  animation-duration: 1.08s;
}

@keyframes echo-cursor-ring {
  0% {
    opacity: 0.4;
    transform: translate(-50%, -50%) scale(0.55);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(5.6);
  }
}

.echo-route-wash {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  background:
    linear-gradient(90deg, transparent, rgba(244, 244, 241, 0.08), transparent);
  transform: translateX(-110%);
  animation: echo-route-pass 0.82s var(--echo-ease) both;
}

@keyframes echo-route-pass {
  0% {
    opacity: 0;
    transform: translateX(-110%);
  }
  34% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateX(110%);
  }
}

.vdp-hero,
.ptp-hero,
.abp-hero,
.ctp-hero {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 76svh;
  padding: 144px 0 86px;
  background: transparent;
}

.vdp-hero h1,
.ptp-hero h1,
.abp-hero h1.abp-title,
.ctp-hero h1 {
  max-width: 980px;
  margin-bottom: 24px;
  font-size: 72px;
  font-weight: 710;
  line-height: 1.02;
  text-wrap: balance;
}

.vdp-featured {
  grid-template-columns: minmax(0, 1.16fr) minmax(340px, 0.84fr);
  gap: 52px;
  margin-top: 64px;
}

.vdp-featured-photo,
.vdp-featured-inset {
  border-radius: 6px;
}

.vdp-featured-photo img {
  min-height: 620px;
}

.vdp-device-row {
  gap: 30px;
  margin-top: 22px;
}

.vdp-device {
  grid-template-columns: 108px 1fr;
  gap: 18px;
  padding: 18px 0;
  border: 0;
  border-top: 1px solid var(--echo-line);
  border-radius: 0;
  background: transparent;
}

.vdp-device:hover {
  border-color: var(--echo-line-strong);
  background: transparent;
  transform: translateY(-2px);
}

.vdp-device img {
  width: 108px;
  height: 108px;
  border-radius: 5px;
}

.ptp-hero::before {
  display: none;
}

.ptp-material-rows {
  gap: 0;
  margin-top: 64px;
}

.ptp-material-row {
  gap: 64px;
  padding: 46px 0;
  border: 0;
  border-top: 1px solid var(--echo-line);
  border-radius: 0;
  background: transparent;
}

.ptp-material-row:last-child {
  border-bottom: 1px solid var(--echo-line);
}

.ptp-material-row:hover {
  border-color: var(--echo-line-strong);
  background: transparent;
}

.ptp-material-figure img {
  border: 0;
  border-radius: 6px;
  filter: grayscale(0.1) contrast(1.03);
}

.ptp-signal-row {
  padding-top: 30px;
  padding-bottom: 30px;
}

.abp-hero-rule {
  width: 44px;
  height: 1px;
  background: var(--echo-ink);
}

.abp-investor-panel {
  border-radius: 6px;
  background: rgba(244, 244, 241, 0.035);
}

.ctp-rows {
  gap: 0;
}

.ctp-row {
  padding: 30px 2px;
  border: 0;
  border-top: 1px solid var(--echo-line);
  border-radius: 0;
  background: transparent;
}

.ctp-row:last-child {
  border-bottom: 1px solid var(--echo-line);
}

.ctp-row:hover {
  border-color: var(--echo-line-strong);
  background: transparent;
  transform: none;
}

.ctp-final-mail {
  font-size: 72px;
}

@media (max-width: 1080px) {
  .site-header,
  .hero-content,
  .section,
  .contact-section,
  .site-footer,
  .narrative-sticky,
  .vdp-hero,
  .ptp-hero,
  .abp-hero,
  .ctp-hero,
  .ctp-response-inner,
  .ctp-final {
    width: min(920px, calc(100% - 40px));
  }

  .hero-copy h1.echo-brand-title,
  .echo-hero-copy-layer h1.echo-brand-title,
  :lang(en) .hero-copy h1.echo-brand-title,
  :lang(en) .echo-hero-copy-layer h1.echo-brand-title {
    font-size: 72px;
  }

  .section-intro h2,
  .section-intro h2.kinetic-heading,
  .vdp-hero h1,
  .ptp-hero h1,
  .abp-hero h1.abp-title,
  .ctp-hero h1 {
    font-size: 56px;
  }

  .voice-layout {
    grid-template-columns: 1fr;
    max-width: 920px;
  }

  .voice-copy,
  .product-stage {
    position: relative;
    top: auto;
  }

  .main-product,
  .main-product img {
    min-height: 540px;
    height: 540px;
  }

  .textile-header {
    gap: 44px;
  }

  .vdp-featured {
    grid-template-columns: 1fr;
  }

  .vdp-featured-photo img {
    min-height: 0;
    aspect-ratio: 16 / 10;
  }
}

@media (max-width: 760px) {
  .site-header {
    top: 8px;
    width: calc(100% - 24px);
    padding: 8px 10px;
  }

  .nav-links {
    display: none;
  }

  .brand {
    font-size: 13px;
  }

  .hero-content {
    align-items: flex-start;
    width: calc(100% - 28px);
    padding: 114px 0 78px;
    text-align: left;
  }

  .hero-copy {
    max-width: none;
  }

  .hero-copy h1.echo-brand-title,
  .echo-hero-copy-layer h1.echo-brand-title,
  :lang(en) .hero-copy h1.echo-brand-title,
  :lang(en) .echo-hero-copy-layer h1.echo-brand-title {
    max-width: 12ch;
    margin: 0 0 24px;
    font-size: 48px;
    line-height: 1.02;
    text-wrap: pretty;
  }

  .echo-hero-copy-layer {
    /* top/left removed: later ≤760px block sets top:auto/left:auto, so these were
       inert dead declarations (editing them here had no effect — a debug trap). */
    justify-items: start;
    width: calc(100% - 28px);
    text-align: left;
    transform: none;
  }

  .echo-overlay-eyebrow {
    margin-bottom: 18px;
  }

  .echo-overlay-body {
    max-width: 34rem;
    font-size: 15px;
    text-wrap: pretty;
  }

  .hero-body {
    max-width: 34rem;
    margin-right: 0;
    margin-left: 0;
    font-size: 15px;
    text-wrap: pretty;
  }

  .echo-counterline {
    font-size: 17px;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .hero-lines {
    display: none;
  }

  .signal-hint {
    top: 86px;
    right: 16px;
  }

  .section,
  .contact-section,
  .site-footer,
  .narrative-sticky,
  .vdp-hero,
  .ptp-hero,
  .abp-hero,
  .ctp-hero,
  .ctp-response-inner,
  .ctp-final {
    width: calc(100% - 28px);
  }

  .section {
    padding: 88px 0;
  }

  .section-intro h2,
  .section-intro h2.kinetic-heading,
  .vdp-hero h1,
  .ptp-hero h1,
  .abp-hero h1.abp-title,
  .ctp-hero h1 {
    max-width: none;
    font-size: 38px;
    line-height: 1.08;
  }

  .section-body,
  .vdp-hero-body,
  .ptp-hero-body,
  .abp-hero-body,
  .ctp-hero-body {
    font-size: 16px;
  }

  .pillar-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .pillar {
    min-height: 260px;
  }

  .pillar-key {
    margin-bottom: 66px;
  }

  .main-product,
  .main-product img {
    min-height: 390px;
    height: 390px;
  }

  .workbench-preview {
    width: 92%;
    margin-top: -52px;
  }

  .textile-header {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .textile-grid {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    gap: 12px;
  }

  .textile-card,
  .textile-card-1 {
    grid-row: auto;
    min-height: 330px;
  }

  .why-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .journey {
    grid-template-columns: 1fr;
  }

  .journey-step {
    min-height: 188px;
  }

  .vdp-hero,
  .ptp-hero,
  .abp-hero,
  .ctp-hero {
    min-height: 70svh;
    padding: 126px 0 68px;
  }

  .vdp-featured {
    margin-top: 44px;
  }

  .vdp-device-row {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .ptp-material-row {
    grid-template-columns: 1fr;
    gap: 22px;
    padding: 34px 0;
  }

  .ptp-material-row:nth-child(2n) .ptp-material-figure {
    order: 0;
  }

  .ctp-row {
    grid-template-columns: 1fr;
    gap: 18px;
  }

  .ctp-final-mail {
    font-size: 36px;
  }

  .echo-cursor-layer {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .echo-heading,
  .echo-trace,
  .echo-route-wash {
    animation: none;
  }

  .echo-trace,
  .echo-route-wash {
    display: none;
  }

  .echo-media,
  .echo-media img {
    transition: none;
  }
}

/* Locale-safe product storytelling: keep each language inside its grid track. */
.voice-layout {
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
  gap: 56px;
}

.voice-layout > *,
.voice-copy,
.product-stage,
.voice-copy .section-intro {
  min-width: 0;
  max-width: 100%;
}

.voice-copy {
  top: 104px;
}

.voice-copy .section-intro h2,
.voice-copy .section-intro h2.kinetic-heading,
.voice-copy .section-intro h2.fr-heading {
  max-width: 11.5ch;
  margin-bottom: 24px;
  font-size: 54px;
  line-height: 1.04;
  overflow-wrap: normal;
  word-break: normal;
  text-wrap: pretty;
}

.voice-copy .section-body {
  max-width: 34rem;
  font-size: 17px;
  line-height: 1.68;
}

:lang(zh) .kinetic-heading .kh-word,
:lang(zh) .fr-heading .fr-word {
  display: inline;
  white-space: normal;
}

:lang(zh) .voice-copy .section-intro h2,
:lang(zh) .voice-copy .section-intro h2.kinetic-heading,
:lang(zh) .voice-copy .section-intro h2.fr-heading {
  max-width: 9.8em;
  font-size: 52px;
  line-height: 1.12;
  line-break: strict;
  overflow-wrap: anywhere;
}

:lang(en) .voice-copy .section-intro h2,
:lang(en) .voice-copy .section-intro h2.kinetic-heading,
:lang(en) .voice-copy .section-intro h2.fr-heading {
  max-width: 100%;
  font-size: 50px;
  hyphens: none;
}

.voice-copy .section-intro h2,
.voice-copy .section-intro h2.kinetic-heading,
.voice-copy .section-intro h2.fr-heading,
:lang(zh) .voice-copy .section-intro h2,
:lang(zh) .voice-copy .section-intro h2.kinetic-heading,
:lang(zh) .voice-copy .section-intro h2.fr-heading {
  display: block;
  width: 100%;
  max-width: 100%;
}

.vision-media.has-signal-universe {
  position: relative;
  width: min(980px, 100%);
  max-width: 980px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--echo-line);
  border-radius: 6px;
  background: #050505;
  box-shadow:
    9px 9px 0 rgba(244, 244, 241, 0.045),
    18px 18px 0 rgba(244, 244, 241, 0.018);
}

.vision-media.has-signal-universe > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
}

.signal-universe-canvas {
  position: absolute;
  z-index: 20;
  display: block;
  overflow: hidden;
  border: 1px solid var(--echo-line);
  border-radius: 6px;
  background: #050505;
  box-shadow:
    9px 9px 0 rgba(244, 244, 241, 0.045),
    18px 18px 0 rgba(244, 244, 241, 0.018);
  pointer-events: auto;
  touch-action: pan-y;
}

.signal-universe-canvas[hidden] {
  display: none;
}

@media (max-width: 1080px) {
  .voice-layout {
    grid-template-columns: 1fr;
    gap: 54px;
  }

  .voice-copy {
    position: relative;
    top: auto;
  }

  .voice-copy .section-intro h2,
  .voice-copy .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2.fr-heading,
  :lang(en) .voice-copy .section-intro h2,
  :lang(en) .voice-copy .section-intro h2.kinetic-heading,
  :lang(en) .voice-copy .section-intro h2.fr-heading,
  :lang(zh) .voice-copy .section-intro h2,
  :lang(zh) .voice-copy .section-intro h2.kinetic-heading,
  :lang(zh) .voice-copy .section-intro h2.fr-heading {
    max-width: 13ch;
    font-size: 56px;
  }
}

@media (max-width: 760px) {
  .voice-layout {
    gap: 42px;
  }

  .voice-copy .section-intro h2,
  .voice-copy .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2.fr-heading,
  :lang(en) .voice-copy .section-intro h2,
  :lang(en) .voice-copy .section-intro h2.kinetic-heading,
  :lang(en) .voice-copy .section-intro h2.fr-heading,
  :lang(zh) .voice-copy .section-intro h2,
  :lang(zh) .voice-copy .section-intro h2.kinetic-heading,
  :lang(zh) .voice-copy .section-intro h2.fr-heading {
    max-width: none;
    font-size: 38px;
    line-height: 1.08;
  }

  .voice-copy .section-body {
    font-size: 16px;
  }

  .vision-media.has-signal-universe {
    aspect-ratio: 4 / 3;
    margin-top: 42px;
    box-shadow:
      5px 5px 0 rgba(244, 244, 241, 0.04),
      10px 10px 0 rgba(244, 244, 241, 0.016);
  }

  .signal-universe-canvas {
    box-shadow:
      5px 5px 0 rgba(244, 244, 241, 0.04),
      10px 10px 0 rgba(244, 244, 241, 0.016);
  }
}

/* Wide editorial rhythm and responsive voice-product composition. */
@media (min-width: 1440px) {
  .section:not(.voice-section),
  .contact-section,
  .site-footer,
  .narrative-sticky {
    width: min(1240px, calc(100% - 64px));
  }

  .section:not(.voice-section) {
    padding-top: 150px;
    padding-bottom: 150px;
  }
}

.voice-section {
  width: 100%;
  max-width: none;
  padding-right: max(32px, calc((100vw - 1360px) / 2));
  padding-left: max(32px, calc((100vw - 1360px) / 2));
}

.voice-layout {
  grid-template-columns: minmax(420px, 0.78fr) minmax(640px, 1.22fr);
  gap: 64px;
  width: 100%;
  max-width: 1360px;
  margin-right: auto;
  margin-left: auto;
}

.main-product,
.main-product img {
  min-height: 680px;
  height: 680px;
}

.section-tag {
  transform: translate3d(var(--section-shift, 0px), 0, 0);
  will-change: transform;
}

.signal-universe-canvas {
  cursor: pointer;
}

.signal-universe-canvas:focus-visible {
  outline: 0;
  filter: brightness(1.04);
}

/* Visible keyboard focus for the interactive canvases (all tabIndex=0 with
   keydown handlers). The base outline:0 suppresses the persistent mouse-click
   ring; restore a ring only for :focus-visible (keyboard), later + higher
   specificity so it beats the outline:0 rules above. */
.echo-hero-particle-canvas:focus-visible,
.relation-field-canvas:focus-visible,
.textile-flow-canvas:focus-visible,
.signal-universe-canvas:focus-visible {
  outline: 2px solid rgba(244, 244, 241, 0.65);
  outline-offset: 2px;
}

@media (max-width: 1300px) {
  .voice-section {
    padding-right: max(24px, calc((100vw - 1160px) / 2));
    padding-left: max(24px, calc((100vw - 1160px) / 2));
  }

  .voice-layout {
    grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
    gap: 56px;
    max-width: 1160px;
  }

  .main-product,
  .main-product img {
    min-height: 620px;
    height: 620px;
  }
}

@media (max-width: 1080px) {
  .voice-section {
    padding-right: max(20px, calc((100vw - 920px) / 2));
    padding-left: max(20px, calc((100vw - 920px) / 2));
  }

  .voice-layout {
    grid-template-columns: 1fr;
    gap: 54px;
    max-width: 920px;
  }

  .main-product,
  .main-product img {
    min-height: 540px;
    height: 540px;
  }
}

@media (max-width: 760px) {
  .voice-section {
    padding-right: 14px;
    padding-left: 14px;
  }

  .voice-layout {
    gap: 42px;
  }

  .main-product,
  .main-product img {
    min-height: 390px;
    height: 390px;
  }

  .section-tag {
    transform: none;
    will-change: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .section-tag {
    transform: none;
    will-change: auto;
  }
}

/* Keep the bilingual hero in one content flow so copy and actions cannot collide. */
.echo-ready .hero-copy > .hero-actions {
  visibility: hidden;
}

.echo-overlay-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: flex-start;
  margin-top: 26px;
  pointer-events: auto;
}

:lang(zh) .echo-hero-copy-layer h1.echo-brand-title {
  max-width: 11.5em;
  font-size: clamp(64px, 6vw, 92px);
  line-height: 1.08;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.origin-lead {
  max-width: 24ch;
  letter-spacing: 0;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

:lang(zh) .origin-lead {
  max-width: 16em;
  font-size: clamp(30px, 3.2vw, 42px);
  line-height: 1.34;
}

/* The signal field should feel embedded in the page, without a framed card. */
.vision-media.has-signal-universe,
.signal-universe-canvas {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Product lightbox copy lives in its own high-contrast information rail. */
.pr-lightbox {
  padding: clamp(12px, 2vw, 28px);
}

.echo-lightbox-host {
  position: fixed !important;
  inset: 0 !important;
  z-index: 119 !important;
  width: 100vw !important;
  height: 100dvh !important;
  margin: 0 !important;
  transform: none !important;
}

.echo-lightbox-host > .pr-grid {
  display: none !important;
}

.echo-lightbox-host > .pr-lightbox {
  position: absolute !important;
  inset: 0 !important;
}

.pr-lightbox-inner {
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: min(1160px, 100%);
  max-height: calc(100dvh - 32px);
}

.pr-lightbox-figure {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  min-height: 0;
  max-height: calc(100dvh - 158px);
  background: #080808;
}

.pr-lightbox-figure img {
  min-height: 0;
  max-height: calc(100dvh - 272px);
  object-fit: contain;
  background: #0a0a0a;
}

.pr-lightbox-figure figcaption {
  position: relative;
  right: auto;
  bottom: auto;
  left: auto;
  z-index: 3;
  display: grid;
  gap: 5px;
  min-height: 96px;
  padding: 18px 22px 20px;
  border-top: 1px solid rgba(244, 244, 241, 0.12);
  color: var(--echo-ink);
  background: #080808;
  text-align: left;
}

.pr-lightbox-cn {
  color: rgba(244, 244, 241, 0.58);
  line-height: 1.5;
}

.pr-lightbox-title {
  max-width: 100%;
  color: var(--echo-ink);
  font-size: clamp(22px, 2.4vw, 32px);
  line-height: 1.18;
  overflow-wrap: anywhere;
  text-shadow: none;
}

.pr-lightbox-corner-bl,
.pr-lightbox-corner-br {
  display: none;
}

@media (max-width: 760px) {
  .signal-hint {
    display: none;
  }

  .echo-overlay-actions {
    justify-content: flex-start;
    margin-top: 22px;
  }

  :lang(zh) .echo-hero-copy-layer h1.echo-brand-title {
    max-width: 100%;
    font-size: 46px;
    line-height: 1.08;
  }

  .origin-lead,
  :lang(zh) .origin-lead {
    max-width: none;
    font-size: 30px;
    line-height: 1.32;
    text-wrap: pretty;
  }

  .pr-lightbox-inner {
    gap: 12px;
    max-height: calc(100dvh - 20px);
  }

  .pr-lightbox-figure {
    max-height: calc(100dvh - 138px);
  }

  .pr-lightbox-figure img {
    max-height: 48dvh;
  }

  .pr-lightbox-figure figcaption {
    min-height: 0;
    padding: 15px 16px 17px;
  }
}

/* Signal-to-experience editorial media */
.narrative-visual {
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: #050505;
  box-shadow: none;
}

.narrative-plate.has-editorial-media {
  overflow: hidden;
  background: transparent;
  animation: none !important;
}

.narrative-plate.has-editorial-media::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  content: "";
  background:
    linear-gradient(90deg, rgba(4, 4, 4, 0.62), transparent 35%, transparent 70%, rgba(4, 4, 4, 0.28)),
    linear-gradient(180deg, rgba(4, 4, 4, 0.2), transparent 42%, rgba(4, 4, 4, 0.72));
}

.echo-narrative-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.38;
  filter: grayscale(0.78) brightness(0.48) contrast(1.18);
  transform: scale(1.085);
  transition:
    opacity 1.15s var(--echo-ease),
    filter 1.6s var(--echo-ease),
    transform 2.4s var(--echo-ease);
}

.narrative-plate[data-on="1"] .echo-narrative-image {
  opacity: 0.9;
  filter: grayscale(0.2) brightness(0.76) contrast(1.08);
  transform: scale(1.018);
}

.narrative-plate[data-media-mode="interface"] .echo-narrative-image {
  object-fit: contain;
  padding: 4%;
  background: #060606;
  filter: grayscale(1) brightness(0.54) contrast(1.3);
}

.narrative-plate[data-media-mode="interface"][data-on="1"] .echo-narrative-image {
  filter: grayscale(0.72) brightness(0.78) contrast(1.18);
}

.narrative-plate[data-media-mode="memory"] .echo-narrative-image {
  object-fit: cover;
  filter: grayscale(1) invert(1) brightness(0.28) contrast(1.45);
  mix-blend-mode: screen;
}

.narrative-plate[data-media-mode="memory"][data-on="1"] .echo-narrative-image {
  filter: grayscale(1) invert(1) brightness(0.48) contrast(1.36);
}

.narrative-scanline {
  z-index: 2;
  opacity: 0.3;
  mix-blend-mode: screen;
}

/* Four product slow reveal */
@property --pr-reveal {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

.pr-grid {
  gap: clamp(22px, 2.4vw, 34px);
  background: transparent;
}

.pr-tile,
.pr-tile:hover,
.pr-tile:focus-visible {
  --pr-reveal: 0%;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.pr-tile {
  transition: transform 0.9s var(--echo-ease);
}

.pr-tile:hover,
.pr-tile:focus-visible,
.pr-tile.is-revealed {
  --pr-reveal: 190%;
  transform: translateY(-4px);
}

.pr-stage {
  overflow: hidden;
  border: 0;
  border-radius: 4px;
  background: #050505;
}

.pr-img,
.pr-tile:hover .pr-img,
.pr-tile:focus-visible .pr-img {
  transition:
    filter 1.55s var(--echo-ease),
    opacity 1.35s var(--echo-ease),
    transform 2.1s var(--echo-ease);
}

.pr-img {
  opacity: 0.78;
  filter: grayscale(0.96) brightness(0.28) contrast(1.18);
  transform: scale(1.025);
}

.pr-tile:hover .pr-img,
.pr-tile:focus-visible .pr-img,
.pr-tile.is-revealed .pr-img {
  opacity: 1;
  filter: grayscale(0.04) brightness(0.98) contrast(1.04);
  transform: scale(1.065);
}

.pr-veil {
  opacity: 0.88;
  background:
    radial-gradient(circle at 1px 1px, rgba(244, 244, 241, 0.15) 1px, transparent 1.55px) 0 0 / 14px 14px,
    rgba(2, 2, 2, 0.52);
  -webkit-mask-image: radial-gradient(circle at var(--pr-mx, 50%) var(--pr-my, 50%), transparent 0 var(--pr-reveal), #000 calc(var(--pr-reveal) + 20%));
  mask-image: radial-gradient(circle at var(--pr-mx, 50%) var(--pr-my, 50%), transparent 0 var(--pr-reveal), #000 calc(var(--pr-reveal) + 20%));
  transition:
    --pr-reveal 1.65s var(--echo-ease),
    opacity 1.45s var(--echo-ease);
}

.pr-tile:hover .pr-veil,
.pr-tile:focus-visible .pr-veil,
.pr-tile.is-revealed .pr-veil {
  opacity: 0.06;
}

.pr-grid-lines,
.pr-scan,
.pr-bracket {
  display: none;
}

.pr-seal {
  top: 16px;
  left: 16px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  transform: none;
  transition: opacity 0.8s var(--echo-ease);
}

.pr-tile:hover .pr-seal,
.pr-tile:focus-visible .pr-seal,
.pr-tile.is-revealed .pr-seal {
  opacity: 0.34;
}

.pr-meta {
  padding: 17px 0 0;
  border: 0;
  background: transparent;
}

.pr-cn,
.pr-title,
.pr-cue {
  transition:
    color 0.85s var(--echo-ease),
    opacity 0.85s var(--echo-ease),
    transform 0.85s var(--echo-ease);
}

.pr-tile:hover .pr-cue,
.pr-tile:focus-visible .pr-cue,
.pr-tile.is-revealed .pr-cue {
  transform: translateX(5px);
}

/* Draggable relation field */
.signal-map.has-relation-field {
  min-height: clamp(520px, 52vw, 680px);
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: #030303;
  box-shadow: none;
  isolation: isolate;
}

.signal-map.has-relation-field::before,
.signal-map.has-relation-field::after {
  content: none;
}

.signal-map.has-relation-field > span,
.signal-map.has-relation-field > .signal-core,
.signal-map.has-relation-field > canvas:not(.relation-field-canvas) {
  display: none;
}

.relation-field-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  outline: 0;
  cursor: grab;
  touch-action: none;
}

.relation-field-canvas[data-interaction="node"] {
  cursor: pointer;
}

.relation-field-canvas:active {
  cursor: grabbing;
}

@media (max-width: 900px) {
  .narrative-sticky {
    gap: 34px;
  }

  .signal-map.has-relation-field {
    min-height: 500px;
  }
}

@media (max-width: 760px) {
  .narrative-visual {
    aspect-ratio: 4 / 3;
  }

  .echo-narrative-image {
    filter: grayscale(0.6) brightness(0.58) contrast(1.12);
  }

  .signal-map.has-relation-field {
    min-height: 420px;
  }

  .pr-img {
    opacity: 0.96;
    filter: grayscale(0.24) brightness(0.74) contrast(1.06);
  }

  .pr-veil {
    opacity: 0.24;
  }
}

@media (pointer: coarse) {
  .pr-img {
    opacity: 0.94;
    filter: grayscale(0.28) brightness(0.7) contrast(1.08);
  }

  .pr-veil {
    opacity: 0.28;
  }
}

@media (prefers-reduced-motion: reduce) {
  .echo-narrative-image,
  .pr-img,
  .pr-veil,
  .pr-tile {
    transition-duration: 0.01ms;
  }
}

/* Body-to-care interactive textile path */
.textile-arc.has-textile-flow {
  position: relative;
  display: block;
  min-height: clamp(390px, 31vw, 470px);
  overflow: hidden;
  border: 0;
  background: transparent;
  isolation: isolate;
}

.textile-arc.has-textile-flow > span {
  display: none !important;
}

.textile-flow-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  outline: 0;
  cursor: crosshair;
  touch-action: manipulation;
}

.textile-flow-canvas[data-interaction="node"] {
  cursor: pointer;
}

.textile-flow-caption {
  position: absolute;
  bottom: 2px;
  left: 0;
  z-index: 2;
  display: grid;
  gap: 3px;
  max-width: 260px;
  pointer-events: none;
  transform-origin: left bottom;
  transition: transform 0.34s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

.textile-flow-caption.is-lensed {
  transform: scale(1.06);
}

.textile-arc.has-textile-flow .textile-flow-index {
  display: block;
  height: auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  /* was 0.42 (~3.7:1, below WCAG AA 4.5:1 on the dark gradient); 0.55 ≈ 5.5:1
     while staying subordinate to the white title and the 0.5-alpha body. */
  color: rgba(244, 244, 241, 0.55);
  background: transparent;
  font-size: 10px;
  font-weight: 850;
  letter-spacing: 0.12em;
  opacity: 1;
  place-items: initial;
  transform: none;
  transition: none;
}

.textile-header {
  grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.15fr);
  gap: clamp(36px, 4vw, 64px);
  align-items: center;
}

.textile-flow-title {
  color: var(--echo-ink);
  font-size: 15px;
  font-weight: 800;
  line-height: 1.2;
}

.textile-flow-body {
  margin: 0;
  color: rgba(244, 244, 241, 0.5);
  font-size: 12px;
  line-height: 1.45;
}

@media (max-width: 760px) {
  .textile-header {
    grid-template-columns: 1fr;
    gap: 38px;
  }

  .textile-arc.has-textile-flow {
    min-height: 360px;
  }

  .textile-flow-caption {
    top: 0;
    right: 0;
    bottom: auto;
    left: auto;
    max-width: 150px;
    text-align: right;
    transform-origin: right top;
  }

  .textile-flow-body {
    font-size: 11px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .textile-flow-caption {
    transition: none;
  }
}

/* Compact mobile hero: copy owns the height and the particle mark gets its own stage. */
@media (max-width: 760px) {
  .hero-section {
    display: block;
    height: auto !important;
    min-height: 0 !important;
  }

  .hero-content {
    position: absolute;
    inset: 0;
    width: 100%;
    min-height: 0 !important;
    height: 100%;
    margin: 0;
    padding: 0;
  }

  .echo-hero-copy-layer {
    position: relative;
    top: auto;
    left: auto;
    width: calc(100% - 28px);
    margin: 0 14px;
    /* padding removed: later ≤760px block sets padding:88px 0 64px, which wins —
       this was an inert dead declaration. Edit padding at that later block. */
    transform: none;
  }

  .echo-hero-copy-layer h1.echo-brand-title,
  :lang(en) .echo-hero-copy-layer h1.echo-brand-title,
  :lang(zh) .echo-hero-copy-layer h1.echo-brand-title {
    max-width: 100%;
    margin-bottom: 22px;
    font-size: clamp(39px, 10.8vw, 48px);
    line-height: 1.08;
    overflow-wrap: normal;
    word-break: keep-all;
    text-wrap: balance;
  }

  .echo-overlay-body {
    gap: 10px;
    max-width: 100%;
    font-size: 15px;
    line-height: 1.58;
  }

  .echo-counterline {
    font-size: 17px;
    line-height: 1.4;
  }

  .echo-overlay-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
    gap: 10px;
    margin-top: 24px;
  }

  .echo-overlay-actions .button {
    width: 100%;
    min-width: 0;
    padding-right: 12px;
    padding-left: 12px;
    white-space: normal;
    text-align: center;
  }

  .echo-hero-particle-canvas {
    cursor: default;
  }

  .pixel-cursor {
    display: none !important;
  }
}

@media (max-width: 390px) {
  .echo-hero-copy-layer {
    padding-top: 104px;
  }

  .echo-hero-copy-layer h1.echo-brand-title,
  :lang(en) .echo-hero-copy-layer h1.echo-brand-title,
  :lang(zh) .echo-hero-copy-layer h1.echo-brand-title {
    font-size: 38px;
  }
}

/* Mobile reading mode: preserve the editorial system while removing desktop-length stacking. */
@media (max-width: 760px) {
  html {
    scroll-padding-top: 72px;
  }

  body {
    overflow-x: clip;
  }

  section[id] {
    scroll-margin-top: 72px;
  }

  .site-header {
    top: max(6px, env(safe-area-inset-top));
    width: calc(100% - 20px);
    padding: 5px 8px;
  }

  .site-header > .ikho-app-entry {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .site-header .brand,
  .site-footer .brand {
    min-height: 44px;
  }

  .lang-toggle {
    gap: 0;
    padding: 0;
  }

  .lang-toggle button {
    min-width: 44px;
    height: 44px;
  }

  .section {
    padding-top: 68px;
    padding-bottom: 68px;
  }

  .section-tag {
    margin-bottom: 18px;
    letter-spacing: 0.22em;
  }

  .section-intro h2,
  .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2,
  .voice-copy .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2.fr-heading,
  :lang(en) .voice-copy .section-intro h2,
  :lang(en) .voice-copy .section-intro h2.kinetic-heading,
  :lang(en) .voice-copy .section-intro h2.fr-heading,
  :lang(zh) .voice-copy .section-intro h2,
  :lang(zh) .voice-copy .section-intro h2.kinetic-heading,
  :lang(zh) .voice-copy .section-intro h2.fr-heading {
    margin-bottom: 16px;
    font-size: clamp(34px, 9.8vw, 38px);
    line-height: 1.1;
  }

  .pillar-grid {
    margin-top: 38px;
  }

  .pillar {
    min-height: 0;
    padding: 26px 22px 30px;
  }

  .pillar-key {
    margin-bottom: 30px;
  }

  .narrative-sticky {
    padding-top: 68px;
    padding-bottom: 68px;
  }

  .signal-map.has-relation-field {
    min-height: 340px;
  }

  .thesis-visual,
  .thesis-blocks,
  .voice-points {
    gap: 8px;
  }

  .thesis-blocks article,
  .voice-points article {
    padding: 16px;
  }

  .voice-layout {
    gap: 34px;
  }

  .flow-strip,
  .pr-grid,
  .pipeline-diagram-5,
  .textile-grid,
  .why-grid,
  .journey {
    display: flex;
    gap: 14px;
    margin-right: -14px;
    margin-left: -14px;
    padding-right: 14px;
    padding-bottom: 12px;
    padding-left: 14px;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .flow-strip::-webkit-scrollbar,
  .pr-grid::-webkit-scrollbar,
  .pipeline-diagram-5::-webkit-scrollbar,
  .textile-grid::-webkit-scrollbar,
  .why-grid::-webkit-scrollbar,
  .journey::-webkit-scrollbar {
    display: none;
  }

  .flow-strip {
    margin-top: 26px;
    margin-bottom: 16px;
  }

  .flow-strip span {
    flex: 0 0 min(46%, 160px);
    min-height: 70px;
    scroll-snap-align: start;
  }

  .product-reveal-head {
    margin-top: 54px;
  }

  .pr-grid {
    margin-top: 32px;
  }

  .pr-grid > *,
  .pipeline-diagram-5 > *,
  .textile-grid > *,
  .why-grid > * {
    flex: 0 0 86%;
    min-width: 0;
    scroll-snap-align: start;
  }

  .pr-tile,
  .pr-tile:hover,
  .pr-tile:focus-visible,
  .textile-card:hover {
    transform: none;
  }

  .pipeline-diagram-5 {
    margin-top: 36px;
  }

  .pipeline-diagram::before,
  .pipeline-diagram::after {
    display: none;
  }

  .pipeline-diagram article {
    min-height: 230px;
    padding: 26px;
  }

  .textile-header {
    gap: 28px;
  }

  .textile-arc.has-textile-flow {
    min-height: 310px;
  }

  .textile-field-wrap {
    margin-top: 38px;
  }

  .textile-grid {
    margin-top: 28px;
  }

  .why-grid {
    margin-top: 42px;
  }

  .why-grid article {
    min-height: 210px;
    padding: 24px 18px;
    border-top: 0 !important;
    border-left: 1px solid var(--echo-line) !important;
  }

  .journey {
    margin-top: 42px;
  }

  .journey-step {
    flex: 0 0 78%;
    min-height: 198px;
    scroll-snap-align: start;
  }

  .origin-inner {
    gap: 48px;
  }

  .vision-media.has-signal-universe {
    margin-top: 34px;
  }

  .contact-section {
    padding-top: 76px;
    padding-bottom: 72px;
  }

  .site-footer .footer-links a,
  .site-footer [data-ikho-icp] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .site-footer [data-ikho-icp] {
    justify-content: flex-end;
  }

  /* Touch targets: physiology-textile page cross-nav links ship at 18px. */
  .ptp-cta-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Contact page primary email link ships at 25px; extend the tap area to 44px
     with a transparent pseudo-element so the tight underline stays put. */
  .ctp-hero-mail {
    position: relative;
  }

  .ctp-hero-mail::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 44px;
  }
}

/* Mobile hardening: WeChat / older-WebView resilience.
   Root causes addressed:
   - No text-size-adjust meant WeChat Android font boosting inflated copy,
     widened unbreakable runs, and let the layout viewport expand sideways
     (hero title/buttons clipped at the right edge, page pannable).
   - Char-split heading effects (.kh-char / .fr-unit) can freeze mid-reveal
     when the WebView suspends rAF/timers, leaving headings partially
     invisible; per-char inline-blocks also defeat CJK punctuation rules.
   - .relation-field-canvas shipped touch-action:none, swallowing vertical
     swipes across a full-width block.
   - clamp()/min()/env()/svh have no effect on older engines; critical
     mobile declarations restate a plain-px fallback first. */

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

@media (min-width: 761px) {
  .hero-section,
  .hero-content {
    min-height: 100vh;
    min-height: 100svh;
  }

  .echo-hero-copy-layer {
    top: 50vh;
    top: 50svh;
  }

  .vdp-hero,
  .ptp-hero,
  .abp-hero,
  .ctp-hero {
    min-height: 76vh;
    min-height: 76svh;
  }
}

@media (max-width: 1080px) {
  html {
    overflow-x: hidden;
  }

  /* clip (not hidden) still blocks horizontal overscroll but does NOT turn
     <body> into a scroll container — hidden here would size body to content and
     break every position:sticky descendant (the narrative stepper stops pinning
     on touch, collapsing its 5-stage scroll range). Matches the ≤760px rule. */
  body {
    overflow-x: clip;
  }
}

@media (pointer: coarse) {
  .kinetic-heading .kh-char,
  .fr-heading .fr-unit {
    opacity: 1 !important;
    filter: none !important;
    clip-path: none !important;
    transform: none !important;
    transition: none !important;
  }

  .kinetic-heading .kh-sweep {
    display: none !important;
  }

  .relation-field-canvas {
    touch-action: pan-y !important;
  }
}

@media (max-width: 760px) {
  .site-header {
    top: 6px;
    top: max(6px, env(safe-area-inset-top));
  }

  .kinetic-heading .kh-word,
  .kinetic-heading .kh-char,
  .fr-heading .fr-word,
  .fr-heading .fr-unit {
    display: inline;
    white-space: normal;
  }

  .section-intro h2,
  .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2,
  .voice-copy .section-intro h2.kinetic-heading,
  .voice-copy .section-intro h2.fr-heading,
  :lang(en) .voice-copy .section-intro h2,
  :lang(en) .voice-copy .section-intro h2.kinetic-heading,
  :lang(en) .voice-copy .section-intro h2.fr-heading,
  :lang(zh) .voice-copy .section-intro h2,
  :lang(zh) .voice-copy .section-intro h2.kinetic-heading,
  :lang(zh) .voice-copy .section-intro h2.fr-heading {
    font-size: 36px;
    font-size: clamp(34px, 9.8vw, 38px);
    line-break: strict;
    overflow-wrap: break-word;
  }

  /* The copy layer is a grid with implicit auto columns: an unbreakable
     keep-all title run (9 chars x 10.8vw ~= 364px) grew the column past the
     347px container and dragged the description and CTAs off-screen. Pin the
     track to the container and let the title break under CJK strict rules. */
  .echo-hero-copy-layer,
  .echo-overlay-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .echo-hero-copy-layer > * {
    min-width: 0;
    max-width: 100%;
  }

  :lang(zh) .echo-hero-copy-layer h1.echo-brand-title {
    font-size: 44px;
    font-size: clamp(39px, 10.8vw, 48px);
    word-break: normal;
    line-break: strict;
    overflow-wrap: break-word;
  }

  .echo-counterline,
  .echo-overlay-description,
  .hero-body {
    overflow-wrap: break-word;
  }

  .echo-hero-copy-layer {
    padding: 88px 0 64px;
  }

  .vdp-hero,
  .ptp-hero,
  .abp-hero,
  .ctp-hero {
    min-height: 70vh;
    min-height: 70svh;
    padding-top: 108px;
    padding-bottom: 60px;
  }

  .flow-strip span {
    flex: 0 0 46%;
    flex: 0 0 min(46%, 160px);
  }

  .flow-strip,
  .pr-grid,
  .pipeline-diagram-5,
  .textile-grid,
  .why-grid,
  .journey {
    scroll-snap-type: x proximity;
  }

  .signal-map .relation-field-canvas {
    touch-action: pan-y;
  }
}

/* Scroll-reveal failsafe (mobile / WeChat WebView).
   [data-reveal] elements ship as opacity:0 + blur(10px) + translateY(30px) and
   only become visible when JS adds .is-visible from a scroll/intersection
   observer. That reveal has no fallback: prefers-reduced-motion zeroes only
   `animation` (this uses `transition`), so when the observer is throttled,
   missed on a fast flick, or never fires (WeChat X5 / older WKWebView), whole
   sections stay permanently blank while scrolling down — and even when it does
   fire, the 1.15s blurred fade reads as laggy "still loading" content mid-scroll.
   Pin the revealed end-state on coarse pointers so mobile content is always
   present and immediate. The desktop scroll-reveal animation is untouched.
   Scoped to [data-reveal] only — decorative hover glows (.pillar-glow,
   .business-card-scan, .pr-scan, …) are class-gated, not [data-reveal], so they
   correctly stay hidden until interaction. */
@media (pointer: coarse) {
  [data-reveal] {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
  /* The [data-reveal] floor above only lights the wrapper. These children ship
     opacity:0 and are revealed by `.is-visible` added to an ANCESTOR (the same
     observer), so the wrapper-only floor can't reach them — when the observer is
     throttled/missed on a coarse pointer (WeChat X5), the cards stay blank.
     Pin the descendants too. Inert on the canvas path (textile spans become
     display:none once the flow canvas mounts). */
  .pipeline-diagram article {
    opacity: 1 !important;
    transform: none !important;
  }
  .textile-arc span {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---- Mobile narrative stepper pacing --------------------------------------
   Founder: on the phone "从信号到体验" scrolls too fast — the 5 stages
   (人类日常 / 多模态数据 / AI Memory / 模式识别 / 产品体验) blow past with no
   dwell. The frozen bundle derives the active stage live from scroll progress:
       stage = floor( clamp(-rect.top / (rect.height - innerHeight), 0, 1) * 5 )
   The base build's ≤1080px rule collapses .narrative-section to height:auto and
   un-pins .narrative-sticky (position:relative), so the whole 5-stage range is
   only ~1 viewport tall → every stage flips after ~20px of scroll (measured:
   section 921px, C=109px, ≈22px/stage at 375×812). That is the "too fast".
   Fix: re-pin the stepper and give the section real height so each stage gets
   ~a screenful of scroll to settle on, restoring the desktop pacing on touch.
   rect.height is read live by the bundle, so no bundle patch is needed — the
   taller section simply slows the progression. Plates use React `data-on`
   state (not [data-reveal]), so pinning cannot leave the section blank. */
@media (max-width: 1080px) {
  .narrative-section {
    height: 520vh;
    height: 520svh;
  }
  /* Flex column (not the base grid): grid + align-content:center let the visual
     overlap the rail once content exceeds the viewport; flex items never overlap
     and the visual simply absorbs the leftover height. */
  .narrative-sticky {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    grid-template-columns: none;
    gap: clamp(14px, 2.6svh, 26px);
    padding: max(74px, 9svh) 0 max(28px, 4svh);
  }
  .narrative-copy {
    flex: 0 0 auto;
  }
  .narrative-visual {
    flex: 1 1 auto;
    min-height: 120px;
    width: 100%;
    max-width: none;
    max-height: none;
    aspect-ratio: auto;
  }
}

/* Short viewports (small phones in landcape-ish / older SE): compact the copy so
   the stage image keeps real estate and the index never tucks under the fixed nav. */
@media (max-width: 1080px) and (max-height: 745px) {
  .narrative-sticky {
    gap: clamp(10px, 1.8svh, 18px);
    padding-top: max(66px, 8svh);
  }
  .narrative-index-active {
    font-size: clamp(40px, 11vw, 52px);
  }
  .narrative-rail {
    margin-top: 0;
  }
  .narrative-rail li {
    padding: 7px 0;
  }
}

/* ---- Static ICP fallback --------------------------------------------------
   #ikho-static-icp lives in index.html so the legally-required filing renders
   with JS off / compliance script failed / React not mounted. In that state it
   sits at document bottom as a quiet centered line. Once the React footer
   renders, ikho-cn-compliance.js moves the SAME node into .site-footer, where
   these overrides make it an inline right-aligned footer item. */
#ikho-static-icp {
  display: block;
  padding: 14px 12px;
  text-align: center;
  font-size: 11px;
  color: rgba(244, 244, 241, 0.5);
  text-decoration: none;
}

.site-footer #ikho-static-icp {
  flex-basis: 100%;
  padding: 0;
  text-align: right;
  color: inherit;
}
