/*
  Yifeng Sun — personal site
  Swiss / International Typographic Style, one screen.

  Grid     12 columns. Every block starts and ends on a column line.
  Colour   black, off-white, one red (#DA291C). Flat. No shadow, no gradient.
  Type     Helvetica Neue / Neue Haas Grotesk / Inter. Regular 400 and Bold 700,
           plus Medium 500 for the name only.
  Layout   Flush left, ragged right. Nothing is centred.

  Left  half (cols 1–6)   name, 04 Contact
  Right half (cols 7–12)  01 Experience, 02 Education, 03 Skills
  Inside each block       col 1 = number, cols 2–6 = content (skills: 2–3 label, 4–6 items)

  Hierarchy: four sizes, nothing in between.
    Display   name
    XL        the one primary item of a block: current employer, e-mail
    M         secondary items: past employers, schools, GitHub
    S         everything else: labels, details, skills
  Order of importance across blocks: Experience, Contact, Education, Skills.
*/

:root {
  --ink: #111111;   /* soft black: pure #000 glares against off-white on bright displays */
  --paper: #F0ECE0;
  --red: #DA291C;

  --margin: clamp(16px, 2.4vw, 40px);
  --gutter: clamp(8px, 1.7vw, 24px);
  --rule: 1px solid var(--ink);

  --fs-s: 13px;
  --lh: 18px;
  --fs-m: clamp(17px, 1.4vw, 20px);
  --fs-xl: clamp(28px, 2.8vw, 40px);
  --fs-num: 20px;

  --font: "Neue Haas Grotesk Display Pro", "Neue Haas Grotesk Text Pro",
          "Helvetica Neue", "Inter", Helvetica, Arial, sans-serif;
}

/* ---------- Reset ---------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 var(--fs-s) / var(--lh) var(--font);
  text-align: left;
  hyphens: none;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ol, ul, li { margin: 0; padding: 0; }
ol, ul { list-style: none; }
h1, h2, h3, strong { font-weight: 700; }
p { text-wrap: pretty; }

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}
a:hover { text-decoration-thickness: 0.16em; }
a:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
}

::selection { background: var(--red); color: var(--ink); }

/* ---------- Grid ---------- */

.wrap {
  max-width: 1680px;
  margin-inline: auto;
  padding-inline: var(--margin);
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
}

/* Nested grids. A block that spans n parent columns gets n columns with the
   same gutter, so its lines land exactly on the parent's column lines. */
.head,
.list,
.links {
  --n: 6;
  display: grid;
  grid-template-columns: repeat(var(--n), minmax(0, 1fr));
  column-gap: var(--gutter);
}

/* ---------- One screen ---------- */

.stage {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  padding-block: var(--margin);
}

.frame {
  flex: 1;
  min-width: 0;
  grid-template-rows: auto 1fr auto;
  row-gap: 28px;
  border-top: var(--rule);
  padding-top: 12px;
}

.name   { grid-column: 1 / 7;  grid-row: 1 / 3; }
.s-exp  { grid-column: 7 / 13; grid-row: 1; }
.s-edu  { grid-column: 7 / 13; grid-row: 2; align-self: center; }
.s-skl  { grid-column: 7 / 13; grid-row: 3; }
.s-con  { grid-column: 1 / 7;  grid-row: 3; }

/* ---------- Display: name ---------- */

/* Display type follows optical sizing: the larger the type, the lighter the weight,
   the looser the tracking and the more open the leading. Bold strokes scale with the
   size, so a 200px Bold name is a heavy black mass on a bright monitor, and Regular
   reads lighter than the Bold employer name beside it. Medium (500) sits between:
   the one place the page leaves its two-weight rule, so the name still outweighs
   everything else. */
.name {
  align-self: start;
  font-weight: 500;
  font-size: clamp(64px, min(11.5vw, 28vh), 200px);
  line-height: 0.88;
  letter-spacing: -0.03em;
  margin-top: -0.062em;
}
.name span { display: block; }
/* Optical margin alignment. Only the tip of the Y touches its left edge (it recedes
   ~0.1em within a quarter of the cap height), while the S is a round bowl. Equal ink
   extremes therefore looked misaligned. The S sits on the grid line with a hairline of
   round overshoot; the Y tip hangs 0.02em further left so both lines read as flush.
   Offsets are Helvetica Neue Medium side bearings: Y -0.006em, S +0.033em. */
