/* ==========================================================================
   Julia Hung — Direction 1A "Register"
   Every value here is from the design specification. There is no accent
   colour, no dark mode, no shadow, no rounding, and no motion except colour.
   If a rule cannot be traced to a line of the spec, it does not belong.
   ========================================================================== */

/* --- Tokens -------------------------------------------------------------- */

:root {
  --paper:    #FBFBFA;  /* page ground                        */
  --ink:      #121212;  /* titles, opening rules              */
  --body:     #55524D;  /* metadata, running text             */
  --mute:     #8A8780;  /* labels, inactive nav, underlines   */
  --hover:    #F2F1ED;  /* index row wash                     */
  --hairline: #E4E2DD;  /* rules between rows                 */

  --sans: "Helvetica Neue", Helvetica, Arial, "Noto Sans TC",
          "PingFang TC", "Microsoft JhengHei", sans-serif;

  --max: 1180px;        /* content max-width                  */
  --pad: 56px;          /* page padding, desktop              */
  --gutter: 24px;       /* 12-column gutter                   */
  --meta-col: 260px;    /* sticky meta column on work detail  */
  --label-col: 78px;    /* label column inside the meta block */

  /* Section gaps differ by page family: home / index / detail. */
  --gap-home: 80px;
  --gap-index: 64px;
  --gap-detail: 56px;

  --top: 44px;          /* a page opens 44px below the top edge */
  --tail: 64px;         /* and ends 64px after its last element */
}

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

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--body);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; width: 100%; height: auto; border: 0; }

/* Colour is the only animated property, anywhere on the site. */
a, .row {
  transition: color 120ms linear, background-color 120ms linear,
              border-color 120ms linear;
}

a { color: inherit; text-decoration: none; }

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

/* --- Type roles ---------------------------------------------------------- */

.t-display {          /* work and exhibition titles, current-show name */
  font-size: 24px; line-height: 1.2; letter-spacing: -0.01em;
  font-weight: 400; color: var(--ink);
}
.work-title__series {
  display: block;
  margin-top: 0.25em;
  font-size: 0.68em;
  font-style: normal;
  letter-spacing: 0;
  color: var(--mute);
}
.t-lead {             /* home statement, exhibition intro */
  font-size: 19px; line-height: 1.55; letter-spacing: -0.005em;
  color: var(--ink); max-width: 640px;
}
.t-lead--sm {         /* the same voice, set smaller: about-page bio */
  font-size: 15px; line-height: 1.6;
}
.t-row {              /* titles inside an index */
  font-size: 17px; line-height: 1.3; color: var(--ink);
}
.t-body {             /* venue lines, captions, CV entries */
  font-size: 13px; line-height: 1.7; color: var(--body);
  max-width: 70ch;
}
.poem { line-height: 1.45; }
.t-meta {             /* navigation, links, next/prev */
  font-size: 12px; line-height: 1.4; letter-spacing: 0.10em;
  text-transform: uppercase;
}
.t-label {            /* "On view", "Material", section heads */
  font-size: 11px; line-height: 1.4; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--mute);
}

/* --- Page frame ---------------------------------------------------------- */

.page {
  max-width: var(--max);
  margin: 0 auto;
  padding: var(--top) var(--pad) var(--tail);
}

.rule      { height: 1px; background: var(--hairline); border: 0; margin: 0; }
.rule--ink { background: var(--ink); }   /* opens a section */

/* The recurring 8/4 split: image or index left, metadata right. */
.split {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
}
.split > .col-8 { grid-column: span 8; }
.split > .col-4 { grid-column: span 4; }

/* --- Header -------------------------------------------------------------- */
/* Wordmark left, nav right, baseline-aligned. Not sticky, no border. */

.hdr {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gutter);
  flex-wrap: wrap;
}

/* The wordmark is the largest type on the site — above .t-display. It scales
   with the viewport so it never crowds the nav on the way down to 600px,
   below which the nav takes its own row and the mark has the line to itself. */
.hdr__mark {
  font-size: clamp(24px, 3.4vw, 34px);
  line-height: 1.1; letter-spacing: -0.005em;
  font-weight: 500; color: var(--ink);
}
/* min-width:0 lets the nav shrink below its content width so wrapping can
   actually happen; without it a flex item refuses and the page overflows. */
