/* ------------------------------------------------------------------
   Tokens. Light by default, dark when the visitor's device asks for it.
   ------------------------------------------------------------------ */
:root {
  --bg: #fbfbfd;
  --surface: #ffffff;
  --frame: #f2f2f4;
  --ink: #1d1d1f;
  --muted: #6e6e73;
  --line: #d2d2d7;
  --accent: #0066cc;
  --overlay: rgba(251, 251, 253, 0.74);
  --scrim: linear-gradient(to top, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0) 70%);
  --shadow-art: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.16)) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.08));
  --good: #1d7a46;
  --bad: #c0352b;

  --sans: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, sans-serif;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);      /* quick start, long soft landing */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --spring: cubic-bezier(0.18, 1.12, 0.32, 1);  /* a small, settling overshoot */
  --gutter: clamp(16px, 4vw, 48px);
  --max: 1320px;
  --nav-h: 52px;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #161617;
    --frame: #111113;
    --ink: #f5f5f7;
    --muted: #a1a1a6;
    --line: #333336;
    --accent: #2997ff;
    --overlay: rgba(0, 0, 0, 0.72);
    --shadow-art: drop-shadow(0 18px 30px rgba(0, 0, 0, 0.6));
    --good: #4cc27e;
    --bad: #ff6b5e;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--nav-h) + 12px); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 17px/1.47 var(--sans);
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, p { margin: 0; }
img { display: block; max-width: 100%; height: auto; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent) 70%, transparent); outline-offset: 3px; border-radius: 6px; }
::selection { background: color-mix(in srgb, var(--accent) 24%, transparent); }

.skip { position: absolute; left: 12px; top: -60px; z-index: 100; padding: 10px 16px; border-radius: 999px; background: var(--ink); color: var(--bg); transition: top 0.2s var(--ease); }
.skip:focus { top: 10px; text-decoration: none; }

/* ------------------------------------------------------------------
   Navigation: translucent glass that gains a hairline once you scroll.
   ------------------------------------------------------------------ */
