/* Ping Rui portfolio — career narrative layered into the procedural Sylva world. */
:root {
  --pr-font-sans: Lexend, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  --pr-ink: rgba(248, 250, 245, .96);
  --pr-muted: rgba(241, 245, 237, .62);
  --pr-accent: #edf3ee;
  --pr-ease: cubic-bezier(.2, .78, .2, 1);
}

body[data-design-version="2"] { font-family: var(--pr-font-sans); }

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body[data-design-version="2"] .profile-signature {
  position: absolute;
  z-index: 12;
  top: calc(132 * var(--u));
  left: calc(52 * var(--u));
  display: grid;
  grid-template-columns: auto auto;
  align-items: baseline;
  gap: calc(8 * var(--u)) calc(22 * var(--u));
  color: var(--pr-ink);
  pointer-events: none;
}

.profile-index {
  grid-column: 1 / -1;
  color: rgba(255, 255, 255, .96);
  font-size: max(24px, calc(30 * var(--u)));
  font-weight: 620;
  line-height: 1;
  letter-spacing: -.035em;
  text-shadow: 0 calc(3 * var(--u)) calc(18 * var(--u)) rgba(12, 17, 13, .2);
}

.profile-name { color: rgba(255, 255, 255, .84); font-size: max(10px, calc(11 * var(--u))); font-weight: 560; letter-spacing: .025em; }
.profile-role { color: rgba(255, 255, 255, .58); font-size: max(8px, calc(8.5 * var(--u))); font-weight: 500; letter-spacing: .12em; }

.hero-copy {
  position: absolute;
  z-index: 12;
  top: calc(210 * var(--u));
  right: auto;
  left: calc(52 * var(--u));
  width: calc(440 * var(--u));
}

body[data-design-version="2"] .headline {
  position: static;
  width: 100%;
  max-width: none;
  margin: 0;
  color: rgba(248, 250, 245, .86);
  font-size: max(20px, calc(24 * var(--u)));
  font-weight: 520;
  line-height: calc(30 * var(--u));
  letter-spacing: calc(-.6 * var(--u));
}

body[data-design-version="2"] .headline > span { display: block; white-space: nowrap; }

.capability-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: calc(430 * var(--u));
  margin: calc(15 * var(--u)) 0 0;
  padding: 0;
  gap: calc(10 * var(--u)) calc(20 * var(--u));
  list-style: none;
}

.capability-list li {
  display: grid;
  grid-template-columns: calc(18 * var(--u)) minmax(0, 1fr);
  gap: calc(8 * var(--u));
  padding-top: calc(8 * var(--u));
  border-top: 1px solid rgba(255, 255, 255, .16);
}

.capability-list li > span { color: rgba(255, 255, 255, .42); font-size: max(7px, calc(7 * var(--u))); font-weight: 600; letter-spacing: .12em; }
.capability-list strong { display: block; color: rgba(255, 255, 255, .88); font-size: max(10px, calc(10.5 * var(--u))); font-weight: 560; line-height: 1.35; }
.capability-list small { display: block; margin-top: calc(4 * var(--u)); color: rgba(255, 255, 255, .48); font-size: max(7px, calc(7.2 * var(--u))); line-height: 1.45; white-space: nowrap; }

body[data-design-version="2"] .lede {
  position: static;
  width: calc(430 * var(--u));
  margin: calc(24 * var(--u)) 0 0;
  color: var(--pr-muted);
  font-size: calc(12 * var(--u));
  line-height: 1.75;
}

@media (min-width: 761px) {
  body[data-design-version="2"] .lede { display: none; }
}

.hero-actions {
  display: none;
}

.hero-primary {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  width: calc(148 * var(--u));
  height: calc(40 * var(--u));
  padding: 0 calc(14 * var(--u));
  border: 1px solid rgba(255, 255,255, .25);
  border-radius: calc(12 * var(--u));
  color: #20261e;
  background: rgba(244, 247, 239, .94);
  box-shadow: 0 calc(10 * var(--u)) calc(32 * var(--u)) rgba(14, 18, 13, .16);
  cursor: pointer;
  font-size: calc(9 * var(--u));
  font-weight: 550;
  transition: opacity .35s ease, transform .35s var(--pr-ease), background .3s ease, box-shadow .35s ease;
}