.hdr__nav {
  display: flex; align-items: baseline; gap: 24px;
  flex-wrap: wrap; justify-content: flex-end;
  flex: 1 1 auto; min-width: 0;
}
.hdr__nav a { color: var(--mute); }
.hdr__nav a:hover { color: var(--ink); }
.hdr__nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  padding-bottom: 2px;          /* underline sits 2px below the baseline */
}

/* --- Index row ----------------------------------------------------------- */
/* Work title and year; the whole row is the hit area. */

.rows { border-top: 1px solid var(--ink); }   /* ink rule opens the group */

.row {
  display: grid;
  grid-template-columns: 1fr 120px;
  gap: var(--gutter);
  align-items: baseline;
  padding: 16px 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--body);
}
.row:hover { background: var(--hover); }
.row__title { color: var(--ink); }
.row__year  { text-align: right; font-size: 13px; line-height: 1.7; }

/* --- Recovered post body -------------------------------------------------- */
/* Body copy carried over from the Wix blog: headings, paragraphs, lists and
   the publisher's own links, set in the site's register rather than Wix's. */

.post > * + * { margin-top: 16px; }
.post__h {
  margin-top: 32px;
  font-size: 17px; line-height: 1.4; font-weight: 500; color: var(--ink);
  max-width: 70ch;
}
.post .fig { margin-top: 24px; }
.post .fig img { width: 100%; height: auto; }
.lnk-inline {                 /* inline in a sentence, so it keeps its case */
  color: var(--ink);
  border-bottom: 1px solid var(--mute);
}
.lnk-inline:hover { border-bottom-color: var(--ink); }

/* --- Press row ----------------------------------------------------------- */
/* Outlet over date in the gutter, headline at reading size beside them. */

.press-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--gutter);
}

.prow {
  display: grid;
  grid-template-columns: var(--meta-col) 1fr;
  gap: var(--gutter);
  padding: 24px 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--body);
}
.prow:hover { background: var(--hover); }
.prow__outlet { font-size: 14px; line-height: 1.6; color: var(--ink); }
.prow__when {                 /* tabular, so the dates align down the column */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.6; color: var(--mute);
}
.prow__title { max-width: 60ch; }

/* "Solo" sets as a label chip after the title, not a pill. */
.chip {
  margin-left: 10px;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--mute);
  white-space: nowrap;
}

/* --- Meta block ---------------------------------------------------------- */
/* Label / value pairs, fixed label column. Order: Material, Dimensions,
   Shown. Closed by a hairline and a short written note. */

.meta { display: grid; grid-template-columns: var(--label-col) 1fr; gap: 0 16px; }
.meta dt {
  font-size: 11px; line-height: 1.7; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--mute);
}
.meta dd { font-size: 13px; line-height: 1.7; color: var(--body); }

.meta__note {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
  font-size: 13px; line-height: 1.7; color: var(--body);
}

/* --- Imagery ------------------------------------------------------------- */
/* Square-cornered, no border, no shadow, no rounding, fixed ratios only. */

.fig { margin: 0; }
.fig img { background: var(--hover); }
.fig--16-10 img { aspect-ratio: 16 / 10; object-fit: cover; }
.fig--4-3   img { aspect-ratio: 4 / 3;   object-fit: cover; }
.fig--3-2   img { aspect-ratio: 3 / 2;   object-fit: cover; }
.fig--1-1   img { aspect-ratio: 1 / 1;   object-fit: cover; }
.fig--3-4   img { aspect-ratio: 3 / 4;   object-fit: cover; }
/* Preserve more of the portrait-oriented supporting photographs. */
.bloom-gallery > .pair .fig img,
.artificial-phenomena-gallery > .pair .fig img { aspect-ratio: 3 / 4; }
.will-looped-gallery > .pair .fig img,
.will-looped-gallery > .fig:not(:first-child) img { aspect-ratio: 2 / 3; }
.inter-symbiosis-gallery .fig img { aspect-ratio: 2 / 3; }
.untamed-gallery > .pair { width: calc(100% + 48px); }
/* Airy Disk's two closing portraits share the left one's full 4:5 frame; the
   taller 2:3 shot on the right loses mostly top, keeping the wire tail. */
.airydisk-portraits .fig img { aspect-ratio: 4 / 5; }
.airydisk-portraits .fig:last-child img { object-position: center 80%; }
/* Untamed's closing portraits share the right one's full frame; the slightly
   taller shot on the left gives up a sliver at the bottom to match. */
