/* Prima Merx — static site styles. System fonts only; no downloaded assets. */

:root {
  --navy: #102a3a;
  --navy-raised: #183a4f;
  --ivory: #f6f5f0;
  --white: #ffffff;
  --ink: #102a3a;
  --grey: #54626a;
  --muted: #bfcbd0;
  --teal: #166f72;
  --teal-hover: #125d60;
  --teal-light: #8fd3d1;
  --error: #a1262b;
  --rule-light: #d8d8d0;
  --rule-dark: rgba(191, 203, 208, 0.26);
  --input-border: #7d8a90;

  --font: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --gutter: clamp(20px, 5.8vw, 84px);
  --content-max: 1272px;
  --radius-card: 24px;
  --radius-input: 12px;
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  --float-clearance: 104px;
  --focus: var(--teal);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--ivory);
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* --scrollbar-width is set by site.js only for classic (space-taking)
   scrollbars, so locking the page does not shift the layout. */
html.dialog-open {
  overflow: hidden;
  padding-right: var(--scrollbar-width, 0px);
}

body {
  margin: 0;
  min-width: 320px;
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--ivory);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

h1,
h2,
h3,
p,
figure {
  margin: 0;
}

a {
  color: inherit;
}

button {
  font: inherit;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

#main:focus {
  outline: none;
}

.tone-dark {
  --focus: var(--teal-light);
  background: var(--navy);
  color: var(--white);
}

.tone-light {
  --focus: var(--teal);
  background: var(--ivory);
  color: var(--ink);
}

.container {
  width: 100%;
  max-width: calc(var(--content-max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: max(var(--gutter), env(safe-area-inset-left)) max(var(--gutter), env(safe-area-inset-right));
}

.skip-link {
  position: absolute;
  z-index: 100;
  top: 12px;
  left: 12px;
  padding: 12px 18px;
  border-radius: 999px;
  background: var(--white);
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  transform: translateY(-160%);
}

.skip-link:focus-visible {
  transform: none;
}

/* Type */

.section-index {
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.tone-dark .section-index {
  color: var(--muted);
}

.tone-light .section-index {
  color: var(--grey);
}

.hero-title,
.title-md,
.title-lg,
.title-xl,
.lead,
.panel-title,
.done-title {
  font-weight: 300;
  letter-spacing: -0.02em;
}

.title-md,
.title-lg,
.title-xl {
  text-wrap: balance;
}

/* Each phrase of the headline starts its own line and wraps word by word on
   narrow screens; the size keeps "Opportunities." inside a 320px viewport. */
.hero-title {
  font-size: clamp(2.375rem, 1.45rem + 4.6vw, 6rem);
  line-height: 1;
  letter-spacing: -0.035em;
}

.hero-title .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.line-in {
  display: block;
}

.title-md {
  font-size: clamp(2.125rem, 1.6rem + 2.2vw, 3.5rem);
  line-height: 1.08;
}

.title-lg {
  font-size: clamp(2.5rem, 1.75rem + 3vw, 4.25rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
}

.title-xl {
  font-size: clamp(3.5rem, 2.2rem + 5.4vw, 7.5rem);
  line-height: 1;
  letter-spacing: -0.04em;
}

.lead {
  font-size: clamp(1.375rem, 1.1rem + 1.15vw, 2.25rem);
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.body-text {
  font-size: clamp(1rem, 0.9rem + 0.42vw, 1.25rem);
  line-height: 1.6;
}

.tone-light .body-text {
  color: var(--grey);
}

.tone-dark .body-text {
  color: #e7edef;
}

/* Buttons and links */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  min-height: 56px;
  padding: 0 1.5rem 0 1.75rem;
  border: 0;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.25s ease;
}

.btn-pill {
  border-radius: 999px;
}

.btn-ivory {
  background: var(--ivory);
  color: var(--ink);
}

.btn-ivory:hover {
  background: var(--white);
}

.btn-navy {
  background: var(--navy);
  color: var(--white);
}

.btn-navy:hover {
  background: var(--navy-raised);
}

.btn-block {
  width: 100%;
}

/* While an enquiry is sending the button stays focusable but inactive. */
.btn[aria-disabled="true"] {
  opacity: 0.6;
  cursor: progress;
}

.icon-arrow {
  flex: none;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.25s var(--ease-out);
}

.btn:hover .icon-arrow,
.btn:focus-visible .icon-arrow,
.text-link:hover .icon-arrow,
.text-link:focus-visible .icon-arrow {
  transform: translate(2px, -2px);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 11.5rem;
  min-height: 48px;
  padding-bottom: 2px;
  border-bottom: 1px solid currentColor;
  font-size: clamp(1rem, 0.94rem + 0.25vw, 1.125rem);
  text-decoration: none;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.tone-dark .text-link:hover {
  color: var(--teal-light);
}

/* Floating enquiry widget: the PM mark in an ivory disc, with an "Enquire"
   speech bubble beside it on wider screens. */
.btn-float {
  position: fixed;
  z-index: 40;
  right: max(24px, calc(env(safe-area-inset-right) + 16px));
  bottom: max(24px, calc(env(safe-area-inset-bottom) + 16px));
  display: inline-flex;
  align-items: center;
  gap: 14px;
  color: var(--navy);
  text-decoration: none;
  transition: translate 0.5s var(--ease-out), opacity 0.35s ease;
}

.float-label {
  position: relative;
  padding: 10px 16px;
  border: 1px solid rgba(191, 203, 208, 0.36);
  border-radius: 12px;
  background: var(--navy-raised);
  color: var(--white);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.2;
  box-shadow: 0 12px 30px rgba(6, 20, 29, 0.32);
  transition: transform 0.3s var(--ease-out);
}

.float-label::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -9px;
  width: 0;
  height: 0;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  border-left: 8px solid var(--navy-raised);
  translate: 0 -50%;
}

.float-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border: 1px solid rgba(191, 203, 208, 0.42);
  border-radius: 50%;
  background: var(--navy-raised);
  box-shadow: 0 0 0 1px rgba(16, 42, 58, 0.6), 0 0 26px rgba(143, 211, 209, 0.28), 0 12px 30px rgba(6, 20, 29, 0.32);
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease;
}

/* Pulse ring, animated only when motion is allowed. */
.float-mark::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  border: 1.5px solid transparent;
  pointer-events: none;
}

/* On the dark disc the two-tone mark becomes an ivory monogram. */
.float-mark img {
  display: block;
  width: 28px;
  height: 28px;
  filter: brightness(0) invert(1);
  opacity: 0.96;
}

.btn-float:hover .float-mark {
  transform: scale(1.06);
  box-shadow: 0 0 0 1px rgba(16, 42, 58, 0.6), 0 0 34px rgba(143, 211, 209, 0.4), 0 18px 40px rgba(6, 20, 29, 0.34);
}

.btn-float:hover .float-label {
  transform: translateX(-2px);
}

.btn-float:focus-visible {
  outline: none;
}

.btn-float:focus-visible .float-mark {
  box-shadow: 0 0 0 3px var(--white), 0 0 0 6px var(--teal), 0 14px 34px rgba(6, 20, 29, 0.28);
}

/* Narrow screens: the disc alone; the label stays available to assistive
   technology. */
@media (max-width: 767px) {
  .float-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .float-mark {
    width: 52px;
    height: 52px;
  }
}

html.dialog-open .btn-float {
  visibility: hidden;
}

/* Header */

.site-header {
  position: relative;
  z-index: 2;
}

.header-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 112px;
  padding-top: max(0px, env(safe-area-inset-top));
}

.header-inner::after {
  content: "";
  position: absolute;
  right: max(var(--gutter), env(safe-area-inset-right));
  bottom: 0;
  left: max(var(--gutter), env(safe-area-inset-left));
  border-bottom: 1px solid var(--rule-dark);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 44px;
  text-decoration: none;
}

/* The PM mark sits in an ivory tile so both its navy and teal halves read
   on the navy header. */
.brand-tile {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--ivory);
}

