/* Palette colours, set from whichever painting is in view */
@property --c1 { syntax: "<color>"; inherits: true; initial-value: #b9b2a8; }
@property --c2 { syntax: "<color>"; inherits: true; initial-value: #7f8790; }
@property --c3 { syntax: "<color>"; inherits: true; initial-value: #5e5852; }

:root {
  --c1: #b9b2a8;
  --c2: #7f8790;
  --c3: #5e5852;
  --ground: #0c0c0e;
  --ground-2: #151518;
  --ink: #efe9df;
  --ink-2: #c3bcb0;
  --ink-3: #8a847a;
  --line: rgba(239, 233, 223, 0.13);
  --line-2: rgba(239, 233, 223, 0.3);
  --accent: color-mix(in oklab, var(--c1) 55%, #fff);
  --brush: "Ma Shan Zheng", "STKaiti", "KaiTi", serif;
  --display: "Shippori Mincho", "Yu Mincho", Georgia, serif;
  --body: "Zen Kaku Gothic New", "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", Consolas, monospace;
  --wrap: 1180px;
  color-scheme: dark;
}

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

html { scroll-behavior: smooth; }

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

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

/* Paper tooth */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
  opacity: 0.06;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='p'><feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.6 -0.25'/></filter><rect width='100%' height='100%' filter='url(%23p)'/></svg>");
}

a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 4px; }
a:hover { color: var(--accent); }

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

::selection { background: var(--accent); color: var(--ground); }

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

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 28px; }

.mono {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.zh { font-family: var(--brush); font-weight: 400; letter-spacing: 0.04em; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* Colour washes, tinted by the current palette */

.washes {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
}

.washes span {
  position: absolute;
  border-radius: 46% 54% 60% 40% / 50% 44% 56% 50%;
  filter: blur(80px);
  animation: breathe 26s ease-in-out infinite alternate;
}

.washes .w1 { width: 52vmax; height: 40vmax; left: -14vmax; top: -12vmax; background: color-mix(in srgb, var(--c1) 46%, transparent); }
.washes .w2 { width: 46vmax; height: 36vmax; right: -14vmax; top: 30vh; background: color-mix(in srgb, var(--c2) 36%, transparent); animation-duration: 33s; }
.washes .w3 { width: 50vmax; height: 34vmax; left: 20vw; bottom: -22vmax; background: color-mix(in srgb, var(--c3) 40%, transparent); animation-duration: 39s; }

.washes::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.6) 100%);
}

.page .washes { opacity: 0.6; }

@keyframes breathe { to { transform: translate(6vw, 4vh) scale(1.12) rotate(8deg); } }

/* Autofocus: the lens racks from soft to sharp in one smooth pull, with a little focus breathing */

.focus { animation: focus-pull 1.6s var(--delay, 0s) cubic-bezier(0.22, 0.61, 0.36, 1) both; }

@keyframes focus-pull {
  0% { opacity: 0; filter: blur(12px); transform: scale(1.035); }
  15% { opacity: 1; }
  60% { filter: blur(0); transform: scale(0.996); }
  100% { opacity: 1; filter: blur(0); transform: none; }
}

.later { animation: rise 1.1s var(--delay, 1.6s) ease both; }

/* Text painted in the current palette */

.painted {
  background: linear-gradient(170deg, #fff6ea 15%, color-mix(in srgb, var(--c1) 80%, #fff) 60%, color-mix(in srgb, var(--c2) 55%, #fff) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Header */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  transition: background 0.3s ease;
}

.site-header.scrolled {
  background: rgba(12, 12, 14, 0.84);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 64px;
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--display);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-decoration: none;
  white-space: nowrap;
  color: var(--accent);
}

.wordmark:hover { color: var(--accent); }
.wordmark .zh { font-size: 1.25rem; }

.home .wordmark { opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity 0.6s ease, visibility 0.6s, transform 0.6s ease; }
.home .site-header.past-hero .wordmark { opacity: 1; visibility: visible; transform: none; }

.nav { display: flex; gap: 22px; margin: 0; padding: 0; list-style: none; }

.nav a {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 0;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--ink-2);
  border-bottom: 1px solid transparent;
}

.nav a .zh { font-size: 1.3rem; line-height: 1; color: var(--ink-3); transition: color 0.2s ease; }
.nav a:hover { color: var(--ink); }
.nav a:hover .zh { color: var(--accent); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }
.nav a[aria-current="page"] .zh { color: var(--accent); }

main { flex: 1; }

/* Full-screen openings */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  padding: 96px 24px 110px;
  text-align: center;
  overflow: hidden;
}

.hero > :not(.hero-foot) { position: relative; z-index: 1; }

.hero-foot {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 28px;
  pointer-events: none;
}