.untamed-portraits .fig img { aspect-ratio: 3543 / 5147; }
.untamed-portraits .fig:first-child img { object-position: center top; }
/* Taipei Dangdai's closing pair are both 2:3 portraits; show them whole. */
.taipeidangdai-portraits .fig img { aspect-ratio: 2 / 3; }
/* When Night Falls' two portraits share the right one's full 4:5 frame; the
   taller 2:3 shot on the left gives up bare floor at the bottom to match. */
.whennightfalls-portraits .fig img { aspect-ratio: 4 / 5; }
.whennightfalls-portraits .fig:first-child img { object-position: center top; }
/* Artificial Phenomena's closing portraits share the left one's full 3:4
   frame; Spun Twist (2:3) on the right loses mostly wall above the sculpture's
   tip, with a sliver off the base so the tip stays in. */
.artificial-phenomena-portraits .fig img { aspect-ratio: 3 / 4; }
.artificial-phenomena-portraits .fig:last-child img { object-position: center 85%; }
/* An Unusual Knot: Torus is cut to its neighbour's 4:3, framed on the wall
   piece (which sits just above centre); the closing portraits stay 2:3. */
.an-unusual-knot-wide-tall .fig:last-child img { object-position: center 40%; }
.an-unusual-knot-portraits .fig img { aspect-ratio: 2 / 3; }
/* A pair that stands level without cropping the art: each figure carries a
   ratio as --ar (width / height) and grows by it, so the two share a height.
   --ar is the photo's own ratio, or its neighbour's when a little background
   is trimmed to even up the widths; --pos says where that trim comes from. */
.pair--fit { display: flex; align-items: flex-start; }
.pair--fit > .fig { flex: var(--ar) 1 0; min-width: 0; }
.pair--fit > .fig img {
  aspect-ratio: var(--ar); object-fit: cover; object-position: var(--pos, center);
}

.video-embed { position: relative; aspect-ratio: 4 / 3; background: var(--hover); }
.video-embed iframe { width: 100%; height: 100%; border: 0; display: block; }

.fig figcaption {
  margin-top: 8px;
  font-size: 11px; line-height: 1.4; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--mute);
}
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter); }
.fig--half { width: calc((100% - var(--gutter)) / 2); }

/* --- Links --------------------------------------------------------------- */

.lnk {
  font-size: 12px; line-height: 1.4; letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--body);
  border-bottom: 1px solid var(--mute);
  padding-bottom: 1px;
}
.lnk:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* Two PDFs offered at the head of the CV: the same link, set in a row. */
.downloads {
  display: flex; flex-wrap: wrap; gap: 24px;
  margin-top: 16px;
}

/* Next/prev sits at the foot of a detail page, right-aligned, named. */
.nextprev {
  display: flex; justify-content: space-between; gap: var(--gutter);
  margin-top: var(--gap-detail);
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}
.nextprev > :only-child { margin-left: auto; }

/* --- Card grid ------------------------------------------------------------ */
/* The one place a grid is allowed: three columns, one uniform tile. Works are
   square; exhibitions take --wide, because an install view is a room and a
   square centre crop throws the room away. */

.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 48px var(--gutter); }
.grid .fig img {
  width: 100%; height: auto;
  aspect-ratio: 1 / 1; object-fit: cover; object-position: center;
}
.grid .card--debris .fig img { object-position: center 56%; }
.grid .card--inter-symbiosis .fig img {
  object-fit: contain;
  background: #c8caf0;
}
.grid--wide .fig img { aspect-ratio: 4 / 3; }
.card__title { margin-top: 12px; font-size: 17px; line-height: 1.3; color: var(--ink); }
.card__venue { font-size: 13px; line-height: 1.7; color: var(--body); }
.card__year  { font-size: 13px; line-height: 1.7; color: var(--mute); }

/* Filters set as meta-case text, no pills. */
.filters { display: flex; gap: 20px; flex-wrap: wrap; }
.filters button {
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: var(--mute);
}
.filters button:hover, .filters button[aria-pressed="true"] { color: var(--ink); }

/* --- News ---------------------------------------------------------------- */
/* Grouped by year. The numeral and its count open the group, an ink rule
   closes the heading, and the year's entries and the one picture that
   illustrates them sit under it in two columns. */

.news-year__head { display: flex; align-items: baseline; gap: 16px; }
.news-year__n {
  font-size: 28px; line-height: 1.1; letter-spacing: -0.01em;
  color: var(--ink);
}
.news-year .rule--ink { margin-top: 10px; }