.brand-mark {
  display: block;
  width: 30px;
  height: 30px;
}

.brand-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.brand-name {
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.brand-sub {
  margin-top: 6px;
  font-size: 0.625rem;
  line-height: 1;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--muted);
}

.site-nav ul {
  display: flex;
  gap: clamp(8px, 4.4vw, 72px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 4px;
  font-size: 0.9375rem;
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 4px calc(100% - 8px);
  background-repeat: no-repeat;
  background-size: 0 1px;
  transition: background-size 0.3s var(--ease-out);
}

.site-nav a:hover,
.site-nav a:focus-visible {
  background-size: calc(100% - 8px) 1px;
}

/* Hero */

.hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* The copy layer lets pointer input through to the live object beneath,
   except on the copy itself and its controls. */
.hero-inner {
  position: relative;
  z-index: 1;
  padding-top: clamp(40px, 5vw, 72px);
  pointer-events: none;
}

.hero-copy {
  width: fit-content;
  max-width: 100%;
  pointer-events: auto;
}

.hero-subtitle {
  max-width: 19em;
  margin-top: clamp(24px, 3vw, 44px);
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.75rem);
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.hero-text {
  max-width: 28em;
  margin-top: clamp(16px, 1.6vw, 24px);
  font-size: clamp(1rem, 0.94rem + 0.25vw, 1.125rem);
  line-height: 1.6;
  color: var(--muted);
}

.hero-action {
  margin-top: clamp(32px, 3.4vw, 48px);
}

.hero-media {
  position: relative;
  margin-top: 48px;
  aspect-ratio: 39 / 32;
  overflow: hidden;
  background: var(--navy);
}

.hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 68% 50%;
}

/* Live object canvas (assets/hero-ring.js) sits over the still. */
.hero-gl {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: pan-y;
}

