@font-face {
  font-family: 'PRISMORA Sans';
  src: url('../assets/fonts/prismora-light.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'PRISMORA Sans';
  src: url('../assets/fonts/prismora-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'PRISMORA Sans';
  src: url('../assets/fonts/prismora-medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'PRISMORA Sans';
  src: url('../assets/fonts/prismora-bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'PRISMORA Sans';
  src: url('../assets/fonts/prismora-black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

html {
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

html::-webkit-scrollbar {
  display: none;
}

body {
  margin: 0;
  background: var(--c-white);
  color: var(--c-black);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: 1.556; /* 28 / 18, measured on the About paragraph */
  overflow-x: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/*
 * <picture> only exists to let the browser pick a source; it should not add a
 * box that breaks `height: 100%` on the image. Wrappers that *are* the layout
 * box always carry a class (.stage__layer, .about__fan, …).
 */
picture:not([class]) {
  display: contents;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 100;
  padding: 10px 20px;
  background: var(--c-black);
  color: var(--c-white);
  font-size: var(--fs-note);
  transform: translate(-50%, -110%);
  transition: transform var(--dur) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translate(-50%, 0);
}

.container {
  width: min(var(--page-max-width), 100% - var(--page-gutter) * 2);
  margin-inline: auto;
}

.section {
  position: relative;
  isolation: isolate;
}

/* full-bleed background image layer for a section */
.section__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

.section__bg picture {
  display: block;
  width: 100%;
  height: 100%;
}

.section__bg img,
.section__bg video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

.text-red {
  color: var(--c-red);
}

/* ---- reveal-on-scroll (opacity + transform only, per spec §26) ---- */

/*
 * The offset uses the standalone `translate` property, not `transform`: a revealed
 * element is often also a centred stage layer, and `transform` is a single slot —
 * whichever rule won would silently drop the other's `translateX(-50%)`.
 */
.reveal {
  opacity: 0;
  translate: 0 30px;
  transition:
    opacity 700ms var(--ease-out),
    translate 700ms var(--ease-out);
  will-change: opacity, translate;
}

.reveal.is-visible {
  opacity: 1;
  translate: none;
}

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .reveal {
    opacity: 1;
    translate: none;
    transition: none;
  }
}

/*
 * Fixed-ratio composition stage.
 * Sections that are pixel compositions in the mockup (业务板块 / 全球布局 / 创意科技)
 * keep their 1920-based geometry by scaling every child through --u, so the whole
 * arrangement stays proportional at any viewport width.
 */
/*
 * `--sw` / `--sh` are the mockup dimensions of the composition; `--u` is therefore
 * exactly one design pixel, and children position themselves with the raw numbers
 * read off the mockup (`--x` / `--y` / `--w`).
 *
 * `--u` resolves inside the children, not on .stage itself — `cqw` always refers to
 * the nearest *ancestor* container — so .stage must never consume it.
 */
.stage {
  container-type: inline-size;
  position: relative;
  width: 100%;
  aspect-ratio: var(--sw) / var(--sh);
  --u: calc(100cqw / var(--sw));
}

/*
 * `--dy` lets a stage that was re-exported taller keep every coordinate as it was
 * measured and state the shift once, instead of restating it on each layer.
 */
.stage__layer {
  position: absolute;
  display: block;
  left: calc(var(--x) * var(--u));
  top: calc((var(--y) + var(--dy, 0)) * var(--u));
  width: calc(var(--w, 0) * var(--u));
}

/* opt out of the width rule for text layers that size themselves */
.stage__layer--auto {
  width: auto;
}

/*
 * A stage whose children are laid out in flow rather than at coordinates: it keeps
 * `--u` (so every size is still expressed in design pixels and scales with the
 * viewport) but drops the ratio box, letting the content set the height. When the
 * flow arithmetic is right the resulting height equals the mockup's, which makes the
 * screenshot's total height a free correctness check.
 */
.stage--flow {
  aspect-ratio: auto;
}

/*
 * Horizontally centred text layer: --x is ignored, --y still applies. --dx is an
 * optional nudge in design pixels, for mockup text that is hand-placed rather
 * than truly centred.
 */
.stage__layer--center {
  left: 50%;
  width: auto;
  transform: translateX(calc(-50% + var(--dx, 0) * var(--u)));
}

/*
 * A composition that cannot survive a phone width carries .stage--reflow: below
 * the breakpoint the ratio box is dropped and the layers rejoin the normal flow,
 * so each section only has to restate its own stacking and spacing. Layers that
 * are pure decoration opt out with .stage__layer--decor.
 */
@media (max-width: 900px) {
  .stage--reflow {
    container-type: normal;
    aspect-ratio: auto;
    --u: 1px;
  }

  .stage--reflow > .stage__layer {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    transform: none;
  }

  .stage--reflow > .stage__layer--decor {
    display: none;
  }
}

.stage__layer img {
  display: block;
  width: 100%;
  height: auto;
}
