/* ============================================================
   base.css — shared design system
   Pages: index.html, projects/*.html
   ============================================================ */

:root {
  --ink: #0a0a0a;
  --ink-soft: #1a1a1a;
  --paper: #fafaf8;
  --paper-2: #f2f2ef;
  --paper-3: #ecebe6;
  --rule: #d8d8d4;
  --rule-soft: #e6e5e0;
  --muted: #6b6b6b;
  --muted-2: #8a8a86;
  --accent: #b74c2c;  /* restrained rust — used sparingly, never as fill */

  --serif: "Fraunces", "Times New Roman", serif;
  --sans: "Inter Tight", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;

  --wrap: 1240px;
  --pad-x: 56px;
  --num-col: 160px;

  --dur: .45s;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* ---- i18n: dual-block language switching ----
   default: EN visible, ZH hidden. html[lang="zh"] inverts.
   use class .en or .zh on every translatable block or span. */
.zh { display: none; }
html[lang="zh"] .en { display: none; }
html[lang="zh"] .zh { display: revert; }
/* CJK body tuning when zh is active */
html[lang="zh"] body { font-feature-settings: "halt", "palt"; }

/* ---- meta-bar lang switch ---- */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lang-switch a {
  color: var(--muted);
  cursor: pointer;
  text-decoration: none;
  transition: color .2s var(--ease);
  padding: 2px 4px;
}
.lang-switch a:hover { color: var(--ink); }
.lang-switch a.active { color: var(--ink); font-weight: 500; }
.lang-switch .sep { color: var(--rule); }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  font-feature-settings: "ss01", "cv11";
}
a { color: inherit; text-decoration: none; }
p { margin: 0; }

/* ---- paper noise overlay ---- */
.noise {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999;
  opacity: .05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.85 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* ---- corner registration marks (like print crop marks) ---- */
.crops { position: fixed; inset: 18px; pointer-events: none; z-index: 998; }
.crops::before, .crops::after,
.crops > span::before, .crops > span::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid var(--muted-2);
  opacity: .55;
}
.crops::before { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.crops::after  { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.crops > span { position: absolute; inset: 0; }
.crops > span::before { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; top: auto; }
.crops > span::after  { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; top: auto; }

/* ---- wrap / layout ---- */
.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--pad-x);
  position: relative;
}

/* ---- meta bar ---- */
.meta-bar {
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--muted);
}
.meta-bar .wrap {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  padding: 16px var(--pad-x);
  gap: 32px;
}
.meta-bar .mark {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 20px;
  letter-spacing: -.01em;
  color: var(--ink);
  text-transform: none;
  line-height: 1;
}
.meta-bar .mark .dot-mark { color: var(--accent); }
.meta-bar .center {
  display: flex;
  gap: 28px;
  justify-content: center;
  overflow: hidden;
  white-space: nowrap;
}
.meta-bar .center .sep { color: var(--rule); }
.meta-bar .right { justify-self: end; }
.meta-bar .dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink);
  margin-right: 10px;
  vertical-align: middle;
  animation: pulse 2.2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: .35; transform: scale(.9); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

/* ---- editorial two-column row ---- */
.row { border-bottom: 1px solid var(--rule); }
.row-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 72px var(--pad-x);
  display: grid;
  grid-template-columns: var(--num-col) 1fr;
  gap: 48px;
}
.num {
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .22em;
  color: var(--muted);
  padding-top: 8px;
  position: sticky;
  top: 24px;
  align-self: start;
}
.num .big {
  display: block;
  color: var(--ink);
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: 24px;
  letter-spacing: -.01em;
  margin-top: 10px;
  text-transform: none;
  line-height: 1;
}
.num .rule-short {
  display: block;
  width: 32px;
  height: 1px;
  background: var(--ink);
  margin-top: 14px;
  opacity: .4;
}