.hero-foot .wrap { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.hero-foot a { text-decoration: none; pointer-events: auto; }
.hero-foot a:hover { color: var(--accent); }

.cue { font-size: 1.5rem; line-height: 1; color: var(--ink-2); text-decoration: none; animation: bob 2.4s ease-in-out infinite; }
.cue:hover { color: var(--accent); }

@keyframes bob { 50% { transform: translateY(5px); } }

/* Palette credit: which painting the colours come from, on that painting */

.palette-credit {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: min(300px, calc(100vw - 32px));
  height: 88px;
  padding: 0 18px;
  overflow: hidden;
  text-decoration: none;
  text-align: left;
  background-color: #000;
  background-repeat: no-repeat;
  box-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.9);
  transition: filter 0.3s ease;
}

.palette-credit::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(10, 10, 12, 0.9) 0%, rgba(10, 10, 12, 0.72) 42%, rgba(10, 10, 12, 0.1) 78%, rgba(10, 10, 12, 0) 100%);
}

.palette-credit > * { position: relative; }
.palette-credit:hover { filter: brightness(1.12); }
.palette-credit .mono { display: block; margin-bottom: 6px; line-height: 1; color: var(--ink-2); }
.palette-credit strong {
  display: block;
  max-width: 64%;
  overflow: hidden;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.12rem;
  line-height: 1.25;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.7);
}
.palette-credit .palbar { width: 140px; height: 7px; margin-top: 7px; }
.palette-credit strong,
.palette-credit .palbar { transition: opacity 0.35s ease; }
.palette-credit.swapping strong,
.palette-credit.swapping .palbar { opacity: 0; }

/* Painting layers: a new painting fades in over the old one */
.palette-credit > .art-layer,
.header-art > .art-layer {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 0.9s ease;
}

.palette-credit > .art-layer.in,
.header-art > .art-layer.in { opacity: 1; }

/* In the header, the painting fills the bar behind the name and fades out to the right */
.header-art {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  width: min(560px, 75vw);
  isolation: isolate;
  pointer-events: none;
  filter: brightness(0.6);
  -webkit-mask-image: linear-gradient(90deg, #000 30%, transparent);
  mask-image: linear-gradient(90deg, #000 30%, transparent);
  transition: opacity 0.6s ease;
}
.header-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(10, 10, 12, 0.42), rgba(10, 10, 12, 0.2) 40%, transparent 70%);
}
.home .site-header:not(.past-hero) .header-art { opacity: 0; }
.wordmark { text-shadow: 0 0 2px rgba(0, 0, 0, 0.7), 0 1px 10px rgba(0, 0, 0, 0.9); }

/* Crop tool: art.html?crop */

.crop-tool { margin: 0 0 64px; padding: 24px; border: 1px dashed var(--line-2); }
.crop-tool > p { margin: 0 0 20px; color: var(--ink-2); max-width: 70ch; }
.crop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 24px; }
.crop-item { display: flex; flex-direction: column; gap: 10px; }
.crop-preview { cursor: grab; user-select: none; touch-action: none; }
.crop-preview.dragging { cursor: grabbing; }
.crop-item label { display: flex; align-items: center; gap: 10px; }
.crop-item input[type="range"] { flex: 1; accent-color: var(--accent); }
.crop-item code {
  display: block;
  padding: 8px 10px;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid var(--line);
  overflow-x: auto;
  white-space: nowrap;
}

/* Home opening */

.name-block {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 4vw, 56px);
  filter: drop-shadow(0 0 40px color-mix(in srgb, var(--c1) 30%, transparent));
}

.home h1 {
  margin: 0 0 -0.32em;
  padding-bottom: 0.32em;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(3.2rem, 10.5vw, 8.4rem);
  line-height: 1.05;
  letter-spacing: 0.02em;
  white-space: nowrap;
}


.zh-name {
  display: flex;
  flex-direction: column;
  font-size: clamp(2.2rem, 5.6vw, 4.4rem);
  line-height: 1.08;
  --delay: 0.5s;
}

.home .tagline {
  margin: 30px 0 0;
  font-family: var(--display);
  font-size: clamp(1rem, 2vw, 1.25rem);
  letter-spacing: 0.3em;
  color: var(--ink-2);
}

.home .tagline span { color: var(--accent); }


/* Page openings */

.page-hero .glyph {
  font-size: clamp(7rem, 24vh, 15rem);
  line-height: 1;
}

.page-hero h1 {
  margin: 10px 0 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(3rem, 9vw, 6rem);
  line-height: 1.1;
  letter-spacing: 0.04em;
  white-space: nowrap;
  --delay: 0.35s;
}

.page-hero .subtitle { margin: 22px auto 0; max-width: 46ch; font-size: 1.08rem; color: var(--ink-2); }