.hero-primary span { font-size: calc(14 * var(--u)); }
.hero-primary:hover { transform: translateY(calc(-2 * var(--u))); background: #fff; box-shadow: 0 calc(14 * var(--u)) calc(40 * var(--u)) rgba(14, 18, 13, .22); }
.hero-primary:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }
body:not([data-season="winter"]) .hero-primary { opacity: 0; pointer-events: none; transform: translateY(calc(8 * var(--u))); }

.hero-hint {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--u));
  color: rgba(255, 255, 255, .48);
  font-size: calc(8.5 * var(--u));
  letter-spacing: .04em;
}

.hero-hint i { display: block; width: calc(28 * var(--u)); height: 1px; background: rgba(255, 255, 255, .28); }

/* Fixed identity/capabilities sit left; the active career chapter changes on the right. */
.career-caption {
  position: absolute;
  z-index: 12;
  top: calc(132 * var(--u));
  right: calc(52 * var(--u));
  left: auto;
  width: calc(430 * var(--u));
  padding-left: calc(14 * var(--u));
  border-left: 1px solid rgba(255, 255, 255, .24);
  color: var(--pr-ink);
  pointer-events: none;
}

.career-caption::after {
  content: "";
  position: absolute;
  top: 0;
  left: -1px;
  width: 1px;
  height: 100%;
  background: linear-gradient(var(--pr-accent), rgba(255, 255, 255, 0));
  transform: scaleY(.42);
  transform-origin: top;
  transition: transform .65s var(--pr-ease);
}

body.is-chapter-changing .career-caption::after { transform: scaleY(1); }

.caption-index,
.caption-period {
  display: block;
  color: rgba(255, 255, 255, .58);
  font-size: max(7px, calc(7.5 * var(--u)));
  font-weight: 600;
  letter-spacing: .15em;
}

.caption-index { display: block; }

.caption-company {
  margin: calc(10 * var(--u)) 0 0;
  font-size: max(17px, calc(18 * var(--u)));
  font-weight: 500;
  line-height: 1.24;
  letter-spacing: -.035em;
}

.caption-role { margin: calc(5 * var(--u)) 0 0; color: rgba(255, 255, 255, .64); font-size: max(8px, calc(8.5 * var(--u))); line-height: 1.5; }
.caption-copy { display: block; width: calc(400 * var(--u)); margin: calc(11 * var(--u)) 0 0; color: rgba(255, 255, 255, .76); font-size: max(9px, calc(9.5 * var(--u))); line-height: 1.62; }

.caption-evidence {
  display: block;
  margin-top: calc(8 * var(--u));
}

.caption-evidence span { display: none; }
.caption-evidence strong { color: color-mix(in srgb, var(--pr-accent) 78%, white); font-size: calc(8 * var(--u)); font-weight: 520; line-height: 1.5; }
.caption-period { margin-top: calc(8 * var(--u)); }

.career-map-label {
  position: absolute;
  z-index: 8;
  bottom: calc(28 * var(--u));
  left: calc(52 * var(--u));
  display: grid;
  gap: calc(5 * var(--u));
  color: var(--pr-ink);
  pointer-events: none;
}

.career-map-label span { color: rgba(255, 255, 255, .38); font-size: calc(7 * var(--u)); letter-spacing: .18em; }
.career-map-label strong { color: rgba(255, 255, 255, .72); font-size: calc(9 * var(--u)); font-weight: 500; letter-spacing: .04em; }

/* Labels are projected from actual Three.js joints. The button is only the
   accessible interaction surface; visually, the joint belongs to the root. */
.career-nodes { position: absolute; z-index: 10; inset: 0; pointer-events: none; }

body[data-design-version="2"] .career-node {
  position: absolute;
  top: var(--screen-y, 70%);
  left: var(--screen-x, 50%);
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  color: var(--pr-ink);
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
  transform: translate(-.5px, -.5px);
}