/* ---- image slot (placeholder until user drops in art) ---- */
.img-slot {
  position: relative;
  width: 100%;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  overflow: hidden;
}
.img-slot[data-ratio="16:9"] { aspect-ratio: 16 / 9; }
.img-slot[data-ratio="4:3"]  { aspect-ratio: 4 / 3; }
.img-slot[data-ratio="3:2"]  { aspect-ratio: 3 / 2; }
.img-slot[data-ratio="1:1"]  { aspect-ratio: 1 / 1; }
.img-slot[data-ratio="3:4"]  { aspect-ratio: 3 / 4; }
.img-slot[data-ratio="2:3"]  { aspect-ratio: 2 / 3; }
.img-slot[data-ratio="21:9"] { aspect-ratio: 21 / 9; }

.img-slot::before {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px dashed var(--rule);
  pointer-events: none;
}
.img-slot .lbl {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  padding: 24px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .2em;
  color: var(--muted);
  text-align: center;
  line-height: 1.5;
}
.img-slot .lbl .no {
  font-family: var(--serif);
  font-style: italic;
  font-size: 40px;
  letter-spacing: -.01em;
  color: var(--muted-2);
  text-transform: none;
  line-height: 1;
  margin-bottom: 4px;
}
.img-slot .lbl .desc {
  max-width: 280px;
  color: var(--muted-2);
  letter-spacing: .16em;
}
.img-slot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  z-index: 2;
}
/* when an <img> exists in DOM, hide the placeholder label.
   If the image fails to load, its inline onerror removes the <img>,
   so the placeholder .lbl shows again. */
.img-slot img + .lbl { display: none; }

/* ---- footer ---- */
.footer {
  padding: 96px 0 36px;
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
}
.footer .wrap { padding-left: var(--pad-x); padding-right: var(--pad-x); }
.footer-grid {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 72px;
  align-items: start;
}
.footer h2 {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(44px, 5.6vw, 88px);
  line-height: .98;
  letter-spacing: -.028em;
  margin: 0;
  color: var(--ink);
}
.footer h2 .strong { font-style: italic; font-weight: 500; }
.contact {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.9;
}
.contact .c-row {
  display: grid;
  grid-template-columns: 90px 1fr 18px;
  gap: 20px;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  transition: transform .28s var(--ease), color .28s var(--ease);
}
.contact .c-row:first-child { border-top: 1px solid var(--rule); }
.contact .c-row:hover {
  transform: translateX(-6px);
  color: var(--ink);
}
.contact .c-row:hover .arrow { transform: translateX(4px); opacity: 1; }
.contact .k {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .2em;
  font-size: 11px;
  padding-top: 2px;
}
.contact .v { color: var(--ink); }
.contact .arrow {
  color: var(--muted);
  opacity: 0;
  transform: translateX(-4px);
  transition: transform .28s var(--ease), opacity .28s var(--ease);
  padding-top: 2px;
  text-align: right;
}
.copyright {
  margin-top: 72px;
  padding-top: 22px;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .2em;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.copyright .totop {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  text-decoration: none;
}
.copyright .totop:hover { color: var(--accent); }

/* ---- reveal on scroll ---- */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}
.reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* ---- responsive ---- */
@media (max-width: 960px) {
  :root { --pad-x: 28px; --num-col: 100%; }
  .crops { display: none; }
  .row-inner { grid-template-columns: 1fr; gap: 28px; padding: 64px var(--pad-x); }
  .meta-bar .wrap { grid-template-columns: 1fr auto; }
  .meta-bar .center { display: none; }
  .footer { padding: 80px 0 32px; }
  .footer-grid { grid-template-columns: 1fr; gap: 48px; }
  .num { position: static; }
  .num .big { display: inline-block; margin-left: 10px; margin-top: 0; }
}

/* ---- print ---- */
@media print {
  @page { size: A4; margin: 18mm 16mm; }
  body { background: #fff; }
  .noise, .crops { display: none; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .row-inner { padding: 32px 0; page-break-inside: avoid; }
  .footer { padding: 48px 0 16px; background: transparent; }
  .meta-bar { display: none; }
  a { color: inherit; }
}