/* Sections */

.section { margin-top: 110px; }

.section-head { display: flex; align-items: baseline; gap: 18px; margin-bottom: 34px; }
.section-head .zh { font-size: clamp(2.6rem, 5vw, 3.6rem); line-height: 1; color: var(--accent); }

.section-head h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.7rem, 3.6vw, 2.5rem);
  line-height: 1.2;
}

.section-head .mono { margin-left: auto; }

/* Section cards on the home page */

.cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
}

.card.c-math { --wash: color-mix(in srgb, var(--c1) 50%, var(--c2)); }

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 340px;
  padding: 26px 24px 22px;
  overflow: hidden;
  text-decoration: none;
  background: var(--ground-2);
  border: 1px solid var(--line);
  transition: border-color 0.3s ease, transform 0.4s ease;
}

.card::before {
  content: "";
  position: absolute;
  width: 120%;
  height: 80%;
  left: -10%;
  top: -20%;
  border-radius: 50%;
  filter: blur(50px);
  opacity: 0.45;
  background: var(--wash);
  transition: opacity 0.4s ease;
}

.card.c-art { --wash: var(--c1); }
.card.c-research { --wash: var(--c2); }
.card.c-about { --wash: var(--c3); }

.card .glyph {
  position: absolute;
  top: 10px;
  right: 22px;
  font-size: clamp(5rem, 9vw, 7.5rem);
  line-height: 1.1;
  color: rgba(255, 246, 234, 0.9);
  text-shadow: 0 0 30px color-mix(in srgb, var(--wash) 50%, transparent);
  transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.card .body { position: relative; }
.card h3 { margin: 0; font-family: var(--display); font-weight: 600; font-size: clamp(1.7rem, 2.8vw, 2.2rem); line-height: 1.2; }
.card p { margin: 4px 0 0; font-size: 0.92rem; color: var(--ink-2); }
.card .go { margin-top: 14px; }

.card:hover { border-color: var(--line-2); transform: translateY(-3px); color: var(--ink); }
.card:hover::before { opacity: 0.7; }
.card:hover .glyph { transform: rotate(-4deg) scale(1.05); }

/* Strip of selected work */

.strip { position: relative; overflow: hidden; }

.reel-view {
  overflow: hidden;
  touch-action: pan-y;
  cursor: grab;
}
.reel-view.dragging { cursor: grabbing; user-select: none; }
.reel-view img { -webkit-user-drag: none; user-select: none; }

.reel { display: flex; width: max-content; padding: 4px 0; will-change: transform; }

.reel .piece { flex: 0 0 auto; width: min-content; margin: 0 14px 0 0; cursor: inherit; }
.reel .piece .frame { height: clamp(240px, 36vw, 380px); }
.reel .piece .frame img { height: 100%; width: auto; max-width: none; }
.reel .piece .m { display: none; }

/* Gallery */

.filters { display: flex; flex-wrap: wrap; gap: 6px 26px; margin-bottom: 30px; }


.gallery { display: flex; align-items: flex-start; gap: 22px; }
.gallery-col { flex: 1 1 0; min-width: 0; }

.piece { margin: 0 0 32px; break-inside: avoid; cursor: zoom-in; }
.piece[hidden] { display: none; }

.piece .frame {
  position: relative;
  border: 1px solid var(--line);
  background: #000;
  overflow: hidden;
  transition: border-color 0.4s ease, box-shadow 0.6s ease;
}

.piece .frame img { width: 100%; transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1); }
.piece:hover .frame img,
.piece:focus-visible .frame img { transform: scale(1.03); }
.piece.current .frame { border-color: var(--line-2); box-shadow: 0 30px 60px -30px color-mix(in srgb, var(--c1) 60%, transparent); }
.piece:focus-visible { outline: none; }
.piece:focus-visible .frame { outline: 2px solid var(--accent); outline-offset: 3px; }

.piece figcaption { display: flex; gap: 10px; align-items: baseline; margin-top: 10px; }
.piece .num { flex: 0 0 auto; color: var(--accent); }
.piece .t { font-family: var(--display); font-size: 1.08rem; line-height: 1.3; }
.piece .m { margin-left: auto; flex: 0 0 auto; }
.piece { transition: opacity 0.4s ease; }
.gallery.lighting .piece:not(.lit) { opacity: 0.22; }
.piece.lit .frame { border-color: var(--line-2); }

/* A piece's own palette, each colour sized by how much of the painting it covers */

.palbar { display: flex; height: 6px; margin-top: 8px; overflow: hidden; border-radius: 3px; }
.palbar i { display: block; min-width: 3px; }

/* Palette: paint dabs from every artwork, sorted by hue */

