/* ---------------------------------------------------------------------------
   Po-Hsiang (Barnett) Chiu — personal site
   Palette: "blueprint" — cool near-white / blue-black grounds, ink-blue accent,
   one muted copper reserved exclusively for private, unlinked projects.
   --------------------------------------------------------------------------- */

:root {
  --paper:      #f7f8fa;
  --plate:      #eef1f5;
  --ink:        #131a24;
  --ink-2:      #56626f;
  --ink-3:      #7d8894;
  --hair:       #dbe1e8;
  --hair-soft:  #e6eaf0;
  --signal:     #1f5fa8;
  --signal-dim: #7ba0cc;
  --copper:     #9a5730;

  --cc-op: 0.20;      /* masthead formation */
  --cc-op-sm: 0.15;   /* in-page formations, quieter behind body text */

  --measure: 36rem;   /* reading column — ~68 characters */
  --page: 62rem;      /* outer container; the schematic uses the full width */
  --rail: 8.5rem;
  --gap: 2rem;

  --f-display: "Newsreader", Georgia, "Times New Roman", serif;
  --f-body: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #0d1219;
    --plate:      #141c26;
    --ink:        #e3e9f0;
    --ink-2:      #98a5b3;
    --ink-3:      #75828f;
    --hair:       #232d3a;
    --hair-soft:  #1b242e;
    --signal:     #6fa8e8;
    --signal-dim: #3c5f88;
    --copper:     #d08b5f;
    --cc-op:      0.26;
    --cc-op-sm:   0.20;
  }
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.6rem 1rem;
  z-index: 10;
}
.skip:focus { left: 0; }

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

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* --- links ------------------------------------------------------------- */

a {
  color: var(--signal);
  text-decoration: none;
  border-bottom: 1px solid var(--signal-dim);
  transition: border-color 120ms ease, color 120ms ease;
}
a:hover { border-bottom-color: var(--signal); }
a:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  border-radius: 1px;
}

/* --- crop formations ---------------------------------------------------- */

/* Crop circles sit behind the page. Each is delivered as a MASK, so the figure
   takes its colour from the theme token and one file serves light and dark.
   A section opts in with `.field` plus a `.f-*` modifier below. */

.field { position: relative; overflow: hidden; }  /* clip: also guards the page width */
.field > * { position: relative; z-index: 1; }

.field::before {
  content: "";
  position: absolute;
  width: var(--f-w);
  aspect-ratio: var(--f-ar, 1);
  top: var(--f-top, auto);
  right: var(--f-right, auto);
  bottom: var(--f-bottom, auto);
  left: var(--f-left, auto);
  background-color: var(--signal);
  opacity: var(--f-op, var(--cc-op-sm));
  /* Two mask layers intersected: the formation, and a radial fade so it dissolves
     into the page instead of meeting the clip edge as a hard line. */
  -webkit-mask-image: var(--f-src),
                      radial-gradient(ellipse at 52% 46%, #000 50%, rgba(0,0,0,0.62) 74%, transparent 92%);
  mask-image: var(--f-src),
              radial-gradient(ellipse at 52% 46%, #000 50%, rgba(0,0,0,0.62) 74%, transparent 92%);
  -webkit-mask-size: contain, 100% 100%;
  mask-size: contain, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
  mask-repeat: no-repeat, no-repeat;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  /* Pinned, not left to match-source: the SVGs are coloured so they preview on
     their own, and only their alpha may be allowed to matter. */
  mask-mode: alpha, alpha;
  pointer-events: none;
  z-index: 0;
}

/* placements */
.f-cosmos   { --f-src: url("assets/crop-cosmos.svg");
              --f-w: min(31rem, 74vw);  --f-top: -13%;  --f-right: -1%;
              --f-op: var(--cc-op); }
.f-helix    { --f-src: url("assets/crop-helix.svg");
              --f-w: min(22rem, 60vw);  --f-top: 5%;    --f-right: -4%; }
.f-13moons  { --f-src: url("assets/crop-13moons.svg");
              --f-w: min(23rem, 62vw);  --f-top: 8%;    --f-right: -5%; }
.f-trine    { --f-src: url("assets/crop-trine.svg");
              --f-w: min(17rem, 50vw);  --f-top: 30%;   --f-right: -4%; }
.f-cipher   { --f-src: url("assets/crop-cipher.svg");
              --f-w: min(44rem, 100%);  --f-ar: 1240 / 260;
              --f-bottom: -6%; --f-right: -2%;
              --f-op: calc(var(--cc-op-sm) + 0.02); }

/* --- masthead ---------------------------------------------------------- */

.masthead {
  padding: clamp(3.5rem, 9vw, 6.5rem) 0 2.75rem;
  margin-left: 0;
}

@media (min-width: 56rem) {
  .masthead { padding-left: calc(var(--rail) + var(--gap)); }
}

.eyebrow {
  margin: 0 0 1.1rem;
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.masthead h1 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(2.4rem, 7vw, 3.75rem);
  line-height: 1.06;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

.masthead h1 .alt {
  color: var(--ink-2);
  font-weight: 400;
  font-style: italic;
}

.lede {
  max-width: var(--measure);
  margin: 1.5rem 0 0;
  font-size: 1.075rem;
  line-height: 1.6;
  color: var(--ink);
}

.idlinks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  margin-top: 1.8rem;
  font-family: var(--f-mono);
  font-size: 0.8rem;
}

/* --- section scaffold -------------------------------------------------- */

.band {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.85rem;
  padding: 2.75rem 0;
  border-top: 1px solid var(--hair);
}

@media (min-width: 56rem) {
  .band {
    grid-template-columns: var(--rail) minmax(0, 1fr);
    column-gap: var(--gap);
  }
  /* The schematic needs every pixel it can get. Rather than collapsing the band,
     the figure alone breaks out of the content column and back across the rail,
     so the rail label and heading stay where every other section puts them. */
  .band.wide .schematic { margin-left: calc(-1 * (var(--rail) + var(--gap))); }
}

.rail { padding-top: 0.35rem; }

.railtag {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}

.col { min-width: 0; max-width: var(--measure); }
.bleed .col { max-width: none; }

.col > h2 {
  margin: 0 0 0.9rem;
  font-family: var(--f-display);
  font-weight: 500;
  font-size: 1.65rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

.col p { margin: 0 0 0.95rem; }
.col > p:last-child { margin-bottom: 0; }

.now {
  display: inline-block;
  vertical-align: 0.32em;
  margin-left: 0.55rem;
  font-family: var(--f-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--signal);
  border: 1px solid var(--signal-dim);
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
}

.thesis {
  max-width: var(--measure);
  color: var(--ink-2);
  font-size: 1.02rem;
  border-left: 2px solid var(--hair);
  padding-left: 1rem;
}
.thesis strong { color: var(--ink); font-weight: 500; }

.note {
  max-width: var(--measure);
  font-size: 0.92rem;
  color: var(--ink-2);
}

/* A trailing note is a separate remark, not the tail of the block above it. */
.proj + .note,
.pubs + .note { margin-top: 1.75rem; }

/* --- projects ---------------------------------------------------------- */

.proj {
  max-width: var(--measure);
  margin-top: 2rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hair-soft);
}

.proj h3 {
  margin: 0 0 0.15rem;
  font-family: var(--f-mono);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}

.proj h3 a { border-bottom-color: transparent; }
.proj h3 a:hover { border-bottom-color: var(--signal); }

.proj .meta {
  margin: 0 0 0.8rem;
  font-family: var(--f-mono);
  font-size: 0.73rem;
  color: var(--ink-3);
}
.proj .meta code { font: inherit; }

.proj p { max-width: var(--measure); }

.proj .links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.2rem;
  margin-bottom: 0;
  font-family: var(--f-mono);
  font-size: 0.78rem;
}

.tag {
  margin-left: 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--copper);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
  vertical-align: 0.14em;
}