.nav {
  position: sticky; top: 0; z-index: 30;
  height: var(--nav-h);
  background: var(--overlay);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid transparent;
}
@supports (animation-timeline: scroll()) {
  .nav { animation: nav-line linear both; animation-timeline: scroll(root); animation-range: 0 120px; }
  @keyframes nav-line { to { border-bottom-color: var(--line); } }
}
.nav.is-scrolled { border-bottom-color: var(--line); } /* set by site.js where the above is unsupported */
.nav__inner { max-width: var(--max); height: 100%; margin: 0 auto; padding: 0 var(--gutter); display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.nav__brand { color: var(--ink); font-weight: 600; font-size: 19px; letter-spacing: -0.02em; }
.nav__brand:hover { text-decoration: none; opacity: 0.7; }
.nav__links { display: flex; gap: clamp(18px, 3vw, 34px); font-size: 13px; }
.nav__links a { color: var(--ink); opacity: 0.8; transition: opacity 0.25s var(--ease); }
.nav__links a:hover { opacity: 1; text-decoration: none; }

/* ------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------ */
.hero {
  min-height: calc(92svh - var(--nav-h));
  display: grid; place-content: center; justify-items: center; gap: 18px;
  padding: 80px var(--gutter) 60px; text-align: center;
}
.hero__eyebrow { color: var(--muted); font-size: clamp(17px, 2vw, 21px); font-weight: 500; letter-spacing: 0; }
.hero__title {
  font-size: clamp(64px, 14vw, 180px); line-height: 0.95; font-weight: 650; letter-spacing: -0.055em;
  background: linear-gradient(180deg, var(--ink) 30%, color-mix(in srgb, var(--ink) 55%, transparent));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  /* The fade is painted only inside this box, and the tight spacing pulls the box in past the
     last letter's edge (a Q's tail, say). The padding gives every letter room to show whole. */
  padding: 0 0.08em 0.1em;
}
.hero__statement { max-width: 30ch; font-size: clamp(21px, 2.6vw, 28px); line-height: 1.25; color: var(--muted); font-weight: 450; letter-spacing: -0.02em; }
.hero__cue { margin-top: 26px; font-size: 17px; }
.hero__cue span { display: inline-block; transition: transform 0.4s var(--ease); }
.hero__cue:hover { text-decoration: none; }
.hero__cue:hover span { transform: translateY(4px); }

/* ------------------------------------------------------------------
   Sections
   ------------------------------------------------------------------ */
.section { max-width: var(--max); margin: 0 auto; padding: clamp(64px, 10vw, 140px) var(--gutter); }
.section__title { font-size: clamp(40px, 6vw, 64px); line-height: 1.05; font-weight: 650; letter-spacing: -0.04em; margin-bottom: clamp(28px, 4vw, 56px); }
.empty { color: var(--muted); font-size: 21px; }

/* ------------------------------------------------------------------
   Gallery. Every piece sits in the same calm frame, whatever its shape,
   so the order the artist chose reads left to right.
   ------------------------------------------------------------------ */
.gallery { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(28px, 3.5vw, 48px) clamp(20px, 2.6vw, 36px); grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }
.tile { min-width: 0; }
.tile__link { position: relative; display: block; border-radius: 22px; overflow: hidden; color: inherit; isolation: isolate; }
.tile__link:hover { text-decoration: none; }
.tile__frame { display: block; aspect-ratio: 4 / 5; background: var(--frame); }
.tile__frame picture { display: contents; }
.tile__frame img {
  width: 100%; height: 100%; object-fit: contain; padding: 11%;
  filter: var(--shadow-art);
  transition: transform 0.9s var(--ease);
}
.tile__overlay {
  position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 10px;
  padding: 26px; color: #fff; background: var(--scrim);
  opacity: 0; transition: opacity 0.5s var(--ease);
  pointer-events: none;
}
.tile__desc { font-size: 15px; line-height: 1.45; transform: translateY(14px); transition: transform 0.6s var(--ease); text-wrap: pretty; }
.tile__more { align-self: flex-start; font-size: 13px; font-weight: 600; padding: 7px 14px; border-radius: 999px; background: rgba(255, 255, 255, 0.22); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); transform: translateY(14px); transition: transform 0.6s 0.04s var(--ease); }
@media (hover: hover) {
  .tile__link:hover img, .tile__link:focus-visible img { transform: scale(1.04); }
  .tile__link:hover .tile__overlay, .tile__link:focus-visible .tile__overlay { opacity: 1; }
  .tile__link:hover .tile__desc, .tile__link:hover .tile__more,
  .tile__link:focus-visible .tile__desc, .tile__link:focus-visible .tile__more { transform: none; }
}
.tile__caption { padding: 16px 4px 0; }
.tile__title { font-size: 19px; line-height: 1.25; font-weight: 600; letter-spacing: -0.02em; }
.tile__details { margin-top: 3px; font-size: 14px; color: var(--muted); }

/* ------------------------------------------------------------------
   About
   ------------------------------------------------------------------ */