.board { margin: 0 0 56px; }

.board .readout { display: flex; align-items: baseline; gap: 14px; min-height: 2.2em; margin-bottom: 18px; }
.board .readout .hex { font-family: var(--display); font-size: clamp(1.2rem, 2.4vw, 1.6rem); line-height: 1.3; color: var(--ink); }

.dabs { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }

.dab {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  cursor: pointer;
  transform: rotate(var(--turn, 0deg)) scale(var(--mag, 1));
  transition: transform 0.14s ease-out, box-shadow 0.2s ease, opacity 0.2s ease;
}

.dab:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--ground), 0 0 0 4px var(--accent); }
.dab[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--ground), 0 0 0 4px var(--ink); }
.dabs:has(.dab[aria-pressed="true"]) .dab:not([aria-pressed="true"]) { opacity: 0.45; }

.board .readout { align-items: center; }

.chip-swatch {
  width: 0;
  height: 34px;
  border-radius: 46% 54% 52% 48% / 50% 46% 54% 50%;
  transition: width 0.2s ease, background-color 0.2s ease;
}

.chip-swatch.on { width: 34px; }

.show-all { margin-left: 6px; }
.show-all[hidden] { display: none; }

.board .how { margin: 16px 0 0; }

/* The art gallery problem */

.agp { display: flex; flex-direction: column; gap: 12px; }

.agp-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 26px; }
.agp-bar .chips { flex: 0 0 auto; }

.agp .agp-note { margin: 0; font-size: 0.92rem; line-height: 1.6; color: var(--ink-2); }
.agp-note i { font-family: var(--display); }

.agp-figure { margin: 0; }

.agp svg {
  display: block;
  width: 100%;
  height: auto;
  touch-action: pan-y pinch-zoom;
  user-select: none;
  -webkit-user-select: none;
  outline: none;
}