/* 400px is the picture; the text column takes what is left. */
.news-year__cols {
  display: grid;
  grid-template-columns: 1fr 400px;
  gap: 48px;
  align-items: start;
  margin-top: 28px;
}

/* The newest entry, set at reading size. */
.news-lead__title {
  margin-top: 12px;
  font-size: 22px; line-height: 1.35; letter-spacing: -0.005em;
  font-weight: 400; color: var(--ink);
  max-width: 34ch;
}
.news-lead__sum { margin-top: 14px; max-width: 46ch; }
.news-lead .lnk { display: inline-block; margin-top: 18px; }

/* --- Section rhythm ------------------------------------------------------ */
/* Section gaps are a property of the page family, not of which two elements
   happen to be adjacent: 80px on home, 64px on index pages, 56px on detail.
   Setting it once on .page keeps every boundary equal, including the ones
   around a rule or a heading block. */

.page            { --gap: var(--gap-index); }
.page--detail    { --gap: var(--gap-detail); }

.page > * + *    { margin-top: var(--gap); }
.page > .hdr + * { margin-top: var(--gap-home); }

.stack > * + * { margin-top: 24px; }
.mt-2 { margin-top: 16px; }
.stack--tight > * + * { margin-top: 8px; }

/* --- Work detail --------------------------------------------------------- */
/* 260px meta column, sticky from the second screen, then the image stack. */

.detail { display: grid; grid-template-columns: var(--meta-col) 1fr; gap: 48px; }
.detail__meta { position: sticky; top: var(--top); align-self: start; }

/* --- CV ------------------------------------------------------------------ */
/* Two-column year list: year left, entry right. */

.cv { display: grid; grid-template-columns: 64px 1fr; gap: 0 16px; }
.cv dt { font-size: 13px; line-height: 1.7; color: var(--mute); }
.cv dd { font-size: 13px; line-height: 1.7; color: var(--body); }
.cv dd + dd { margin-left: 0; }

/* --- Contact ------------------------------------------------------------- */
/* Address and marks left, enquiry form right. The form is the only place on
   the site a visitor can type, so it borrows the register rather than
   inventing one: every field is a label over a hairline — a .meta row made
   writable — and an ink rule opens the block exactly as one opens an index. */

.contact {
  display: grid;
  grid-template-columns: 4fr 7fr;
  gap: 72px;
  align-items: start;
}

/* The address is the largest type on the page: above .t-display, below the
   wordmark, which stays the largest thing on the site. Its rule is the width
   of the address, not of the column, so it reads as an underline. */
.contact__email {
  display: inline-block;
  font-size: clamp(21px, 2.4vw, 28px);
  line-height: 1.2; letter-spacing: -0.005em;
  color: var(--ink);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 10px;
}
.contact__email:hover { border-bottom-color: var(--ink); }

/* The marks sit in the body register, not the mute one the nav uses: they
   are the address's companions rather than a second navigation. */
.socials { display: flex; gap: 46px; margin-top: 44px; }
.socials a { display: block; color: var(--body); }
.socials a:hover { color: var(--ink); }
.socials svg { display: block; width: 20px; height: 20px; }

/* --- Form ---------------------------------------------------------------- */

.form { border-top: 1px solid var(--ink); padding-top: 28px; }
.form > * + * { margin-top: 28px; }

.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }

.field input, .field select, .field textarea {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 0 0 9px;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  border-radius: 0;
  background: none;
  font-family: inherit;
  font-size: 15px; line-height: 1.6;
  color: var(--ink);
  transition: border-color 120ms linear;
}
.field input::placeholder, .field textarea::placeholder {
  color: var(--mute); opacity: 1;      /* Firefox dims placeholders by default */
}
.field input:hover,  .field select:hover,  .field textarea:hover,
.field input:focus,  .field select:focus,  .field textarea:focus {
  border-bottom-color: var(--ink);
}

/* The one affordance the reference design leaves out. A select that looks
   exactly like a text field is a trap, so it keeps a caret — mute, 9px, and
   invisible until you go looking for it. */
.field select {
  appearance: none; -webkit-appearance: none;
  padding-right: 20px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9 6'%3E%3Cpath d='M.8.8 4.5 4.5 8.2.8' fill='none' stroke='%238A8780' stroke-width='1.1'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1px top 9px;
  background-size: 9px 6px;
}