/* Hidden after a lost GPU context: the still beneath is the hero again. */
.hero-gl[hidden] {
  display: none;
}

.hero-gl.is-grabbing {
  cursor: grabbing;
}

.hero-meta {
  position: relative;
  z-index: 1;
  pointer-events: none;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding-block: 22px 26px;
  font-size: 0.75rem;
  color: var(--muted);
}

.hero-meta .section-index {
  display: none;
}

@media (min-width: 640px) {
  .hero-media {
    aspect-ratio: 16 / 9;
  }
}

@media (min-width: 960px) {
  .hero {
    display: flex;
    flex-direction: column;
    min-height: clamp(660px, calc(100svh - 112px), 860px);
  }

  .hero-inner {
    flex: 1;
    padding-top: clamp(48px, 4.6vw, 72px);
  }

  /* Wrap word by word so the headline stays on the navy side of the art. */
  .hero-title {
    max-width: 7.4em;
  }

  .hero-media {
    position: absolute;
    z-index: 0;
    inset: 0 0 0 auto;
    width: 62%;
    margin: 0;
    aspect-ratio: auto;
  }

  .hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg, var(--navy) 0%, rgba(16, 42, 58, 0.72) 14%, rgba(16, 42, 58, 0) 42%),
      linear-gradient(0deg, rgba(16, 42, 58, 0.6) 0%, rgba(16, 42, 58, 0) 26%);
  }

  .hero-img {
    object-position: 60% 50%;
  }

  .hero-meta {
    padding-block: 32px 40px;
  }

  /* Leave room for the fixed Enquire button so it never covers the label. */
  .hero-meta .section-index {
    display: inline;
    margin-right: 168px;
  }
}

/* About */

.about {
  padding-top: clamp(72px, 7.4vw, 112px);
}

.about-inner {
  display: grid;
  gap: 28px;
}

.about-inner > *,
.focus-inner > *,
.philosophy-inner > *,
.contact-inner > * {
  min-width: 0;
}

.about-copy {
  max-width: 760px;
  padding-bottom: clamp(64px, 6.6vw, 104px);
}

.about-copy .lead {
  max-width: 17em;
  margin-top: clamp(24px, 3vw, 48px);
}

.about-copy .body-text {
  max-width: 22em;
  margin-top: clamp(24px, 4vw, 64px);
}

.about {
  padding-bottom: clamp(40px, 4.2vw, 60px);
}

.about-inner::after {
  content: "";
  grid-column: 1 / -1;
  border-bottom: 1px solid var(--rule-light);
}

@media (min-width: 960px) {
  .about-inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 0;
  }

  .about-inner .section-index {
    padding-top: 0.9rem;
  }

  .about-copy .lead {
    max-width: 14.5em;
  }
}

/* Stacked chapters. On wide screens that are also tall enough to hold a
   chapter, each .chapter sticks at the top and the next section slides over
   it with rounded shoulders; --cover (from site.js) dims and eases the
   covered panel back. Short laptop screens flow normally so no copy is ever
   stuck below the fold. Native scrolling throughout. */
@media (min-width: 960px) {
  /* Every section is positioned so later ones paint over earlier pinned
     chapters in document order. */
  main > section {
    position: relative;
  }
}

@media (min-width: 960px) and (min-height: 720px) {
  .chapter {
    position: sticky;
    top: 0;
  }

  .chapter::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 6;
    background: #0b1f2c;
    opacity: calc(var(--cover, 0) * 0.55);
    pointer-events: none;
  }

  .about,
  .region,
  .focus,
  .philosophy,
  .contact {
    border-top-left-radius: 36px;
    border-top-right-radius: 36px;
  }

  .about,
  .philosophy {
    display: grid;
    align-content: center;
    min-height: 100vh;
    min-height: 100svh;
  }
}

/* About ornament: concentric dotted rings turning slowly at the right,
   a quiet echo of the hero object. Wide screens with scripting only. */
/* Positioning comes from the stacking rules (sticky on wide, tall screens;
   relative otherwise) so this must not set it. */
.about {
  overflow: clip;
}

.about-ornament {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: -6vw;
  width: clamp(420px, 44vw, 680px);
  aspect-ratio: 1;
  translate: 0 -50%;
  pointer-events: none;
}

.about-ornament svg {
  width: 100%;
  height: 100%;
}

.orn {
  fill: none;
  stroke: var(--teal);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.28;
  transform-origin: 300px 300px;
}

.orn-1 { stroke-dasharray: 0.1 9; }
.orn-2 { stroke-dasharray: 0.1 12; }
.orn-3 { stroke-dasharray: 0.1 7; }

.orn-dot {
  fill: var(--teal);
  opacity: 0.6;
  transform-origin: 300px 300px;
}

.about-inner {
  position: relative;
  z-index: 1;
}

html:not(.js) .about-ornament {
  display: none;
}

@media (max-width: 959px) {
  .js .about-ornament {
    display: none;
  }
}