.is-private { border-top-style: dashed; }
.is-private h3 { color: var(--ink-2); }

/* --- schematic --------------------------------------------------------- */

.schematic { margin: 0; }

/* Focusable so the diagram can be scrolled from the keyboard (WCAG 2.1.1). */
.scroller {
  overflow-x: auto;
  padding-bottom: 0.5rem;
  background: var(--plate);
  border: 1px solid var(--hair);
  border-radius: 2px;
}
.scroller:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.schematic svg {
  display: block;
  width: 100%;
  min-width: 720px;
  height: auto;
  padding: 0.75rem 1rem;
}

.schematic .node rect {
  fill: var(--paper);
  stroke: var(--hair);
  stroke-width: 1;
}
.schematic .node rect.hot { stroke: var(--signal); }
.schematic .node rect.priv {
  stroke: var(--copper);
  stroke-dasharray: 3 3;
  fill: none;
}

.schematic .node text {
  fill: var(--ink);
  font-family: var(--f-mono);
  font-size: 16px;
  text-anchor: middle;
}

.schematic .edge path {
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 1;
}
.schematic .edge path.dash { stroke-dasharray: 4 4; stroke: var(--signal-dim); }
.schematic .edge path.bi { stroke: var(--copper); }

/* Arrowheads. Filled from theme tokens rather than context-stroke, so the
   colour tracks light/dark without relying on SVG 2 paint servers. */
.schematic .mk path { fill: var(--ink-3); stroke: none; }
.schematic .mk-dash path { fill: var(--signal-dim); }
.schematic .mk-bi path { fill: var(--copper); }

.schematic .edgelab text {
  fill: var(--ink-3);
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.schematic .tracklab text {
  fill: var(--ink-3);
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
  margin-top: 0.75rem;
  font-size: 0.82rem;
  color: var(--ink-3);
}

.key {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--f-mono);
  font-size: 0.72rem;
}

.sw {
  display: inline-block;
  width: 1.5rem;
  height: 0.85rem;
  border-radius: 2px;
}
.priv-sw { border: 1px dashed var(--copper); }

/* --- publications ------------------------------------------------------ */

.pubs {
  list-style: none;
  max-width: var(--measure);
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
}

.pubs .pt { margin: 0 0 0.15rem; line-height: 1.45; }
.pubs .pv {
  margin: 0;
  font-family: var(--f-mono);
  font-size: 0.74rem;
  color: var(--ink-3);
}

/* --- footer ------------------------------------------------------------ */

footer {
  padding: 2.5rem 0 4rem;
  border-top: 1px solid var(--hair);
  font-size: 0.85rem;
  color: var(--ink-2);
}

@media (min-width: 56rem) {
  footer { padding-left: calc(var(--rail) + var(--gap)); }
}

footer p { margin: 0 0 0.35rem; }
footer .fine { color: var(--ink-3); font-size: 0.8rem; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