.name .l1 { margin-left: -0.020em; }
.name .l2 { margin-left: -0.039em; }
.name .stop { display: inline; color: var(--red); }

/* ---------- Blocks ---------- */

.blk { border-top: var(--rule); padding-top: 10px; }
.s-exp { border-top: 0; padding-top: 0; }   /* the frame's top rule already sits here */

/* Block head: red number, bold label. Marker, not content. */
.head {
  align-items: baseline;
  margin-bottom: 14px;
}
.num {
  grid-column: 1;
  font-size: var(--fs-num);
  line-height: 1;
  font-weight: 700;
  color: var(--red);
}
.label { grid-column: 2 / -1; font-weight: 700; }

/* Items. Each item is a 5-column grid sitting on parent columns 2–6,
   with a hairline above every item after the first. */
.list > li {
  grid-column: 2 / -1;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  column-gap: var(--gutter);
  padding-block: 10px;
}
.list > li:first-child { padding-top: 0; }
.list > li:last-child  { padding-bottom: 0; }
.list > li + li        { border-top: var(--rule); }

.what { grid-column: 1 / -1; }
.when { grid-column: 1 / 3; }
.when + .what { grid-column: 3 / -1; }

/* M: secondary items */
.what h3 {
  font-size: var(--fs-m);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 4px;
}

/* XL: the primary item of the Experience block */
.s-exp .list > li:first-child h3 {
  font-size: var(--fs-xl);
  line-height: 1;
  letter-spacing: -0.04em;
  margin-bottom: 8px;
}

.dot {
  display: inline-block;
  width: 0.62em;
  height: 0.62em;
  margin-left: 0.55em;
  background: var(--red);
}

/* ---------- Contact ---------- */

.links { row-gap: 8px; }
.links a {
  grid-column: 2 / -1;
  justify-self: start;
  font-weight: 700;
  text-decoration-color: var(--red);
  text-underline-offset: 0.14em;
}
.big {
  font-size: var(--fs-xl);
  line-height: 1;
  letter-spacing: -0.04em;
  text-decoration-thickness: 0.06em;
}
.mid {
  font-size: var(--fs-m);
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-decoration-thickness: 0.08em;
}
.big:hover, .mid:hover { text-decoration-thickness: 0.12em; }

/* ---------- Short windows: tighten so it still fits one screen ---------- */

@media (min-width: 721px) and (max-height: 780px) {
  :root { --fs-s: 12px; --lh: 16px; --fs-m: 16px; --fs-xl: 28px; }
  .frame { row-gap: 20px; padding-top: 10px; }
  .head { margin-bottom: 8px; }
  .blk { padding-top: 8px; }
  .list > li { padding-block: 6px; }
  .what h3 { margin-bottom: 2px; }
  .s-exp .list > li:first-child h3 { margin-bottom: 4px; }
}

/* ---------- Phone: single column, essentials only ---------- */

@media (max-width: 720px) {
  :root { --fs-s: 14px; --lh: 20px; --fs-m: 18px; --fs-xl: 30px; }

  .stage { display: block; }
  .frame {
    display: block;
    border-top: 0;
    padding-top: 0;
  }

  .name { font-size: 24vw; margin-top: 0; }

  .blk,
  .s-exp { border-top: var(--rule); padding-top: 10px; margin-top: 28px; }

  .head,
  .list,
  .links { --n: 12; }
  .head { margin-bottom: 8px; }
  .num { grid-column: 1 / 3; }
  .label { grid-column: 3 / -1; }

  .list > li {
    grid-column: 3 / -1;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    padding-block: 8px;
  }
  .when,
  .when + .what { grid-column: 1 / -1; }

  .links a { grid-column: 3 / -1; }
  .fig { display: none; }
}

/* ---------- Print ---------- */

@media print {
  html, body { background: #fff; }
}