/* Region chapter: the dotted globe (assets/globe.js) pinned for a stretch of
   scroll while it turns and settles on Malaysia. The copy that belongs with
   it fades in once the globe has arrived. Without scripting the canvas is
   empty and the paragraph is simply shown. */
.region {
  position: relative;
  min-height: 240vh;
  overflow: clip;
}

.region-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.globe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.region-copy {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: end;
  padding-bottom: clamp(48px, 10vh, 96px);
  pointer-events: none;
}

/* A soft scrim keeps the paragraph legible over the dots. */
.region-copy::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(16, 42, 58, 0.92) 0%, rgba(16, 42, 58, 0.55) 38%, rgba(16, 42, 58, 0) 70%);
  opacity: var(--t, 1);
}

.region-text {
  position: relative;
}

.region-text {
  max-width: 22em;
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.75rem);
  font-weight: 300;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--white);
  text-wrap: balance;
}

@media (min-width: 960px) {
  .region {
    min-height: 320vh;
  }

  .region-copy {
    align-content: center;
    padding-bottom: 0;
  }

  .region-copy::before {
    background: linear-gradient(90deg, rgba(16, 42, 58, 0.94) 0%, rgba(16, 42, 58, 0.72) 30%, rgba(16, 42, 58, 0) 58%);
  }

  .region-text {
    max-width: 16.5em;
  }
}

/* What we do, from 960px with scripting: a pinned stage whose three cards
   travel sideways as the page scrolls. The hairline list remains the layout
   everywhere else. */
@media (min-width: 960px) {
  .js .focus {
    min-height: 220vh;
    padding-block: 0;
  }

  .js .focus-inner {
    position: sticky;
    top: 0;
    display: grid;
    grid-template-columns: none;
    grid-template-rows: auto minmax(0, 1fr);
    gap: 0;
    align-content: start;
    height: 100vh;
    height: 100svh;
    padding-top: clamp(40px, 7vh, 72px);
    padding-bottom: clamp(32px, 6vh, 64px);
    overflow: hidden;
  }

  .js .focus-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    padding-right: 0;
  }

  .js .focus-list {
    display: flex;
    gap: clamp(24px, 2.5vw, 40px);
    align-self: center;
    width: max-content;
    border-bottom: 0;
    translate: calc(var(--x, 0) * var(--shift, 0px) + var(--drag, 0px)) 0;
    will-change: translate;
    cursor: grab;
    touch-action: pan-y;
  }

  .js .focus-list.is-dragging {
    cursor: grabbing;
    user-select: none;
  }

  .js .focus-list.is-dragging .focus-item {
    transition-duration: 0.12s;
  }

  .js .focus-list {
    counter-reset: focus;
  }

  /* Navy panels with a living visual (assets/focus-cards.js), a cursor
     spotlight and a slight tilt toward the pointer. */
  .js .focus-item {
    --focus: var(--teal-light);
    position: relative;
    display: grid;
    grid-template-columns: none;
    grid-template-rows: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: 0;
    width: min(640px, 46vw);
    min-height: min(560px, 60vh);
    padding: clamp(28px, 2.4vw, 40px);
    overflow: hidden;
    border: 1px solid rgba(191, 203, 208, 0.16);
    border-radius: var(--radius-card);
    background: linear-gradient(160deg, #15354a 0%, var(--navy) 55%, #0b1f2c 100%);
    color: var(--white);
    counter-increment: focus;
    transform: perspective(1100px) rotateX(calc(var(--ty, 0) * -5deg)) rotateY(calc(var(--tx, 0) * 6deg));
    transition: transform 0.5s var(--ease-out), border-color 0.3s ease;
  }

  .js .focus-item.is-hover {
    border-color: rgba(143, 211, 209, 0.45);
    transition-duration: 0.18s;
  }

  /* A large, faint index behind each card's content. */
  .js .focus-item::before {
    content: counter(focus, decimal-leading-zero);
    position: absolute;
    right: -0.04em;
    bottom: -0.22em;
    z-index: 0;
    font-size: clamp(9rem, 16vw, 15rem);
    font-weight: 300;
    line-height: 1;
    letter-spacing: -0.06em;
    color: var(--white);
    opacity: 0.045;
    pointer-events: none;
  }

  /* Cursor spotlight. */
  .js .focus-item::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    background: radial-gradient(520px circle at var(--sx, 50%) var(--sy, 50%), rgba(143, 211, 209, 0.16), rgba(143, 211, 209, 0) 45%);
    opacity: 0;
    transition: opacity 0.45s ease;
    pointer-events: none;
  }

  .js .focus-item.is-hover::after {
    opacity: 1;
  }

  .js .focus-item > * {
    position: relative;
    z-index: 1;
  }

  .js .focus-canvas {
    position: absolute;
    z-index: 0;
    left: 0;
    right: 0;
    top: 34%;
    height: 38%;
    width: 100%;
    display: block;
    pointer-events: none;
  }

  .js .focus-num {
    color: var(--teal-light);
  }

  .js .focus-text {
    color: var(--muted);
  }

  .js .focus-title {
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(32px, 6vh, 72px);
    font-size: clamp(2rem, 1.4rem + 1.6vw, 3rem);
  }

  .js .focus-text {
    grid-row: 3;
    align-self: end;
    margin-top: 32px;
  }
}