body[data-design-version="2"] .career-node:nth-child(1) { --screen-x: calc(326 * var(--u)); --screen-y: calc(644 * var(--u)); }
body[data-design-version="2"] .career-node:nth-child(2) { --screen-x: calc(642 * var(--u)); --screen-y: calc(694 * var(--u)); }
body[data-design-version="2"] .career-node:nth-child(3) { --screen-x: calc(962 * var(--u)); --screen-y: calc(674 * var(--u)); }
body[data-design-version="2"] .career-node:nth-child(4) { --screen-x: calc(1248 * var(--u)); --screen-y: calc(726 * var(--u)); }

body[data-design-version="2"] .career-node::before {
  content: "";
  position: absolute;
  inset: calc(-22 * var(--u));
  min-width: 44px;
  min-height: 44px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--pr-accent) 32%, transparent), transparent 68%);
  opacity: 0;
  transform: scale(.72);
  transition: opacity .45s ease, transform .7s var(--pr-ease);
}

body[data-design-version="2"] .career-node::after {
  content: "";
  position: absolute;
  top: calc(-5 * var(--u));
  left: calc(-5 * var(--u));
  width: calc(10 * var(--u));
  height: calc(10 * var(--u));
  border: 1px solid transparent;
  border-radius: calc(2 * var(--u));
  opacity: 0;
  transition: opacity .25s ease, transform .35s var(--pr-ease), border-color .25s ease;
}

.career-stem {
  position: absolute;
  bottom: calc(7 * var(--u));
  left: calc(4 * var(--u));
  width: calc(42 * var(--u));
  height: 1px;
  opacity: .38;
  background: linear-gradient(90deg, var(--pr-accent), rgba(255, 255, 255, .08));
  transform: rotate(-54deg);
  transform-origin: left center;
  transition: width .4s var(--pr-ease), opacity .3s ease;
}

.career-company {
  position: absolute;
  left: calc(30 * var(--u));
  bottom: calc(38 * var(--u));
  display: grid;
  min-width: calc(126 * var(--u));
  gap: calc(3 * var(--u));
  text-align: left;
  text-shadow: 0 2px 12px rgba(10, 14, 8, .48);
  opacity: .58;
  transform: translateY(calc(4 * var(--u)));
  transition: opacity .32s ease, transform .42s var(--pr-ease);
}

.career-company > span { color: rgba(255, 255, 255, .52); font-size: calc(6.8 * var(--u)); font-weight: 600; letter-spacing: .13em; white-space: nowrap; }
.career-company strong,
.career-company em { display: block; color: rgba(255, 255, 255, .96); font-size: calc(13 * var(--u)); font-style: normal; font-weight: 560; line-height: 1.25; white-space: nowrap; }
.career-company em { color: rgba(255, 255, 255, .64); font-size: calc(8.5 * var(--u)); }
.career-company b { display: block; color: rgba(255, 255, 255, .72); font-size: calc(8 * var(--u)); font-weight: 520; line-height: 1.35; white-space: nowrap; }
.career-company small { color: rgba(255, 255, 255, .42); font-size: calc(6.8 * var(--u)); letter-spacing: .05em; white-space: nowrap; }

body[data-design-version="2"] .career-node:hover .career-company,
body[data-design-version="2"] .career-node.is-active .career-company,
body[data-design-version="2"] .career-node:focus-visible .career-company { opacity: 1; transform: none; }

body[data-design-version="2"] .career-node.is-active::before {
  opacity: .78;
  transform: scale(1.42);
  animation: pr-joint-breathe 3.8s ease-in-out infinite;
}

body[data-design-version="2"] .career-node.is-active .career-company { transform: translateY(calc(-3 * var(--u))); }
body[data-design-version="2"] .career-node.is-active .career-company strong { font-size: calc(14 * var(--u)); }
body.is-chapter-changing .career-node.is-active .career-company { animation: pr-company-arrive .66s .16s var(--pr-ease) both; }
body.is-chapter-changing .career-node.is-active .career-stem { animation: pr-stem-grow .72s var(--pr-ease) both; }

@keyframes pr-joint-breathe {
  0%, 100% { opacity: .54; transform: scale(1.16); }
  50% { opacity: .84; transform: scale(1.52); }
}