/* The message closes the form on an ink rule, answering the one above it. */
.field textarea {
  min-height: 168px;
  resize: vertical;
  border-bottom-color: var(--ink);
}

/* The note sits left of SEND and appears only once the button is pressed,
   so the row is the button alone until there is something to say. */
.form__actions {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 32px;
  margin-top: 40px;
}
.form__actions .btn { margin-left: auto; flex: none; }

.form__note { max-width: 46ch; font-size: 13px; line-height: 1.7; color: var(--body); }
.form__note[hidden] { display: none; }

/* The only filled element anywhere on the site: ink block, paper text,
   square corners. Colour is still the only thing that moves. */
.btn {
  appearance: none;
  border: 0; border-radius: 0;
  padding: 16px 38px;
  background: var(--ink);
  color: var(--paper);
  font-family: inherit;
  font-size: 12px; line-height: 1.4; letter-spacing: 0.10em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 120ms linear;
}
.btn:hover { background: var(--body); }

/* Off the screen, still in the accessibility tree: the page heading the
   design has no room for, and the honeypot a spam bot fills in and a person
   never sees. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

/* --- Responsive ---------------------------------------------------------- */

@media (max-width: 900px) {
  :root { --pad: 24px; }

  .t-display { font-size: 21px; }          /* the only size that moves */

  /* 8/4 splits stack, image first. */
  .split > .col-8, .split > .col-4 { grid-column: 1 / -1; }

  /* The year stays aligned to the right of the work title. */
  .prow { grid-template-columns: 1fr; gap: 8px; padding: 20px 0; }
  .row { grid-template-columns: 1fr 120px; row-gap: 4px; }
  .row__title { grid-column: 1; }
  .row__year  { grid-column: 2; grid-row: 1; }

  /* The year's picture drops below its entries. */
  .news-year__cols { grid-template-columns: 1fr; gap: 32px; }
  .news-lead__title { font-size: 20px; }

  /* Address over form, and the form takes the full measure. */
  .contact { grid-template-columns: 1fr; gap: 48px; }

  .grid   { grid-template-columns: repeat(2, 1fr); }
  .detail { grid-template-columns: 1fr; gap: 32px; }
  .detail__meta { position: static; }
}

@media (max-width: 600px) {
  /* The works grid holds two columns all the way down — smaller tiles, but
     the shape of the index stays readable. */
  .grid { gap: 28px 16px; }
  .grid .card__title { font-size: 15px; }
  .pair { grid-template-columns: 1fr; }
  .untamed-gallery > .pair { width: 100%; }
  .pair--fit { flex-direction: column; }
  .pair--fit > .fig { flex: none; width: 100%; }
  .fig--half { width: 100%; }

  /* Nav stays a line of text items at 11px — it never becomes a hamburger.
     Below this width it takes its own row under the wordmark. */
  .hdr { row-gap: 16px; }
  .hdr__nav {
    flex: 1 0 100%;
    justify-content: flex-start;
    gap: 14px; font-size: 11px; letter-spacing: 0.08em;
  }

  /* The year column no longer needs a fixed 120px once the venue has moved
     to its own line. */
  .row { grid-template-columns: 1fr auto; column-gap: 16px; }

  /* Name and email stop sharing a line; SEND takes the full width rather
     than sitting as a small block against the right edge. */
  .field-pair { grid-template-columns: 1fr; gap: 28px; }
  .form__actions { flex-direction: column; align-items: stretch; gap: 20px; }
  .btn { width: 100%; }
}

/* Handset widths: the six nav items measure 366px at 11px/0.08em/14px, so they
   stop fitting one line below roughly 430px. Rather than let them wrap, the row
   holds: the page padding tightens, the type scales down to a 9px floor, the
   tracking eases to 0.06em, and space-between spends whatever width is left on
   the gaps. At 320px — the narrowest phone worth serving — the six labels
   measure 242px inside 280px of content width, leaving 7px between each. */

@media (max-width: 430px) {
  :root { --pad: 20px; }

  .hdr__nav {
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 6px;
    font-size: clamp(9px, 2.6vw, 11px);
    letter-spacing: 0.06em;
  }
  .hdr__nav a { white-space: nowrap; }
}

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

@media print {
  .hdr__nav, .nextprev, .filters { display: none; }
  a { border: 0; }
}