/* Philosophy: the lead sentence lights up word by word as it rises. The
   words are wrapped by site.js; the text is unchanged. */
.philosophy-copy .lead.fill-words {
  max-width: 13em;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.75rem);
  line-height: 1.14;
  letter-spacing: -0.025em;
}

.fill-words .w {
  opacity: clamp(0.22, calc(var(--fill, 1) * var(--n, 1) - var(--i, 0)), 1);
}

/* Contact: a soft teal aurora behind the headline and a magnetic action. */
.contact {
  position: relative;
  overflow: clip;
}

.contact-inner {
  position: relative;
  z-index: 1;
}

.contact-canvas {
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  top: 6%;
  width: 100%;
  height: 62%;
  opacity: 0.5;
  pointer-events: none;
}

@media (min-width: 960px) {
  .contact::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: -22vw;
    right: -18vw;
    width: 64vw;
    height: 64vw;
    max-width: 980px;
    max-height: 980px;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 50%, rgba(143, 211, 209, 0.5) 0%, rgba(143, 211, 209, 0.18) 32%, rgba(143, 211, 209, 0) 62%);
    filter: blur(30px);
    pointer-events: none;
  }
}

.contact-action .btn {
  transition: translate 0.55s var(--ease-out), background-color 0.2s ease, color 0.2s ease, box-shadow 0.25s ease;
}

/* Film grain: a fixed, non-interactive noise layer from an SVG filter, on
   wide screens with scripting only. */
.defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 40;
  opacity: 0.07;
  mix-blend-mode: soft-light;
  filter: url(#grain);
  pointer-events: none;
}

html:not(.js) .grain {
  display: none;
}

@media (max-width: 959px) {
  .js .grain {
    display: none;
  }
}

/* Chapter rail: a fixed index on wide screens that counts the chapters as
   they pass. Decorative; it exists only once site.js can drive it. */
.chapter-rail {
  position: fixed;
  z-index: 20;
  left: clamp(16px, 1.6vw, 28px);
  top: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  transform: translateY(-50%);
  font-size: 0.6875rem;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey);
  pointer-events: none;
  transition: color 0.35s ease;
}

html:not(.js) .chapter-rail {
  display: none;
}

@media (max-width: 1099px) {
  .js .chapter-rail {
    display: none;
  }
}

.chapter-rail.on-dark {
  color: var(--muted);
}

.chapter-rail.is-quiet {
  opacity: 0.35;
}

.rail-index {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.rail-num {
  display: block;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.06em;
}

.rail-total {
  font-size: 0.625rem;
  opacity: 0.55;
}

.rail-track {
  position: relative;
  width: 1px;
  height: 88px;
  background: color-mix(in srgb, currentColor 28%, transparent);
}

.rail-fill {
  position: absolute;
  inset: 0;
  background: currentColor;
  transform-origin: top;
  transform: scaleY(var(--page, 0));
}

.rail-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
}

/* What we do: a numbered list separated by hairlines, not cards. */

.focus {
  padding-block: clamp(56px, 6vw, 88px) clamp(72px, 7vw, 112px);
}

.focus-inner {
  display: grid;
  gap: clamp(32px, 4vw, 48px);
}

.focus-head .title-md {
  max-width: 9em;
  margin-top: clamp(20px, 2.4vw, 32px);
}

.focus-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--rule-light);
}

.focus-item {
  display: grid;
  gap: 12px;
  padding-block: clamp(24px, 2.6vw, 36px);
  border-top: 1px solid var(--rule-light);
}

.focus-title {
  display: flex;
  align-items: baseline;
  gap: 0.65em;
  font-size: clamp(1.625rem, 1.3rem + 1.2vw, 2.5rem);
  font-weight: 300;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.focus-num {
  flex: none;
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--teal);
}

.focus-text {
  max-width: 26em;
  font-size: clamp(1rem, 0.94rem + 0.25vw, 1.125rem);
  line-height: 1.6;
  color: var(--grey);
}

@media (min-width: 768px) {
  .focus-item {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 32px;
    align-items: baseline;
  }
}

@media (min-width: 960px) {
  .focus-inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 0;
  }

  .focus-head .section-index {
    padding-top: 0.9rem;
  }

  .focus-head {
    padding-right: 40px;
  }
}

/* Philosophy */

.philosophy {
  padding-block: clamp(72px, 7vw, 100px);
}

.philosophy-inner {
  display: grid;
  gap: 48px;
  align-items: center;
}

.image-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-card);
  aspect-ratio: 536 / 430;
  background: #0b1f2c;
}