@keyframes pr-company-arrive {
  from { opacity: 0; transform: translateY(calc(8 * var(--u))); filter: blur(3px); }
  to { opacity: 1; transform: translateY(calc(-3 * var(--u))); filter: none; }
}

@keyframes pr-stem-grow {
  from { width: calc(5 * var(--u)); opacity: .12; }
  to { width: calc(50 * var(--u)); opacity: .84; }
}

body[data-design-version="2"] .career-node:hover .career-stem,
body[data-design-version="2"] .career-node.is-active .career-stem,
body[data-design-version="2"] .career-node:focus-visible .career-stem { width: calc(50 * var(--u)); opacity: .84; }

body[data-design-version="2"] .career-node:hover::after,
body[data-design-version="2"] .career-node.is-active::after,
body[data-design-version="2"] .career-node:focus-visible::after { border-color: color-mix(in srgb, var(--pr-accent) 72%, transparent); opacity: .76; transform: rotate(45deg) scale(1.18); }

body[data-design-version="2"] .career-node:focus-visible { outline: none; }

.season-particles { position: absolute; z-index: 6; inset: 0; width: 100%; height: 100%; pointer-events: none; }
body, #scene { transition: background 1.1s ease, filter 1.1s ease; }

/* Each season owns one static atmosphere plate. Only opacity changes during a
   chapter switch, so the live WebGL tree keeps its material and frame rate. */