/* Unlit floor is in shadow; each guard's light fades with distance and adds where views overlap */
.agp .floor { fill: #0b0a09; }
.agp .walls { fill: none; stroke: var(--ink-2); stroke-width: 2.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; pointer-events: none; transition: stroke 0.4s ease; }
.agp-light { isolation: isolate; }
.agp .light { mix-blend-mode: screen; pointer-events: none; }
.agp .light-near { stop-color: #ffd7a1; stop-opacity: 0.36; }
.agp .light-far { stop-color: #ffd7a1; stop-opacity: 0.14; }

/* Fully guarded */
.agp.covered .walls { stroke: #7fd6a4; }

.agp .tri { fill: none; stroke: var(--ink-3); stroke-width: 1.2; stroke-dasharray: 5 6; pointer-events: none; }
.agp .dot { stroke: var(--ground); stroke-width: 3; pointer-events: none; }
.agp .dot.c0 { fill: color-mix(in srgb, var(--c1) 75%, #fff); }
.agp .dot.c1 { fill: color-mix(in srgb, var(--c2) 75%, #fff); }
.agp .dot.c2 { fill: color-mix(in srgb, var(--c3) 75%, #fff); }
.agp .guard { cursor: grab; outline: none; touch-action: none; }
.agp.dragging, .agp.dragging .guard { cursor: grabbing; }
.agp .guard-reach { fill: transparent; }
.agp .figure-edge { fill: var(--ground); stroke: var(--ground); stroke-width: 3; stroke-linejoin: round; }
.agp .figure-edge > * { vector-effect: non-scaling-stroke; }
.agp .figure-body { fill: var(--ink); }
.agp .figure-cap { fill: var(--accent); }
.agp .figure-visor { fill: var(--ground); }
.agp .guard:focus-visible .figure-edge { fill: var(--accent); stroke: var(--accent); }
.agp .spare-count { font-family: var(--mono); fill: var(--ink-3); }
.agp .spare.empty { opacity: 0.25; cursor: default; }
.agp .held { pointer-events: none; }
.agp .held.off { opacity: 0.6; }

.agp-art rect { opacity: 0.3; filter: saturate(0); transition: opacity 0.4s ease, filter 0.4s ease; pointer-events: none; }
.agp-art rect.seen { opacity: 1; filter: none; }

.agp figcaption { margin-top: 10px; }

.agp .controls { display: flex; flex-direction: column; gap: 24px; }
.agp .control h3 { margin: 0 0 10px; }

.chips { display: flex; flex-wrap: wrap; gap: 6px 26px; }


.stats { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.stats li { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.stats b { font-family: var(--display); font-weight: 400; font-size: 1.2rem; font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; }
.agp.covered [data-out="covered"] { color: var(--accent); }

.prose { max-width: 66ch; }
.prose p { margin: 0 0 18px; color: var(--ink-2); }
.prose p strong { color: var(--ink); font-weight: 500; }

.theorem { margin: 32px 0; padding: 2px 0 2px 22px; border-left: 2px solid var(--accent); }

.theorem .label { display: block; margin-bottom: 6px; font-family: var(--display); font-weight: 600; font-size: 1.1rem; color: var(--ink); }
.theorem p + p { margin-top: 12px; }

.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps li { position: relative; padding: 0 0 18px 44px; color: var(--ink-2); counter-increment: step; }
.steps li::before { content: counter(step); position: absolute; left: 0; top: -2px; font-family: var(--display); font-size: 1.6rem; line-height: 1; color: var(--accent); }

.floor-math { font-family: var(--display); font-style: italic; white-space: nowrap; }

/* Text buttons: the label alone, with an underline that draws in on hover and stays on the current choice */

.filter,
.chip,
.study-tools a,
.study-tools button {
  position: relative;
  display: inline-block;
  padding: 6px 0;
  font-family: var(--mono);
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-2);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color 0.2s ease;
}

.filter::after,
.chip::after,
.study-tools a::after,
.study-tools button::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}

.filter:hover,
.chip:hover,
.study-tools a:hover,
.study-tools button:hover { color: var(--ink); }

.filter:hover::after,
.chip:hover::after,
.study-tools a:hover::after,
.study-tools button:hover::after { transform: scaleX(1); }

.filter[aria-pressed="true"],
.chip[aria-pressed="true"],
.study-tools button[aria-expanded="true"] { color: var(--accent); }

.filter[aria-pressed="true"]::after,
.chip[aria-pressed="true"]::after,
.study-tools button[aria-expanded="true"]::after { height: 2px; transform: scaleX(1); }

/* Viewer */

.viewer {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: none;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  grid-template-columns: minmax(0, 1fr);
  background: rgba(10, 10, 12, 0.92);
  backdrop-filter: blur(8px);
}

.viewer.open { display: grid; animation: rise 0.3s ease; }

.v-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 20px;
  padding: 16px 24px;
}

.v-title { display: flex; align-items: center; gap: 14px; font-family: var(--display); font-size: 1.3rem; line-height: 1.3; }
.v-title .mono { color: var(--accent); }

.v-stage { display: flex; align-items: center; justify-content: center; min-height: 0; padding: 0 20px; }
.v-holder { position: relative; display: flex; }

.v-stage img {
  width: auto;
  max-width: calc(100vw - 40px);
  max-height: calc(100vh - 210px);
  max-height: calc(100svh - 210px);
  object-fit: contain;
  box-shadow: 0 40px 90px -40px color-mix(in srgb, var(--c1) 70%, transparent);
}

.v-slide {
  position: absolute;
  top: 50%;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  border: 0;
  border-radius: 50%;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink);
  background: rgba(10, 10, 12, 0.6);
  backdrop-filter: blur(4px);
  cursor: pointer;
}

.v-slide.prev { left: 10px; }
.v-slide.next { right: 10px; }
.v-slide:hover { background: rgba(10, 10, 12, 0.85); color: var(--accent); }
.v-slide[hidden], .v-dots[hidden] { display: none; }

.v-dots { position: absolute; left: 0; right: 0; bottom: 12px; display: flex; justify-content: center; gap: 6px; }

.v-dots button {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.45);
  cursor: pointer;
}

.v-dots button.on { background: #fff; transform: scale(1.3); }

.v-desc {
  max-width: 70ch;
  margin: 14px auto 0;
  padding: 0 20px;
  font-size: 0.95rem;
  line-height: 1.65;
  text-align: center;
  color: var(--ink-2);
}

.v-desc[hidden] { display: none; }

.piece .count {
  position: absolute;
  top: 10px;
  right: 10px;
  padding: 2px 8px;
  color: var(--ink);
  background: rgba(10, 10, 12, 0.7);
  backdrop-filter: blur(4px);
}

/* Instagram posts */

.ig[hidden] { display: none; }

.ig-posts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 22px;
  align-items: start;
}

.ig-posts .instagram-media { min-width: 0 !important; width: 100% !important; margin: 0 !important; }

.ig-more { display: inline-flex; margin-top: 26px; text-decoration: none; }

.v-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* The bottom bar stays one line for every piece; the palette bar shrinks instead of wrapping */
.viewer > .v-bar { flex-wrap: nowrap; }
.v-title { min-width: 0; }
.v-title span:last-child { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.v-close { flex: 0 0 auto; }
.v-info { flex: 1 1 auto; min-width: 0; flex-wrap: nowrap; gap: 12px; }
.v-info .mono { flex: 0 0 auto; white-space: nowrap; }
.v-palbar { flex: 0 1 180px; min-width: 40px; margin: 0; }
.viewer > .v-bar:last-child > .v-group:last-child { flex: 0 0 auto; flex-wrap: nowrap; }

.v-btn {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: transparent;
  border: 0;
  padding: 7px 10px;
  cursor: pointer;
  text-decoration: none;
}

.v-btn:hover { color: var(--accent); }

/* Research */

.interests { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 24px 0 0; padding: 0; list-style: none; }

.interests li {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 5px 12px;
  color: var(--ink-2);
  border: 1px solid var(--line-2);
}

.studies { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }

.study {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 12px 32px;
  padding: 38px 0;
  border-bottom: 1px solid var(--line);
}

.study .side { display: flex; flex-direction: column; gap: 8px; }
.study .side .zh { font-size: 3.2rem; line-height: 1; color: var(--accent); }

.status {
  align-self: flex-start;
  padding: 2px 8px;
  border: 1px solid color-mix(in oklab, var(--c2) 50%, #fff);
  color: color-mix(in oklab, var(--c2) 50%, #fff);
}

.study h3 {
  display: inline;
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.25rem, 2.2vw, 1.55rem);
  line-height: 1.45;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-size: 0 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size 0.6s ease;
}

.study:hover h3 { background-size: 100% 1px; }

.study .authors { margin: 12px 0 0; font-size: 0.95rem; color: var(--ink-2); }
.study .authors b { color: var(--ink); font-weight: 500; }
.study .venue { margin: 0; font-size: 0.95rem; font-style: italic; color: var(--ink-3); }

.study-tools { display: flex; flex-wrap: wrap; gap: 6px 26px; margin-top: 16px; }


.abstract { margin-top: 18px; padding-left: 18px; border-left: 2px solid var(--accent); }
.abstract[hidden] { display: none; }
.abstract p { margin: 12px 0 0; max-width: 74ch; font-size: 0.95rem; color: var(--ink-2); }
.abstract p:first-child { margin-top: 0; }

/* About */

.about-intro { max-width: 860px; padding-top: 150px; }

/* The photo in one column, the text beside it in the other; on phones the text wraps around the photo */
.intro-text { display: grid; grid-template-columns: 230px minmax(0, 1fr); column-gap: 40px; }
.intro-text > * { grid-column: 2; }
.intro-text > h1,
.intro-text > .name-line { grid-column: 1 / -1; }

.about-intro .portrait {
  grid-column: 1;
  grid-row: 3 / span 3;
  align-self: start;
  width: 100%;
  margin: 8px 0 0;
  shape-outside: inset(0 round 2px);
}

.about-intro .portrait img { display: block; width: 100%; height: auto; box-shadow: 0 20px 40px -24px rgba(0, 0, 0, 0.9); }

.intro-text h1 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.4rem, 5.5vw, 3.8rem);
  line-height: 1.1;
}

.name-line { display: flex; align-items: center; gap: 16px; margin: 24px 0 34px; }
.name-line .zh { font-size: clamp(2rem, 4vw, 2.8rem); line-height: 1; }
.name-line .pinyin { font-family: var(--display); font-size: 1.1rem; letter-spacing: 0.12em; color: var(--ink-2); }

/* Every paragraph runs to the same right edge, the width of the intro */
.intro-text p { margin: 0 0 18px; font-size: 1.05rem; line-height: 1.75; color: var(--ink-2); }
.intro-text .lead { font-family: var(--display); font-size: clamp(1.2rem, 2vw, 1.4rem); line-height: 1.55; color: var(--ink); }

.links { clear: both; display: flex; flex-wrap: wrap; gap: 6px 26px; margin: 28px 0 0; padding: 28px 0 0; list-style: none; }

.details { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }

.details li {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  gap: 20px;
  align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.details .v { font-family: var(--display); font-size: 1.08rem; line-height: 1.5; overflow-wrap: anywhere; }
.details a.v { text-decoration: none; }
.details a.v:hover { color: var(--accent); }

/* Chinese characters written stroke by stroke */

/* Until the stroke writer takes over, the plain character stays hidden; it shows on its own if the writer never loads */
.js [data-hanzi]:not(.hanzi):not(.hanzi-fallback) { visibility: hidden; animation: hanzi-reveal 0s 4s forwards; }
@keyframes hanzi-reveal { to { visibility: visible; } }

.hanzi-char svg path:not([fill="none"]) { fill: url(#hz-grad) !important; }
.hanzi-char svg path[stroke]:not([stroke="none"]) { stroke: url(#hz-grad) !important; }
.hz-a { stop-color: #fff6ea; }
.hz-b { stop-color: color-mix(in srgb, var(--c1) 80%, #fff); }
.hz-c { stop-color: color-mix(in srgb, var(--c2) 55%, #fff); }

.hanzi:not(.zh-name) { display: inline-flex; gap: 0.06em; }
.hanzi-char { display: inline-block; flex: 0 0 auto; }
.hanzi-char svg { display: block; overflow: visible; filter: drop-shadow(0 0 22px color-mix(in srgb, var(--c1) 35%, transparent)); }
.zh-name.hanzi { gap: 0; }
.page-hero .glyph.hanzi { justify-content: center; }

/* Math blog */

.post-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.post-item { border-bottom: 1px solid var(--line); }

.post-item a {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 28px 0;
  text-decoration: none;
  transition: padding 0.25s ease;
}

.post-item strong { font-family: var(--display); font-weight: 600; font-size: clamp(1.4rem, 2.6vw, 1.9rem); line-height: 1.3; }
.post-item .summary { max-width: 70ch; color: var(--ink-2); }
.post-item a:hover { padding-left: 12px; color: var(--ink); }
.post-item a:hover strong { color: var(--accent); }
.post-empty { padding: 28px 0; }
.post-item .draft { margin-left: 10px; padding: 1px 6px; border: 1px solid var(--line-2); }

.post { max-width: 1000px; }

.post-head { max-width: 760px; padding-top: 120px; }
.post-head .back { text-decoration: none; }
.post-head .back:hover { color: var(--accent); }
.post-head .meta { margin: 28px 0 0; }

.post-head h1 {
  margin: 10px 0 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 4rem);
  line-height: 1.1;
}

.post-head .dek { margin: 16px 0 0; font-family: var(--display); font-size: clamp(1.15rem, 2.2vw, 1.4rem); color: var(--ink-2); }

.post-body { margin-top: 56px; }
.post-body.prose { max-width: none; }
.post-body > :not(.agp), .post-body .agp figcaption { max-width: 760px; }

.post-body h2 {
  margin: 56px 0 18px;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 2rem);
}

.post-body > h2:first-child { margin-top: 0; }
.post-body p, .post-body li { line-height: 1.8; }
.post-body ul, .post-body ol { padding-left: 1.2em; color: var(--ink-2); }
.post-body ul li, .post-body ol li { margin-bottom: 10px; }
.post-body li::marker { color: var(--ink-3); }
.post-body .stats, .post-body .chips { padding-left: 0; }
.post-body .stats li { margin: 0; line-height: 1.5; }

.theorem p { margin: 0; color: var(--ink); }

.post .agp { margin: 48px 0; }
.post .agp figcaption { margin: 0; max-width: 760px; font-size: 0.92rem; color: var(--ink-2); }
.post .agp figcaption .mono { margin-right: 6px; color: var(--ink); }

.proof {
  margin: 0 0 16px;
  border: 1px solid var(--line-2);
  background: rgba(239, 233, 223, 0.03);
}

.proof summary {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 16px 20px;
  font-family: var(--display);
  font-size: 1.12rem;
  cursor: pointer;
  list-style: none;
}

.proof summary::-webkit-details-marker { display: none; }
.proof summary::before { content: "+"; font-family: var(--mono); color: var(--accent); }
.proof[open] summary::before { content: "\2212"; }
.proof summary > span:first-of-type { flex: 1 1 auto; min-width: 0; }
.proof summary .mono { flex: 0 0 auto; }
.proof summary:hover { color: var(--accent); }
.proof-body { padding: 0 20px 6px; }
.proof-body > p { margin: 0 0 16px; }

.katex { font-size: 1.08em; }
.katex-display { overflow-x: auto; overflow-y: hidden; padding: 4px 0; }

.refs { padding-left: 1.4em; color: var(--ink-2); font-size: 0.95rem; }
.refs li { margin-bottom: 10px; }

/* Figures inside proofs */

.proof-fig { margin: 8px 0 22px; }
.proof-fig svg { display: block; width: 100%; height: auto; }
.proof-fig figcaption { margin-top: 8px; font-size: 0.88rem; color: var(--ink-2); }
.proof-fig figcaption .mono { margin-right: 6px; color: var(--ink); }
.proof-fig .floor { fill: rgba(239, 233, 223, 0.05); }
.proof-fig .walls { fill: none; stroke: var(--ink-2); stroke-width: 2.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.proof-fig .diag { stroke: var(--ink-3); stroke-width: 1.5; stroke-dasharray: 6 6; }
.proof-fig .tri-a { fill: rgba(239, 233, 223, 0.06); }
.proof-fig .tri-b { fill: rgba(239, 233, 223, 0.02); }
.proof-fig .dot { stroke: var(--ground); stroke-width: 3; }
.proof-fig .dot.c0 { fill: color-mix(in srgb, var(--c1) 75%, #fff); }
.proof-fig .dot.c1 { fill: color-mix(in srgb, var(--c2) 75%, #fff); }
.proof-fig .dot.c2 { fill: color-mix(in srgb, var(--c3) 75%, #fff); }
.proof-fig .ring { fill: none; stroke: var(--ink); stroke-width: 2.5; }
.proof-fig .wedge { stroke: none; }
.proof-fig .tip { fill: var(--ink); }

/* CV shortlist */

.cv-group {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  gap: 8px 24px;
  padding: 24px 0 10px;
  border-top: 1px solid var(--line);
}

.cv-group h3 { margin: 4px 0 0; }
.cv-group ul { margin: 0; padding: 0; list-style: none; }

.cv-group li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  padding: 0 0 16px;
}

.cv-group .what { display: flex; flex-direction: column; min-width: 0; }
.cv-group .what strong { font-family: var(--display); font-weight: 600; font-size: 1.08rem; line-height: 1.45; }
.cv-group .what strong a { text-decoration: none; }
.cv-group .what strong a:hover { color: var(--accent); }
.cv-group .what span { font-size: 0.92rem; color: var(--ink-2); }
.cv-group .when { flex: 0 0 auto; }

/* Next page */

.next {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  margin-top: 110px;
  padding: 28px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  text-decoration: none;
}

.next strong {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-top: 4px;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  line-height: 1.2;
}

.next strong .zh { color: var(--accent); font-size: 1.3em; }
.next .arrow { font-size: 1.8rem; color: var(--accent); transition: transform 0.3s ease; }
.next:hover { color: var(--ink); }
.next:hover .arrow { transform: translateX(8px); }

/* Footer */

.site-footer { margin-top: 80px; border-top: 1px solid var(--line); background: rgba(0, 0, 0, 0.35); }

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
  padding-top: 26px;
  padding-bottom: 26px;
}

.site-footer ul { display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 0; padding: 0; list-style: none; }
.site-footer a { text-decoration: none; color: var(--ink-2); }
.site-footer a:hover { color: var(--accent); }

/* Small screens */

@media (max-width: 860px) {
  .wrap { padding: 0 16px; }
  .nav { gap: 14px; }
  .nav a { font-size: 0.88rem; gap: 5px; }
  .nav a .zh { font-size: 1.1rem; }
  .wordmark .zh { display: none; }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .card { min-height: 220px; padding: 18px 16px 16px; }
  .card .glyph { font-size: 4.2rem; right: 14px; }
  .study { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 30px 0; }
  .study .side { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
  .study .side .zh { font-size: 2.4rem; }
  .about-intro { padding-top: 120px; }
  .intro-text { grid-template-columns: 180px minmax(0, 1fr); column-gap: 28px; }
  .details li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .cv-group { grid-template-columns: minmax(0, 1fr); }
  .cv-group li { flex-direction: column; gap: 2px; }
  .gallery { gap: 12px; }
  .piece { margin-bottom: 24px; }
  .piece figcaption { flex-wrap: wrap; gap: 4px 10px; }
  .piece .t { font-size: 1rem; flex-basis: 100%; order: 3; }
  .hero-foot .hide-sm { display: none; }
  .v-bar { padding: 12px 16px; }
}

@media (max-width: 560px) {
  .site-header .wrap { flex-direction: column; align-items: flex-start; gap: 0; padding-top: 8px; padding-bottom: 8px; min-height: 0; }
  .wordmark { font-size: 1rem; }
  .intro-text { display: block; }
  .about-intro .portrait { float: left; width: 128px; margin: 6px 18px 10px 0; }
  .hero { padding-top: 110px; }
  .name-block { flex-direction: column; gap: 14px; }
  .zh-name { flex-direction: row; gap: 0.1em; font-size: 2.4rem; }
  /* On phones the viewer's bottom bar takes two rows: details and palette, then the buttons */
  .viewer > .v-bar:last-child { flex-wrap: wrap; gap: 8px; }
  .v-info { flex: 1 1 100%; }
  .v-palbar { flex: 1 1 auto; }
  .viewer > .v-bar:last-child > .v-group:last-child { flex: 1 1 100%; justify-content: space-between; margin: 0 -10px; }
  .post-head { padding-top: 96px; }
  .post-body { margin-top: 40px; }
  .post-body p, .post-body li { line-height: 1.7; }
  .theorem { margin: 26px 0; padding-left: 16px; }
  .proof summary { flex-wrap: wrap; gap: 4px 10px; padding: 14px 14px; font-size: 1.05rem; }
  .proof summary .mono { flex-basis: 100%; padding-left: 22px; }
  .proof-body { padding: 0 14px 4px; }
  .agp-bar .chips { gap: 6px 18px; }
}

@media (prefers-reduced-motion: reduce) {
  :root { transition: none; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}