.image-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 74% 56%;
}

.philosophy-copy .title-lg {
  max-width: 9em;
  margin-top: clamp(20px, 3vw, 40px);
}

.philosophy-copy .lead {
  max-width: 16em;
  margin-top: clamp(28px, 4vw, 56px);
}

.philosophy-copy .body-text {
  max-width: 23em;
  margin-top: clamp(20px, 2.4vw, 32px);
}

@media (max-width: 639px) {
  .image-card {
    display: none;
  }
}

@media (min-width: 960px) {
  .philosophy-inner {
    grid-template-columns: minmax(0, 536fr) minmax(0, 620fr);
    gap: clamp(56px, 8vw, 116px);
  }
}

/* Contact */

.contact {
  padding-top: clamp(64px, 5.4vw, 80px);
}

.contact-row {
  display: grid;
  gap: 40px;
  margin-top: clamp(20px, 2vw, 28px);
  padding-bottom: clamp(40px, 3.4vw, 48px);
}

.contact-row .body-text {
  max-width: 30em;
  margin-top: clamp(20px, 2.2vw, 32px);
}

.contact-action .btn {
  width: 100%;
}

.noscript-note {
  max-width: 36em;
  padding-bottom: 40px;
  color: var(--grey);
}

@media (min-width: 640px) {
  .contact-action .btn {
    width: auto;
    min-width: 17.5rem;
  }
}

@media (min-width: 960px) {
  .contact-row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }

  .contact-action {
    padding-top: 0.6em;
  }
}

/* Footer */

.site-footer {
  font-size: 0.8125rem;
}

.footer-inner .footer-brand {
  display: inline-block;
  min-width: 0;
  min-height: 0;
  margin: 0 0 14px;
  border-radius: 8px;
  background-image: none;
}

.footer-logo {
  width: 200px;
  height: auto;
}

.footer-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding-top: 18px;
  padding-bottom: calc(var(--float-clearance) + env(safe-area-inset-bottom));
}

.footer-inner::before {
  content: "";
  position: absolute;
  top: 0;
  right: max(var(--gutter), env(safe-area-inset-right));
  left: max(var(--gutter), env(safe-area-inset-left));
  border-top: 1px solid var(--rule-light);
}

.footer-inner p,
.footer-inner a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.footer-inner a {
  min-width: 44px;
}

.footer-id {
  flex-wrap: wrap;
  column-gap: 16px;
}

.footer-geo {
  color: var(--grey);
}

.footer-inner a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 calc(100% - 10px);
  background-repeat: no-repeat;
  background-size: 0 1px;
  transition: background-size 0.3s var(--ease-out);
}

.footer-inner a:hover,
.footer-inner a:focus-visible {
  background-size: 100% 1px;
}

@media (min-width: 768px) {
  .footer-inner {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding-top: 12px;
  }

  .footer-inner a {
    margin-right: 22px;
  }
}

/* Enquiry dialog */

.enquiry {
  position: fixed;
  inset: auto max(24px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) auto;
  width: min(420px, calc(100vw - 48px));
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: visible;
  background: transparent;
  color: var(--ink);
  --focus: var(--teal);
}

.enquiry::backdrop {
  background: rgba(8, 22, 31, 0.56);
}

.panel {
  max-height: calc(var(--vvh, 100dvh) - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-card);
  background: var(--white);
  box-shadow: 0 30px 80px rgba(6, 20, 29, 0.36);
}

.panel-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 24px 20px 16px 28px;
  background: var(--white);
  border-bottom: 1px solid #ebebe6;
}

.panel-title {
  font-size: 1.75rem;
  line-height: 1.15;
}

.panel-title:focus {
  outline: none;
}

.panel-title:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 4px;
  border-radius: 4px;
}

.panel-close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.panel-close:hover {
  background: #eef1f0;
}

.panel-close svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}

.demo-note {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--grey);
}

.demo-note[hidden] {
  display: none;
}

.demo-note::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--teal);
}

.panel-body {
  padding: 20px 28px 28px;
}

.field + .field {
  margin-top: 20px;
}

.field label {
  display: block;
  margin-bottom: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.3;
}

.field-hint {
  font-weight: 400;
  color: var(--grey);
}

.field input,
.field textarea {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--input-border);
  border-radius: var(--radius-input);
  background: #f9f9f7;
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.field textarea {
  min-height: 128px;
  resize: vertical;
}

.field input:hover,
.field textarea:hover {
  border-color: var(--ink);
}

.field input:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-color: var(--ink);
  background: var(--white);
}

.field [aria-invalid="true"] {
  border-color: var(--error);
  box-shadow: inset 0 0 0 1px var(--error);
}

.field-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 8px;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--error);
}

.field-error::before {
  content: "!" / "";
  flex: none;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--error);
  color: var(--white);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

.field-error[hidden] {
  display: none;
}

.field-hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  margin-top: 24px;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--error);
}