.about { display: grid; gap: clamp(32px, 6vw, 96px); align-items: start; }
@media (min-width: 800px) { .about:has(.about__portrait) { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }
.about__portrait { border-radius: 24px; overflow: hidden; background: var(--frame); }
.about__portrait img { width: 100%; height: auto; }
.about__text { max-width: 640px; }
.prose { font-size: clamp(19px, 1.8vw, 21px); line-height: 1.5; color: var(--ink); text-wrap: pretty; }
.prose > * + * { margin-top: 1em; }
.prose p { margin: 0; }
.prose a { text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------------
   Contact
   ------------------------------------------------------------------ */
.contact { display: grid; gap: clamp(32px, 6vw, 96px); }
@media (min-width: 800px) { .contact { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }
.contact__lede { font-size: clamp(19px, 1.8vw, 21px); color: var(--muted); max-width: 30ch; }
.contact__direct { list-style: none; margin: 28px 0 0; padding: 0; display: grid; gap: 8px; font-size: 17px; }
.contact__form { display: grid; gap: 16px; }
.field { display: grid; gap: 8px; }
.field__label { font-size: 14px; font-weight: 500; color: var(--muted); }
.field input, .field textarea {
  width: 100%; font: inherit; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px;
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.field textarea { resize: vertical; min-height: 150px; }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--bad); }
.field--trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.contact__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-top: 6px; }
.contact__status { font-size: 15px; color: var(--muted); min-height: 1.4em; }
.contact__status.is-good { color: var(--good); }
.contact__status.is-bad { color: var(--bad); }
.contact__form.is-sent .field { opacity: 0.5; transition: opacity 0.5s var(--ease); }

.button {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 26px; border: 0; border-radius: 999px;
  background: var(--ink); color: var(--bg); font: 500 17px/1 var(--sans); letter-spacing: -0.01em;
  cursor: pointer; transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.button:hover { text-decoration: none; opacity: 0.86; }
.button:active { transform: scale(0.97); }
.button:disabled { cursor: default; opacity: 0.5; }
.button.is-busy .button__text { opacity: 0; }
.button.is-busy::after {
  content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent; animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------
   One piece on its own page (also what the lightbox links to)
   ------------------------------------------------------------------ */
.piece { max-width: var(--max); margin: 0 auto; padding: clamp(24px, 5vw, 64px) var(--gutter) clamp(64px, 8vw, 120px); display: grid; gap: clamp(28px, 4vw, 64px); }
@media (min-width: 1000px) { .piece { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); align-items: center; min-height: calc(100svh - var(--nav-h)); } }
.piece__image { display: grid; place-items: center; background: var(--frame); border-radius: 26px; padding: clamp(24px, 6vw, 80px); }
.piece__image img { max-height: 76svh; width: auto; filter: var(--shadow-art); }
.piece__title { font-size: clamp(36px, 4.6vw, 56px); line-height: 1.05; font-weight: 650; letter-spacing: -0.04em; }
.piece__details { margin-top: 10px; color: var(--muted); font-size: 17px; }
.piece__info .prose { margin-top: 26px; font-size: 19px; }
.piece__nav { display: flex; justify-content: space-between; gap: 16px; margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 15px; }

.notice-page { min-height: calc(80svh - var(--nav-h)); display: grid; place-content: center; justify-items: center; gap: 18px; padding: 80px var(--gutter); text-align: center; }
.notice-page h1 { font-size: clamp(44px, 7vw, 80px); line-height: 1.02; font-weight: 650; letter-spacing: -0.045em; }
.notice-page p { max-width: 36ch; font-size: 21px; color: var(--muted); }
.notice-page .button { margin-top: 14px; }

/* ------------------------------------------------------------------
   Lightbox: the native <dialog>, so focus, Escape and the backdrop
   behave as the browser intends.
   ------------------------------------------------------------------ */
.lightbox {
  width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: var(--overlay); color: var(--ink);
  -webkit-backdrop-filter: saturate(180%) blur(30px); backdrop-filter: saturate(180%) blur(30px);
}
.lightbox::backdrop { background: transparent; }
/* Stacked (picture, then words) until there is room for them side by side. The picture's
   height is capped against the window itself, not its grid row, so it can never grow over
   the words; when the words are long the whole stage scrolls instead. */
.lightbox__stage {
  height: 100%; display: grid; gap: 28px; padding: 72px var(--gutter) 32px;
  grid-template-rows: auto auto; align-content: start; overflow-y: auto;
}
.lightbox__image { display: grid; place-items: center; }
.lightbox__image picture { display: contents; }
.lightbox__image img { max-width: 100%; max-height: 60dvh; width: auto; height: auto; object-fit: contain; filter: var(--shadow-art); }
@media (min-width: 1000px) {
  .lightbox__stage { grid-template-columns: minmax(0, 1fr) 360px; grid-template-rows: none; align-content: center; align-items: center; padding: 64px 96px; gap: 64px; }
  .lightbox__image img { max-height: calc(100dvh - 128px); }
}
.lightbox__title { font-size: clamp(28px, 3vw, 40px); line-height: 1.1; font-weight: 650; letter-spacing: -0.035em; }
.lightbox__title:empty { display: none; }
.lightbox__details { margin-top: 8px; color: var(--muted); font-size: 15px; }
.lightbox__desc { margin-top: 20px; font-size: 17px; }
.lightbox__link { display: inline-block; margin-top: 24px; font-size: 15px; }
.lightbox__btn {
  position: fixed; z-index: 2; display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: 0; border-radius: 50%; background: color-mix(in srgb, var(--ink) 9%, transparent); color: var(--ink); cursor: pointer;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.lightbox__btn:hover { background: color-mix(in srgb, var(--ink) 16%, transparent); }
.lightbox__btn:active { transform: scale(0.92); }
.lightbox__btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lightbox__close { top: 16px; right: 16px; }
.lightbox__prev, .lightbox__next { top: 50%; translate: 0 -50%; }
.lightbox__prev { left: 16px; }
.lightbox__next { right: 16px; }
@media (max-width: 999px) { .lightbox__prev, .lightbox__next { top: auto; bottom: 16px; translate: none; } .lightbox__stage { padding-bottom: 84px; } }
.lightbox__btn[hidden] { display: none; }
body:has(.lightbox[open]) { overflow: hidden; }

/* ------------------------------------------------------------------
   About and Contact pop-outs: native <dialog> panels over the page.
   A centred card on wide screens, a sheet from the bottom on phones.
   ------------------------------------------------------------------ */
.sheet {
  width: min(1040px, calc(100vw - 48px)); max-width: none;
  max-height: min(880px, calc(100dvh - 48px));
  margin: auto; padding: 0; border: 0; border-radius: 30px;
  background: var(--surface); color: var(--ink);
  box-shadow: 0 50px 120px -20px rgba(0, 0, 0, 0.35), 0 0 0 1px color-mix(in srgb, var(--ink) 6%, transparent);
  overflow: hidden;
}
.sheet::backdrop { background: rgba(0, 0, 0, 0.22); -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%); }
.sheet__scroll { max-height: inherit; overflow-y: auto; overscroll-behavior: contain; padding: clamp(36px, 6vw, 80px); }
.sheet .section__title { margin-bottom: clamp(20px, 3vw, 36px); }
.sheet__close {
  position: absolute; top: 18px; right: 18px; display: grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: 50%; background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); cursor: pointer;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.sheet__close:hover { background: color-mix(in srgb, var(--ink) 15%, transparent); }
.sheet__close:active { transform: scale(0.9); }
.sheet__close svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
body:has(.sheet[open]) { overflow: hidden; }
@media (max-width: 699px) {
  .sheet { width: 100vw; max-height: calc(100dvh - 40px); margin: auto 0 0; border-radius: 26px 26px 0 0; }
  .sheet__scroll { padding: 52px 20px calc(32px + env(safe-area-inset-bottom)); }
  .sheet__close { top: 12px; right: 12px; }
  /* A grabber, as on iOS sheets. */
  .sheet::before { content: ""; position: absolute; top: 8px; left: 50%; width: 38px; height: 5px; margin-left: -19px; border-radius: 3px; background: color-mix(in srgb, var(--ink) 18%, transparent); }
}
.section--standalone { min-height: calc(80svh - var(--nav-h)); }

/* ------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------ */
.footer { border-top: 1px solid var(--line); }
.footer__inner { max-width: var(--max); margin: 0 auto; padding: 28px var(--gutter) 40px; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; font-size: 12px; color: var(--muted); }

/* ------------------------------------------------------------------
   Motion. Everything here is decoration: with reduced motion asked for,
   or in a browser without these features, the page simply appears.
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
  /* Above the fold: a short staggered rise when the page opens. */
  .reveal-load { animation: rise 1.1s var(--ease) both; animation-delay: calc(var(--d, 0) * 110ms + 80ms); }

  /* The opening drifts back and fades as the gallery comes up beneath it. */
  @supports (animation-timeline: scroll()) {
    .hero { animation: hero-out linear both; animation-timeline: scroll(root); animation-range: 0 85svh; transform-origin: 50% 40%; }
    @keyframes hero-out { to { opacity: 0; transform: translateY(-8svh) scale(0.94); } }
  }

  /* Below the fold: each block rises as it scrolls into view. Native scroll-driven
     animation where available; site.js does the same with IntersectionObserver elsewhere. */
  @supports (animation-timeline: view()) {
    .reveal { animation: rise-scroll linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
  }
  .js-reveal .reveal { opacity: 0; transform: translateY(36px); transition: opacity 1s var(--ease), transform 1.1s var(--ease); }
  .js-reveal .reveal.is-in { opacity: 1; transform: none; }

  /* The lightbox fades and settles in, and fades out on close. */
  .lightbox { transition: opacity 0.45s var(--ease), display 0.45s allow-discrete, overlay 0.45s allow-discrete; opacity: 0; }
  .lightbox[open] { opacity: 1; }
  @starting-style { .lightbox[open] { opacity: 0; } }
  .lightbox__info { transition: opacity 0.6s 0.12s var(--ease), translate 0.7s 0.12s var(--ease); }
  @starting-style { .lightbox[open] .lightbox__info { opacity: 0; translate: 0 16px; } }
  .lightbox__image.is-changing img { animation: swap 0.5s var(--ease) both; }

  /* Pop-outs grow from the link that opened them (site.js sets the origin) with a soft
     spring, and their contents follow a beat later. Closing is quicker and plainer. */
  .sheet {
    opacity: 0; transform: scale(0.4);
    transition: opacity 0.28s ease-in, transform 0.34s cubic-bezier(0.5, 0, 0.75, 0), display 0.34s allow-discrete, overlay 0.34s allow-discrete;
  }
  .sheet[open] { opacity: 1; transform: none; transition: opacity 0.35s ease-out, transform 0.7s var(--spring), display 0.7s allow-discrete, overlay 0.7s allow-discrete; }
  @starting-style { .sheet[open] { opacity: 0; transform: scale(0.4); } }
  .sheet::backdrop { opacity: 0; transition: opacity 0.34s ease, display 0.34s allow-discrete, overlay 0.34s allow-discrete; }
  .sheet[open]::backdrop { opacity: 1; transition-duration: 0.5s; }
  @starting-style { .sheet[open]::backdrop { opacity: 0; } }
  .sheet[open] :is(.about__portrait, .section__title, .prose, .contact__lede, .contact__direct, .contact__form) {
    transition: opacity 0.6s var(--ease), translate 0.8s var(--ease);
    transition-delay: calc(var(--n, 0) * 60ms + 140ms);
  }
  @starting-style { .sheet[open] :is(.about__portrait, .section__title, .prose, .contact__lede, .contact__direct, .contact__form) { opacity: 0; translate: 0 18px; } }
  .sheet .section__title { --n: 1; } .sheet .prose, .sheet .contact__lede { --n: 2; } .sheet .contact__direct { --n: 3; } .sheet .contact__form { --n: 3; }
  @media (max-width: 699px) {
    .sheet { transform: translateY(100%); transition: transform 0.38s cubic-bezier(0.4, 0, 1, 1), display 0.38s allow-discrete, overlay 0.38s allow-discrete; opacity: 1; }
    .sheet[open] { transform: none; transition: transform 0.6s var(--ease), display 0.6s allow-discrete, overlay 0.6s allow-discrete; }
    @starting-style { .sheet[open] { transform: translateY(100%); } }
  }

  /* Moving between pieces in the lightbox and opening one: the browser's view transitions. */
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.4s; animation-timing-function: var(--ease); }
  ::view-transition-group(art) { animation-duration: 0.55s; animation-timing-function: var(--ease); }
}
@keyframes rise { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes rise-scroll { from { opacity: 0; transform: translateY(56px) scale(0.97); } to { opacity: 1; transform: none; } }
@keyframes swap { from { opacity: 0; transform: scale(0.98); } to { opacity: 1; transform: none; } }

/* Sections that in-page links move focus to need no ring of their own. */
[tabindex="-1"]:focus { outline: none; }