.season-backgrounds {
  position: absolute;
  z-index: 0;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.season-background {
  position: absolute;
  inset: -2%;
  opacity: 0;
  transform: scale(1.02);
  background-position: 50% 50%;
  background-size: cover;
  background-repeat: no-repeat;
  transition: opacity 1.15s var(--pr-ease);
}

.season-background--spring { background-color: #24232f; background-image: url("/images/spring-misty-sakura-garden-v1.jpg"); }
.season-background--summer { background-color: #17282a; background-image: url("/images/summer-misty-garden-v1.jpg"); }
.season-background--autumn { background-color: #2a2221; background-image: url("/images/autumn-misty-garden-v1.jpg"); }
.season-background--winter { background-color: #1d2734; background-image: url("/images/winter-misty-garden-v1.jpg"); }

body[data-season="spring"] .season-background--spring,
body[data-season="summer"] .season-background--summer,
body[data-season="autumn"] .season-background--autumn,
body[data-season="winter"] .season-background--winter { opacity: 1; }

body[data-season="spring"] { --pr-accent: #e5b6ca; background: #24232f; }
body[data-season="spring"] .hero { background: #24232f; }
body[data-season="spring"] .hero::after {
  z-index: 1;
  background:
    radial-gradient(58% 46% at 22% 68%, rgba(19, 19, 29, .72) 0%, rgba(19, 19, 29, .46) 54%, rgba(19, 19, 29, 0) 100%),
    linear-gradient(90deg, rgba(15, 15, 24, .34) 0%, rgba(15, 15, 24, .10) 30%, rgba(15, 15, 24, .03) 58%, rgba(15, 15, 24, .20) 100%),
    radial-gradient(72% 42% at 50% 112%, rgba(225, 211, 220, .18), transparent 76%);
}
body[data-season="spring"] #scene { filter: saturate(.62) hue-rotate(228deg) brightness(1.05); }
body[data-season="summer"] { --pr-accent: #d9e9ae; background: #17282a; }
body[data-season="summer"] .hero { background: #17282a; }
body[data-season="summer"] .hero::after {
  z-index: 1;
  background:
    radial-gradient(58% 46% at 22% 68%, rgba(12, 31, 32, .70) 0%, rgba(12, 31, 32, .44) 54%, rgba(12, 31, 32, 0) 100%),
    linear-gradient(90deg, rgba(8, 23, 25, .31) 0%, rgba(8, 23, 25, .09) 31%, rgba(8, 23, 25, .02) 60%, rgba(8, 23, 25, .19) 100%),
    radial-gradient(72% 42% at 50% 112%, rgba(185, 213, 189, .14), transparent 76%);
}
body[data-season="summer"] #scene { filter: none; }
body[data-season="autumn"] { --pr-accent: #ed8a62; background: #2a2221; }
body[data-season="autumn"] .hero { background: #2a2221; }
body[data-season="autumn"] .hero::after {
  z-index: 1;
  background:
    radial-gradient(58% 46% at 22% 68%, rgba(34, 20, 18, .70) 0%, rgba(34, 20, 18, .45) 54%, rgba(34, 20, 18, 0) 100%),
    linear-gradient(90deg, rgba(29, 17, 17, .32) 0%, rgba(29, 17, 17, .10) 31%, rgba(29, 17, 17, .02) 60%, rgba(29, 17, 17, .20) 100%),
    radial-gradient(72% 42% at 50% 112%, rgba(205, 117, 75, .16), transparent 76%);
}
body[data-season="autumn"] #scene { filter: hue-rotate(-58deg) saturate(1.58) brightness(.95); }
body[data-season="winter"] { --pr-accent: #edf3ee; background: #1d2734; }
body[data-season="winter"] .hero { background: #1d2734; }
body[data-season="winter"] .hero::after {
  z-index: 1;
  background:
    radial-gradient(58% 46% at 22% 68%, rgba(16, 27, 39, .68) 0%, rgba(16, 27, 39, .43) 54%, rgba(16, 27, 39, 0) 100%),
    linear-gradient(90deg, rgba(11, 20, 31, .30) 0%, rgba(11, 20, 31, .09) 31%, rgba(11, 20, 31, .02) 60%, rgba(11, 20, 31, .19) 100%),
    radial-gradient(72% 42% at 50% 112%, rgba(190, 205, 220, .15), transparent 76%);
}
body[data-season="winter"] #scene { filter: grayscale(.68) sepia(.08) hue-rotate(160deg) saturate(.72) contrast(1.06) brightness(.94); }

body.is-chapter-changing .career-caption { animation: pr-copy-change .62s var(--pr-ease) both; }

@keyframes pr-copy-change {
  0% { opacity: .18; filter: blur(5px); transform: translateY(calc(7 * var(--u))); }
  100% { opacity: 1; filter: none; transform: none; }
}

@media (max-width: 900px) {
  .hero {
    height: 100svh;
    min-height: 0;
  }

  .stage {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    margin: 0;
  }

  @supports (height: 100dvh) {
    .hero { height: 100dvh; }
  }

  .season-background {
    inset: 0;
    transform: none;
    background-size: auto 100%;
    background-position: 60% 50%;
  }

  body[data-season="spring"] .hero::after,
  body[data-season="summer"] .hero::after,
  body[data-season="autumn"] .hero::after,
  body[data-season="winter"] .hero::after {
    background:
      linear-gradient(180deg, rgba(15, 15, 24, .28) 0%, rgba(15, 15, 24, .04) 34%, rgba(15, 15, 24, .18) 100%),
      radial-gradient(90% 34% at 50% 76%, rgba(225, 211, 220, .14), transparent 80%);
  }

  .dock-wrap { top: max(calc(30 * var(--u)), calc(env(safe-area-inset-top) + 8px)); }

  body[data-design-version="2"] .profile-signature {
    top: max(82px, calc(122 * var(--u)), calc(env(safe-area-inset-top) + 76px));
    left: max(calc(34 * var(--u)), calc(env(safe-area-inset-left) + 16px));
  }
  .profile-index { font-size: max(22px, calc(30 * var(--u))); }
  .profile-name { font-size: max(10px, calc(11 * var(--u))); }
  .profile-role { font-size: max(7px, calc(8.5 * var(--u))); }

  .hero-copy {
    top: max(150px, calc(220 * var(--u)), calc(env(safe-area-inset-top) + 144px));
    left: max(calc(34 * var(--u)), calc(env(safe-area-inset-left) + 16px));
    width: calc(692 * var(--u));
  }
  body[data-design-version="2"] .headline { font-size: max(18px, calc(24 * var(--u))); line-height: 1.25; letter-spacing: -.02em; }
  .capability-list { width: calc(692 * var(--u)); margin-top: 8px; gap: 4px 12px; }
  .capability-list li { grid-template-columns: 14px minmax(0, 1fr); gap: 4px; padding-top: 5px; }
  .capability-list li > span { font-size: 6px; }
  .capability-list strong { font-size: 9px; line-height: 1.3; white-space: nowrap; }
  .capability-list small { display: none; }

  .hero-actions { align-items: flex-start; flex-direction: column; gap: calc(14 * var(--u)); margin-top: calc(22 * var(--u)); }
  .hero-primary { width: max(138px, calc(174 * var(--u))); height: max(42px, calc(46 * var(--u))); border-radius: 12px; font-size: max(9px, calc(10 * var(--u))); }
  .hero-hint { font-size: max(8px, calc(9 * var(--u))); }

  .career-caption { display: none; }

  .career-map-label { display: none; }
  body[data-design-version="2"] .career-node:nth-child(1) { --screen-x: 13%; --screen-y: 69%; }
  body[data-design-version="2"] .career-node:nth-child(2) { --screen-x: 36%; --screen-y: 73%; }
  body[data-design-version="2"] .career-node:nth-child(3) { --screen-x: 60%; --screen-y: 70%; }
  body[data-design-version="2"] .career-node:nth-child(4) { --screen-x: 83%; --screen-y: 75%; }
  .career-stem { width: 24px; bottom: 6px; left: 3px; }
  body[data-design-version="2"] .career-node:hover .career-stem,
  body[data-design-version="2"] .career-node.is-active .career-stem,
  body[data-design-version="2"] .career-node:focus-visible .career-stem { width: 30px; }
  .career-company { left: -34px; bottom: 31px; min-width: 88px; gap: 2px; }
  body[data-design-version="2"] .career-node:nth-child(4) .career-company { right: -34px; left: auto; text-align: right; }
  .career-company > span { font-size: 6px; letter-spacing: .06em; }
  .career-company strong { font-size: 9px; }
  .career-company em { font-size: 7px; }
  .career-company b { display: none; font-size: 7px; }
  body[data-design-version="2"] .career-node.is-active .career-company b { display: block; }
  .career-company small { font-size: 6px; }
}

@media (orientation: landscape) and (max-height: 560px) {
  :root { --u: calc(100svh / 880); }

  @supports (height: 100dvh) {
    :root { --u: calc(100dvh / 880); }
  }

  .hero,
  .stage { height: 100svh; }

  @supports (height: 100dvh) {
    .hero,
    .stage { height: 100dvh; }
  }

  .dock-wrap { top: max(8px, calc(env(safe-area-inset-top) + 4px)); }
  .dock { height: 52px; padding: 4px; gap: 3px; border-radius: 16px; }
  .dock-item { width: 44px; height: 44px; border-radius: 12px; }

  .season-background {
    background-size: cover;
    background-position: 50% 50%;
  }

  body[data-design-version="2"] .profile-signature {
    top: max(78px, calc(env(safe-area-inset-top) + 68px));
    left: max(24px, calc(env(safe-area-inset-left) + 18px));
  }

  .profile-index { font-size: 24px; }
  .hero-copy {
    top: max(148px, calc(env(safe-area-inset-top) + 138px));
    left: max(24px, calc(env(safe-area-inset-left) + 18px));
    width: min(320px, 44vw);
  }
  .capability-list { width: 100%; }

  .career-caption,
  .career-map-label { display: none; }

  .career-company { opacity: 0; }
  body[data-design-version="2"] .career-node.is-active .career-company { opacity: 1; }
}

@media (max-width: 420px) {
  .hero-actions { display: none; }
}

@media (max-width: 360px) {
  .career-company {
    top: 28px;
    bottom: auto;
    opacity: 0;
  }

  body[data-design-version="2"] .career-node.is-active .career-company { opacity: 1; }

  .career-stem {
    top: 6px;
    bottom: auto;
    transform: rotate(54deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  body.is-chapter-changing .career-caption { animation-duration: .01ms; }
  .career-company,
  .career-stem { transition-duration: .01ms; }
  body[data-design-version="2"] .career-node.is-active::before,
  body.is-chapter-changing .career-node.is-active .career-company,
  body.is-chapter-changing .career-node.is-active .career-stem { animation: none; }
}