.form-status:empty {
  margin-top: 0;
}

.form-note {
  margin-top: 20px;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--grey);
}

.form-status:not(:empty) + .form-note {
  margin-top: 8px;
}

.enquiry-form .btn {
  margin-top: 20px;
}

.form-privacy {
  margin-top: 8px;
}

.form-privacy a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.875rem;
  color: var(--teal);
  text-underline-offset: 3px;
}

.enquiry-done {
  padding-top: 12px;
}

.enquiry-done[hidden] {
  display: none;
}

.done-title {
  font-size: 1.625rem;
  line-height: 1.2;
}

.done-title:focus {
  outline: none;
}

.done-title:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 4px;
  border-radius: 4px;
}

.enquiry-done p {
  max-width: 24em;
  margin-top: 16px;
  color: var(--grey);
}

.enquiry-done h3 + p {
  margin-top: 20px;
}

.enquiry-done p + p {
  margin-top: 4px;
}

.enquiry-done .btn {
  margin-top: 40px;
}

/* Mobile sheet: full width, internal scrolling, safe areas. */
@media (max-width: 639px) {
  .enquiry {
    inset: auto 0 0 0;
    width: 100%;
  }

  .panel {
    max-height: calc(var(--vvh, 100dvh) - max(12px, env(safe-area-inset-top)));
    border-radius: var(--radius-card) var(--radius-card) 0 0;
  }

  .panel-head {
    padding: 18px max(12px, env(safe-area-inset-right)) 14px max(20px, env(safe-area-inset-left));
  }

  .panel-title {
    font-size: 1.5rem;
  }

  .panel-body {
    padding: 16px max(20px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
  }
}

/* Short viewports (landscape phones, zoomed desktop): keep the panel inside the visible area. */
@media (max-height: 520px) and (min-width: 640px) {
  .enquiry {
    inset: 12px max(12px, env(safe-area-inset-right)) 12px auto;
  }

  .panel {
    max-height: calc(var(--vvh, 100dvh) - 24px);
  }
}

/* Privacy draft page */

.privacy-main {
  padding-block: clamp(56px, 7vw, 104px) clamp(56px, 6vw, 96px);
}

.privacy-main .container > * {
  max-width: 760px;
}

.privacy-main h1 {
  margin-top: 20px;
}

.privacy-main .lead {
  margin-top: clamp(32px, 4vw, 56px);
}

.privacy-main h2 {
  margin-top: clamp(40px, 4.4vw, 64px);
  font-size: clamp(1.375rem, 1.2rem + 0.6vw, 1.75rem);
  font-weight: 400;
  letter-spacing: -0.01em;
}

.privacy-main .proposed-wording {
  margin: 20px 0 0;
  padding-left: 20px;
  border-left: 2px solid var(--teal);
}

.privacy-main ul {
  margin: 16px 0 0;
  padding-left: 1.2em;
  color: var(--grey);
}

.privacy-main li + li {
  margin-top: 6px;
}

.privacy-main .body-text + .body-text {
  margin-top: 16px;
}

.back-link {
  margin-top: clamp(40px, 4.4vw, 64px);
}

.site-footer.privacy-footer .footer-inner {
  padding-bottom: calc(40px + env(safe-area-inset-bottom));
}

@media (max-width: 379px) {
  .site-nav ul {
    gap: 8px 14px;
    flex-wrap: wrap;
  }

  .site-nav a {
    font-size: 0.875rem;
  }
}

/* Mobile header: name above a visible row of links. */
@media (max-width: 767px) {
  .header-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    min-height: 0;
    padding-top: max(20px, env(safe-area-inset-top));
    padding-bottom: 8px;
  }

  .site-nav ul {
    gap: clamp(16px, 8vw, 48px);
    margin-left: -4px;
  }
}

/* Motion — only when the visitor has no reduced-motion preference. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero-enter {
    animation: rise 0.42s var(--ease-out) both;
  }

  .js .hero-enter-2 {
    animation-delay: 70ms;
  }

  .js .hero-enter-3 {
    animation-delay: 150ms;
  }

  .js .hero-enter-4 {
    animation-delay: 230ms;
  }

  .js .hero-img {
    animation: fade-in 0.9s ease-out both, ken-burns 30s ease-in-out infinite alternate;
  }

  .js .line-in {
    animation: line-up 1.1s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  .js .line:nth-child(2) .line-in {
    animation-delay: 110ms;
  }

  .js .region-copy {
    --t: clamp(0, calc((var(--p, 1) - 0.7) / 0.16), 1);
  }

  .js .region-text {
    opacity: var(--t);
    translate: 0 calc((1 - var(--t)) * 28px);
  }

  .js .philosophy {
    --fill: clamp(0, calc((var(--p, 1) - 0.16) / 0.3), 1);
  }

  .contact::before {
    animation: aurora 18s ease-in-out infinite alternate;
  }

  .float-mark::before {
    border-color: var(--teal-light);
    animation: pulse 2.8s ease-out infinite;
  }

  .orn-1 { animation: turn 110s linear infinite; }
  .orn-2 { animation: turn 80s linear infinite reverse; }
  .orn-3 { animation: turn 60s linear infinite; }
  .orn-dot { animation: turn 110s linear infinite; }

  .reveal-ready [data-reveal] {
    transition:
      opacity 0.6s var(--ease-out) var(--reveal-delay, 0ms),
      transform 0.6s var(--ease-out) var(--reveal-delay, 0ms);
  }

  .reveal-ready [data-reveal]:not(.is-visible) {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
  }

  .reveal-ready [data-reveal="mask"] {
    transition: clip-path 0.7s var(--ease-out) var(--reveal-delay, 0ms);
  }

  .reveal-ready [data-reveal="mask"]:not(.is-visible) {
    opacity: 1;
    transform: none;
    clip-path: inset(9% 9% 9% 9% round var(--radius-card));
  }

  .reveal-ready [data-reveal="mask"] img {
    transition: transform 1.1s var(--ease-out) var(--reveal-delay, 0ms);
  }

  .reveal-ready [data-reveal="mask"]:not(.is-visible) img {
    transform: scale(1.08);
  }

  .enquiry[open] .panel {
    animation: panel-in 0.28s var(--ease-out);
  }

  .enquiry[open]::backdrop {
    animation: fade-in 0.28s ease-out;
  }
}

/* Scroll-driven motion. site.js writes --p (0 to 1) on [data-progress]
   sections from native scroll position; nothing here intercepts scrolling. */
@media (prefers-reduced-motion: no-preference) and (min-width: 960px) and (min-height: 720px) {
  /* Hero exit: the artwork tucks into a rounded card and drifts, the copy
     lifts away a little faster than the page. */
  .js .hero-media {
    transform: translate3d(0, calc(var(--p, 0) * 9vh), 0) scale(calc(1 - var(--p, 0) * 0.1));
    transform-origin: 70% 60%;
    border-radius: calc(var(--p, 0) * 40px);
    will-change: transform;
  }

  .js .hero-img,
  .js .hero-gl {
    translate: 0 calc(var(--p, 0) * -5vh);
  }

  .chapter {
    transform: scale(calc(1 - var(--cover, 0) * 0.04));
    transform-origin: 50% 30%;
    border-radius: calc(var(--cover, 0) * 36px);
  }

  .js .focus-list {
    --x: var(--p, 1);
  }

  .js .hero-inner {
    transform: translate3d(0, calc(var(--p, 0) * -7vh), 0);
    opacity: calc(1 - var(--p, 0) * 1.15);
  }

  .js .hero-meta {
    opacity: calc(1 - var(--p, 0) * 2.5);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .rail-fill {
    transition: transform 0.15s linear;
  }

  .rail-num.is-switching {
    animation: rail-swap 0.36s var(--ease-out);
  }
}

@keyframes line-up {
  from {
    transform: translate3d(0, 112%, 0);
  }
}

@keyframes ken-burns {
  from {
    transform: scale(1.06) translate(0, 0);
  }

  to {
    transform: scale(1.16) translate(-2.5%, 1.5%);
  }
}

@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 0.75;
  }

  70% {
    transform: scale(1.75);
    opacity: 0;
  }

  100% {
    transform: scale(1.75);
    opacity: 0;
  }
}

@keyframes turn {
  to {
    transform: rotate(360deg);
  }
}

@keyframes aurora {
  from {
    translate: -5% 6%;
  }

  to {
    translate: 6% -5%;
  }
}

@keyframes rail-swap {
  from {
    opacity: 0;
    transform: translate3d(0, 8px, 0);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@keyframes panel-in {
  from {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
  }
}

/* Without scripting the globe canvas is empty: keep that chapter one screen. */
html:not(.js) .region {
  min-height: auto;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* No pinned stretches with nothing moving: the globe chapter is one
     screen resting on Malaysia; the card row is a native horizontal
     scroller so every card stays reachable. */
  .region {
    min-height: auto;
  }

  .region-stage {
    position: relative;
  }

  .js .focus {
    min-height: auto;
  }

  .js .focus-inner {
    position: static;
    height: auto;
    overflow: visible;
  }

  .js .focus-list {
    width: auto;
    overflow-x: auto;
    padding-bottom: 12px;
    translate: none;
    cursor: auto;
    touch-action: auto;
    user-select: auto;
    scrollbar-width: thin;
  }

  .js .focus-item {
    flex: none;
  }
}

@media (forced-colors: active) {
  .btn,
  .panel-close,
  .field input,
  .field textarea,
  .float-mark,
  .float-label,
  .brand-tile {
    border: 1px solid CanvasText;
  }

  .float-mark img {
    filter: none;
  }

  .btn-float:focus-visible .float-mark {
    outline: 3px solid CanvasText;
    outline-offset: 3px;
  }
}
