/* =========================================================================
   Anne Brodersen — poetic textile portfolio
   Palette and rhythm inspired by linen, madder dye and handmade paper.
   ========================================================================= */

:root {
  --bone: #f2eadb;
  --paper: #e7ddca;
  --paper-deep: #ddd0ba;
  --ink: #211c16;
  --ink-soft: #5c5246;
  --ink-faint: #8a7f70;
  --madder: #9d3b2f;
  --madder-deep: #7c2c22;
  --indigo: #2f3b57;
  --line: rgba(33, 28, 22, 0.14);
  --line-soft: rgba(33, 28, 22, 0.08);
  --grain-blend: multiply;
  --grain-opacity: 0.5;

  --serif: "Fraunces", Georgia, "Times New Roman", serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --gutter: clamp(1.25rem, 5vw, 5rem);
  --maxw: 1600px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Tells the browser this page genuinely supports both schemes, so native
     UI (scrollbars, form controls, etc.) themes itself correctly instead of
     assuming light — the tokens below are what actually re-theme the page. */
  color-scheme: light dark;
}
/* The footer theme switch (light / dark / device) sets data-theme on <html>;
   without it the device setting decides. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* A dark reading of the same palette — deep warm charcoal in place of bone,
   not a cold near-black, with madder brightened just enough to keep the
   same accent presence at lower ambient contrast. Every rule in this file
   is written against the custom properties above, so redefining them here
   is the entire dark theme — nothing else below needs to change. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bone: #1b1714;
    --paper: #262019;
    --paper-deep: #302921;
    --ink: #ede4d3;
    --ink-soft: #b7ab97;
    --ink-faint: #8a7f6d;
    --madder: #dd7f6b;
    --madder-deep: #c96552;
    --indigo: #8d9bc4;
    --line: rgba(237, 228, 211, 0.14);
    --line-soft: rgba(237, 228, 211, 0.08);
    /* multiply only ever darkens — invisible against an already-dark page.
       screen only lightens, so the same grain reads as a faint speckle of
       light, like a scan of dark paper, instead of vanishing. */
    --grain-blend: screen;
    --grain-opacity: 0.06;
  }
}
:root[data-theme="dark"] {
  --bone: #1b1714;
  --paper: #262019;
  --paper-deep: #302921;
  --ink: #ede4d3;
  --ink-soft: #b7ab97;
  --ink-faint: #8a7f6d;
  --madder: #dd7f6b;
  --madder-deep: #c96552;
  --indigo: #8d9bc4;
  --line: rgba(237, 228, 211, 0.14);
  --line-soft: rgba(237, 228, 211, 0.08);
  /* multiply only ever darkens — invisible against an already-dark page.
     screen only lightens, so the same grain reads as a faint speckle of
     light, like a scan of dark paper, instead of vanishing. */
  --grain-blend: screen;
  --grain-opacity: 0.06;
}


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

/* ---- View transitions -------------------------------------------------------
   In-site links are handled by the router in site.js as same-document
   transitions (no page load). The @view-transition rule below covers the
   navigations the router leaves to the browser (language switch, reloads,
   JS off) with the same morph. Both share the durations below. Elements
   carrying a matching view-transition-name morph; everything else
   crossfades. Names are set inline where each image renders (work-card.ejs,
   artwork.ejs, collections.ejs, collection.ejs). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
  /* Root (unmatched page chrome) and named groups (morphing images) share
     one duration so neither finishes first and leaves a visible seam —
     the page settling before the image, or the image landing while the
     rest of the page is still mid-fade both read as a glitch. */
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-group(*) {
    animation-duration: 0.6s;
    animation-timing-function: var(--ease);
  }
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
html.is-navigating { cursor: progress; }
/* site.js moves focus here after an in-site navigation (for screen readers). */
#main:focus { outline: none; }

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.1rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Faint paper grain over everything. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
}
/* Named elements (morphing images) render above the document during a view
   transition, so grain never shows on them mid-morph, then pops back the
   instant the transition ends — a small, localized ~4% brightness change
   on just that image (confirmed: mean delta 3.27, max 11 of 255). Tried
   hiding grain for the whole page during the transition and fading it back
   in after — reverted: grain is a full-viewport overlay at 0.5 opacity in
   light mode, so that turned a small pop on one image into a much more
   visible page-wide brighten/darken pulse on every navigation. Left as the
   original, smaller pop rather than trade it for a bigger one. */

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--madder); color: var(--bone); }

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--ink);
  color: var(--bone);
  padding: 0.6rem 1rem;
  z-index: 10000;
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* ---- Typography ---------------------------------------------------------- */

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 380;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
  line-height: 1.04;
  margin: 0;
}

.page-title {
  font-size: clamp(2.6rem, 7vw, 6rem);
  font-weight: 350;
}

.page-lead {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.2rem, 2.4vw, 1.9rem);
  color: var(--ink-soft);
  max-width: 26ch;
  margin: 1.2rem 0 0;
  font-weight: 340;
}

/* ---- Header / nav -------------------------------------------------------- */

.site-header {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: clamp(1.1rem, 2.5vw, 2rem) var(--gutter);
  mix-blend-mode: normal;
}

.brand { display: inline-flex; flex-direction: column; line-height: 1; }
.brand-name {
  font-family: var(--serif);
  font-size: clamp(1.1rem, 1.6vw, 1.45rem);
  letter-spacing: 0.01em;
}
.brand-sub {
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: 0.45rem;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 2.1rem);
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.site-nav a {
  position: relative;
  padding-bottom: 2px;
  color: var(--ink-soft);
  transition: color 0.4s var(--ease);
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
.site-nav a:hover, .site-nav a.is-active { color: var(--ink); }
.site-nav a:hover::after, .site-nav a.is-active::after { transform: scaleX(1); }

.lang-switch {
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 0.35rem 0.7rem !important;
  letter-spacing: 0.1em;
}
.lang-switch::after { display: none; }

.nav-toggle { display: none; }

/* ---- Hero ---------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding: var(--gutter);
  padding-bottom: clamp(2rem, 6vh, 5rem);
  overflow: hidden;
}
.hero-inner { position: relative; z-index: 2; width: 100%; }

.hero-eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 clamp(1rem, 3vh, 2rem);
}

.hero-title {
  font-family: var(--serif);
  font-weight: 320;
  font-size: clamp(3.4rem, 17vw, 17rem);
  line-height: 0.92;
  letter-spacing: -0.03em;
  margin: 0;
}
.hero-line { display: block; overflow: visible; padding-bottom: 0.12em; }
.hero-line--accent { font-style: italic; color: var(--madder); padding-left: 0.08em; }

.hero-scroll {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  margin-top: clamp(1.6rem, 5vh, 3.4rem);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.hero-scroll-line {
  width: 3.2rem; height: 1px; background: var(--ink-faint);
  position: relative; overflow: hidden;
}
.hero-scroll-line::after {
  content: ""; position: absolute; inset: 0;
  background: var(--ink);
  transform: translateX(-100%);
  animation: scrollLine 2.6s var(--ease) infinite;
}
@keyframes scrollLine {
  0% { transform: translateX(-100%); }
  50% { transform: translateX(0); }
  100% { transform: translateX(100%); }
}

/* drifting stitched thread in the hero background */
.hero-thread {
  position: absolute;
  inset: -10%;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(115deg, transparent 0 38px, rgba(157,59,47,0.05) 38px 40px),
    repeating-linear-gradient(60deg, transparent 0 54px, rgba(47,59,87,0.045) 54px 56px);
  mask-image: radial-gradient(120% 90% at 80% 20%, #000 30%, transparent 75%);
}

/* ---- Intro statement ----------------------------------------------------- */

.intro {
  padding: clamp(3rem, 8vh, 7rem) var(--gutter) clamp(3rem, 8vh, 6rem);
  max-width: 1400px;
  margin-inline: auto;
}
.intro-statement {
  font-family: var(--serif);
  font-weight: 330;
  font-size: clamp(1.6rem, 3.2vw, 3rem);
  line-height: 1.22;
  letter-spacing: -0.015em;
  margin: 0 0 clamp(2rem, 4vw, 4rem);
  text-wrap: balance;
}
.home-video { display: block; width: 100%; }
.home-video .video-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  padding-bottom: 0;
  overflow: hidden;
  background: var(--ink);
}
.home-video .video-wrap iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* ---- Section heads ------------------------------------------------------- */

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 var(--gutter);
  margin-bottom: clamp(2rem, 5vh, 4rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.2rem, 3vh, 2.2rem);
}
.section-title { font-size: clamp(1.7rem, 4vw, 3rem); font-weight: 350; }
.section-link {
  font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-soft); white-space: nowrap;
  transition: color 0.3s var(--ease);
}
.section-link:hover { color: var(--madder); }

/* ---- Featured + work grids ---------------------------------------------- */

.featured { padding-bottom: clamp(3rem, 8vh, 7rem); }

/* Selected works: one work per screen, side by side. Sideways scroll snaps
   to each work, so the whole section is about one screen tall. */
.showcase-track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.showcase-track::-webkit-scrollbar { display: none; }
.showcase-track:focus-visible { outline: 1px solid var(--line); outline-offset: -1px; }
.showcase-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.showcase-link {
  box-sizing: border-box;
  height: min(82svh, 58rem);
  min-height: 26rem;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(14rem, 22rem);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 5rem);
  color: inherit;
  text-decoration: none;
}
.showcase-figure {
  margin: 0;
  height: 100%;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.showcase-figure img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  box-shadow: 0 1.5rem 3rem -1.5rem rgba(33, 28, 22, 0.35);
}
.showcase-caption {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.showcase-index {
  font-size: 0.78rem; letter-spacing: 0.16em; color: var(--ink-faint);
}
.showcase-title {
  font-family: var(--serif);
  font-size: clamp(1.8rem, 3.4vw, 3.2rem);
  font-weight: 350;
  line-height: 1.05;
}
.showcase-meta { color: var(--ink-soft); font-size: 0.95rem; }
.showcase-more {
  margin-top: 0.8rem;
  font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-soft);
  transition: color 0.3s var(--ease);
}
.showcase-link:hover .showcase-more,
.showcase-link:focus-visible .showcase-more { color: var(--madder); }

.showcase-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.2rem;
  padding: clamp(1rem, 3vh, 2rem) var(--gutter) 0;
}
.showcase-controls[hidden] { display: none; }
.showcase-btn {
  width: 3rem; height: 3rem;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font-size: 1.1rem;
  cursor: pointer;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.showcase-btn:hover:not(:disabled) { border-color: var(--madder); color: var(--madder); }
.showcase-btn:disabled { opacity: 0.35; cursor: default; }
.showcase-count {
  font-size: 0.85rem; letter-spacing: 0.12em; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  min-width: 4.5em; text-align: center;
}

/* True-to-size wall. Each work is drawn at a height that follows its real
   height (--s from lib/scale.js: 1 = a 60 cm work, compressed so small and
   large pieces both stay readable), with its photo's proportions (--ar).
   --base is the on-screen height of a 60 cm work. Nothing gets taller than
   --max-h or wider than the page. Rows are centred and the works in a row
   hang on a shared centre line, like a gallery wall; captions are always two
   lines (title, then year), so the centre line holds for the images too. */
.works-grid {
  --base: clamp(170px, 27vh, 290px);
  --max-h: 68vh;
  padding: clamp(1.5rem, 4vh, 3rem) var(--gutter) clamp(5rem, 12vh, 10rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: clamp(3rem, 7vh, 5rem) clamp(1.8rem, 3.5vw, 3.5rem);
}
.works-grid-item {
  --h: min(calc(var(--s, 1) * var(--base)), var(--max-h));
  flex: 0 0 auto;
  width: min(100%, calc(var(--h) * var(--ar, 0.8)));
  transition: opacity 0.5s var(--ease);
}
.works-grid-item.is-hidden { display: none; }
.works-grid .work-card-figure { aspect-ratio: var(--ar, 0.8); }
.works-grid .work-card-figure img { height: 100%; object-fit: cover; }
.works-grid .work-card-empty { padding-top: 0; height: 100%; }
/* Captions share one fixed height (room for a two-line title + the year),
   so every image in a row keeps the same centre line; narrow works wrap
   their title instead of cutting it. */
.works-grid .work-card-caption {
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  gap: 0.3rem;
  min-height: 4.1rem;
}
.works-grid .work-card-title {
  font-size: clamp(0.95rem, 1.15vw, 1.12rem);
  line-height: 1.25;
  max-width: 100%;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* ---- Work card ----------------------------------------------------------- */

.work-card { display: block; }
.work-card-figure {
  margin: 0;
  overflow: hidden;
  background: var(--paper);
  position: relative;
}
.work-card-figure img {
  width: 100%;
  height: auto;
  transition: transform 0.7s var(--ease), filter 0.9s var(--ease);
  filter: saturate(0.96);
}
.work-card:hover .work-card-figure img {
  transform: translate(calc(var(--mx, 0) * 9px), calc(var(--my, 0) * 9px)) scale(1.045);
  filter: saturate(1.05);
}
.work-card-empty { display: block; padding-top: 125%; background: var(--paper); }

.work-card-caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.9rem;
}
.work-card-title {
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.6vw, 1.4rem);
  font-style: italic;
  font-weight: 360;
}
.work-card-meta {
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  text-transform: uppercase;
  white-space: nowrap;
}
.dot-available { color: var(--madder); }

/* ---- Filter bar ---------------------------------------------------------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: clamp(1rem, 3vh, 2rem) var(--gutter) 0;
}
.filter-chip {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 0.5rem 1.1rem;
  cursor: pointer;
  transition: all 0.35s var(--ease);
}
.filter-chip:hover { border-color: var(--ink); color: var(--ink); }
.filter-chip.is-active { background: var(--ink); color: var(--bone); border-color: var(--ink); }

/* ---- Page intro ---------------------------------------------------------- */

.page-intro {
  padding: clamp(8rem, 18vh, 14rem) var(--gutter) clamp(1rem, 3vh, 2rem);
  max-width: 1200px;
}

/* ---- Artwork detail ------------------------------------------------------ */

.artwork { padding: clamp(7rem, 14vh, 11rem) var(--gutter) clamp(4rem, 10vh, 8rem); }
.artwork-back {
  font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-soft);
}
.artwork-back:hover { color: var(--madder); }

/* Image left; title sits at the top of the right column above the facts.
   On narrow screens the title comes first, then image, then facts. */
.artwork-body {
  display: grid;
  /* The work sits in a centre column that hugs the image (tall works are
     narrow); the title + details sit against the right edge. The left
     column is flexible spacer so the work drifts toward the middle; it gives
     way first when a wide work needs the room. */
  --img-h: min(74vh, 860px);
  grid-template-columns:
    minmax(0, 1fr)
    min(calc(var(--img-h) * var(--ar, 0.8)), 58%)
    minmax(19rem, 1fr);
  grid-template-areas: ". images head" ". images info";
  grid-template-rows: auto 1fr;
  column-gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
  margin-top: clamp(2rem, 6vh, 4rem);
}
.artwork-head { grid-area: head; margin: 0 0 clamp(2rem, 5vh, 3rem); }
.artwork-images { grid-area: images; align-items: center; }
.artwork-head, .artwork-info { justify-self: end; width: min(100%, 26rem); }
.artwork-info { grid-area: info; }
.artwork-title { font-size: clamp(1.9rem, 3.1vw, 3.3rem); font-weight: 330; text-wrap: balance; }
.artwork-subtitle {
  font-family: var(--serif);
  font-style: italic;
  color: var(--ink-soft);
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  margin: 0.9rem 0 0;
}

.artwork-images { display: flex; flex-direction: column; gap: clamp(1.5rem, 4vh, 3rem); }
/* Tall works fit the screen instead of running far below it. */
.artwork-image { margin: 0; background: var(--paper); overflow: hidden; width: fit-content; max-width: 100%; }
.artwork-image img { width: auto; max-width: 100%; max-height: var(--img-h, min(74vh, 860px)); }
.artwork-image--empty { padding-top: 120%; width: min(40vw, 520px); }

/* ── Lightbox ─────────────────────────────────────────────────────────────── */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s var(--ease);
}
.lightbox.is-open {
  opacity: 1;
  pointer-events: auto;
}
.lightbox-img-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 3.5rem;
}
.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
  transition: opacity 0.18s ease;
}
.lightbox-img.is-loading { opacity: 0; }
/* Press-and-hold opens the loupe on touch (initLoupe): no iOS callout or
   text magnifier, and one-finger drags belong to the loupe; pinch-zoom stays. */
.lightbox-img {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: pinch-zoom;
}
.lightbox-hint {
  display: none;
  position: absolute;
  bottom: 2.9rem;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  width: max-content;
  max-width: calc(100% - 2rem);
  text-align: center;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  pointer-events: none;
  transition: opacity 0.4s var(--ease);
}
@media (hover: none) and (pointer: coarse) {
  .lightbox-hint { display: block; }
}
.lightbox.loupe-used .lightbox-hint { opacity: 0; }

/* Loupe (JS: initLoupe). Replaces the cursor over the artwork page's images
   and the lightbox image (the page images carry an inline zoom-in cursor). */
.lightbox.has-loupe,
.has-loupe .lightbox-img,
.has-loupe [data-lightbox-src] { cursor: none !important; }
/* Press-and-hold on the page images too: no iOS callout / selection. */
.artwork-image img { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.artwork-loupe-hint {
  margin: 0;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  text-align: center;
  transition: opacity 0.5s var(--ease);
}
.artwork-loupe-hint .for-touch { display: none; }
@media (hover: none) and (pointer: coarse) {
  .artwork-loupe-hint .for-mouse { display: none; }
  .artwork-loupe-hint .for-touch { display: inline; }
}
.artwork-images.loupe-used .artwork-loupe-hint { opacity: 0; }
.loupe {
  --loupe: clamp(180px, 22vmin, 280px);
  position: fixed;
  left: 0; top: 0;
  width: var(--loupe);
  height: var(--loupe);
  border-radius: 50%;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  scale: 0.6;
  transition: opacity 0.22s var(--ease), scale 0.32s var(--ease);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.08);
  will-change: transform;
}
.loupe.is-on { opacity: 1; scale: 1; }
.loupe > div { position: absolute; inset: 0; border-radius: 50%; }
.loupe-view,
.loupe-rim { background-color: #0d0c0b; background-repeat: no-repeat; }
.loupe-view { overflow: hidden; }
/* Fake refraction: near the rim the view is magnified a little more and
   picks up faint colour fringes, like thick glass bending light. */
.loupe-rim {
  -webkit-mask: radial-gradient(circle, transparent 62%, #000 86%);
          mask: radial-gradient(circle, transparent 62%, #000 86%);
  filter: saturate(1.25) contrast(1.06) blur(0.4px);
  box-shadow:
    inset 3px 0 6px rgba(255, 70, 40, 0.28),
    inset -3px 0 6px rgba(40, 150, 255, 0.28),
    inset 0 3px 6px rgba(255, 220, 90, 0.12);
}
/* Glass + edge light: a bright rim catching light from the top left, a soft
   inner shade at the bottom, and a faint specular sheen. */
.loupe-glass {
  background:
    radial-gradient(120% 90% at 28% 18%, rgba(255, 255, 255, 0.16), transparent 42%),
    radial-gradient(circle, transparent 70%, rgba(0, 0, 0, 0.28) 100%);
  box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.38),
    inset 0 2px 1px rgba(255, 255, 255, 0.55),
    inset 2px 3px 10px rgba(255, 246, 225, 0.35),
    inset 0 -10px 22px rgba(0, 0, 0, 0.35);
}
.loupe-glass::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 200deg, transparent 0 20%, rgba(255, 255, 255, 0.55) 30%, transparent 42% 70%, rgba(255, 255, 255, 0.18) 80%, transparent 90%);
  -webkit-mask: radial-gradient(circle, transparent 94%, #000 97%);
          mask: radial-gradient(circle, transparent 94%, #000 97%);
}
@media (prefers-reduced-motion: reduce) { .loupe { transition: opacity 0.15s linear; scale: 1; } }
.lightbox-close,
.lightbox-prev,
.lightbox-next {
  position: absolute;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 0.75rem 1rem;
  font-size: 1.6rem;
  line-height: 1;
  opacity: 0.65;
  transition: opacity 0.15s;
  user-select: none;
  -webkit-user-select: none;
}
.lightbox-close:hover,
.lightbox-prev:hover,
.lightbox-next:hover { opacity: 1; }
.lightbox-close { top: 1rem; right: 1.25rem; font-size: 2rem; }
.lightbox-prev  { left: 0.5rem;  top: 50%; transform: translateY(-50%); font-size: 2rem; }
.lightbox-next  { right: 0.5rem; top: 50%; transform: translateY(-50%); font-size: 2rem; }
.lightbox-prev[hidden], .lightbox-next[hidden] { display: none; }
.lightbox-counter {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255,255,255,0.5);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  pointer-events: none;
}

.artwork-info-sticky { position: sticky; top: clamp(5rem, 12vh, 8rem); }
.artwork-story {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.25rem, 2vw, 1.7rem);
  line-height: 1.45;
  font-weight: 340;
  margin: 0 0 clamp(2rem, 5vh, 3rem);
  color: var(--ink);
  text-wrap: pretty;
}

.artwork-facts {
  border-top: 1px solid var(--line);
}
.facts-row {
  display: grid;
  grid-template-columns: auto 1fr;
  border-bottom: 1px solid var(--line);
}
.facts-dt {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0.85rem 1.5rem 0.85rem 0;
  align-self: center;
}
.facts-dd {
  font-size: 0.98rem;
  padding: 0.85rem 0;
}
.avail--available { color: var(--madder); }

.artwork-collection-link {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  color: var(--ink);
  transition: color 0.3s var(--ease);
}
.artwork-collection-link:hover { color: var(--madder); }

.artwork-enquire {
  display: inline-block;
  margin-top: 1.8rem;
  padding: 0.9rem 1.6rem;
  border: 1px solid var(--ink);
  border-radius: 100px;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: all 0.4s var(--ease);
}
.artwork-enquire:hover { background: var(--ink); color: var(--bone); }

.artwork-nav {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  margin-top: clamp(4rem, 12vh, 9rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.5rem, 4vh, 3rem);
}
.artwork-nav-link { display: flex; flex-direction: column; gap: 0.5rem; max-width: 45%; }
.artwork-nav-next { text-align: right; margin-left: auto; }
.artwork-nav-label {
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint);
}
.artwork-nav-title {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.2rem, 2.4vw, 1.9rem);
  transition: color 0.3s var(--ease);
}
.artwork-nav-link:hover .artwork-nav-title { color: var(--madder); }

/* ---- Collections --------------------------------------------------------- */

.home-collections { padding: clamp(3rem, 8vh, 7rem) 0; }
.collection-list { list-style: none; margin: 0; padding: 0 var(--gutter); }
.collection-row { border-bottom: 1px solid var(--line); }
.collection-row a {
  display: grid;
  grid-template-columns: 3rem 1fr 1fr auto;
  gap: 1.5rem;
  align-items: baseline;
  padding: clamp(1.2rem, 3vh, 2.2rem) 0;
  transition: padding 0.4s var(--ease), color 0.4s var(--ease);
}
.collection-row a:hover { padding-left: 1.2rem; color: var(--madder); }
.collection-index { font-size: 0.8rem; color: var(--ink-faint); letter-spacing: 0.1em; }
.collection-name { font-family: var(--serif); font-size: clamp(1.4rem, 3vw, 2.4rem); font-weight: 350; }
.collection-sub { color: var(--ink-soft); font-style: italic; font-family: var(--serif); }
.collection-year { font-size: 0.8rem; color: var(--ink-faint); letter-spacing: 0.08em; text-align: right; }

.collections-feature { padding: clamp(2rem, 6vh, 5rem) var(--gutter) clamp(5rem, 12vh, 10rem); }
.collection-feature {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 6rem);
  align-items: center;
  padding: clamp(2.5rem, 7vh, 6rem) 0;
  border-top: 1px solid var(--line);
}
.collection-feature:nth-child(even) .collection-feature-media { order: 2; }
.collection-feature-media { overflow: hidden; background: var(--paper); aspect-ratio: 5 / 4; }
.collection-feature-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease); }
.collection-feature:hover .collection-feature-media img {
  transform: translate(calc(var(--mx, 0) * 8px), calc(var(--my, 0) * 8px)) scale(1.05);
}
.collection-feature-title { font-size: clamp(2rem, 4.5vw, 3.6rem); font-weight: 340; margin: 0.6rem 0 0; }
.collection-feature-sub { font-family: var(--serif); font-style: italic; color: var(--ink-soft); font-size: 1.2rem; margin: 0.6rem 0 1.2rem; }
.collection-feature-desc { color: var(--ink-soft); max-width: 42ch; }
.collection-feature-meta { display: block; margin-top: 1.4rem; font-size: 0.76rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }

.collection-hero {
  padding: clamp(7rem, 16vh, 12rem) var(--gutter) clamp(3rem, 8vh, 6rem);
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
  max-width: 1500px;
  margin-inline: auto;
}
.collection-hero-text { max-width: 32rem; }
.collection-hero-title { font-size: clamp(2.6rem, 6vw, 5.5rem); font-weight: 330; margin: 1.5rem 0 0; }
.collection-hero-sub { font-family: var(--serif); font-style: italic; color: var(--ink-soft); font-size: clamp(1.1rem, 2vw, 1.5rem); margin: 0.8rem 0 0; }
.collection-hero-desc { max-width: 56ch; margin: 2rem 0 0; font-size: clamp(1.05rem, 1.6vw, 1.25rem); color: var(--ink-soft); }
.collection-hero-media { margin: 0; overflow: hidden; background: var(--paper); aspect-ratio: 4 / 5; }
.collection-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.4s var(--ease);
  transform: translate(calc(var(--mx, 0) * 6px), calc(var(--my, 0) * 6px)) scale(1.02);
}

/* ---- About --------------------------------------------------------------- */

/* about hero */
.about-hero {
  position: relative;
  min-height: 88vh;
  background-size: cover;
  background-position: center top;
  display: flex;
  align-items: flex-end;
}
.about-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.2) 50%, transparent 100%);
  pointer-events: none;
}
.about-hero-inner {
  position: relative;
  z-index: 1;
  padding: clamp(3rem, 8vw, 6rem) var(--gutter) clamp(3.5rem, 9vh, 6rem);
  max-width: 860px;
}
.about-head-plain {
  padding: clamp(8rem, 18vh, 14rem) var(--gutter) clamp(3rem, 6vh, 5rem);
  max-width: 52rem;
}
.about-title {
  font-size: clamp(2.6rem, 7vw, 6rem);
  font-weight: 330;
  color: #fff;
  margin: 0 0 clamp(1.5rem, 4vh, 2.5rem);
}
.about-head-plain .about-title { color: var(--ink); }
.about-quote {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.3rem, 2.6vw, 2.1rem);
  line-height: 1.35;
  font-weight: 330;
  color: rgba(255,255,255,0.9);
  border: 0;
  padding: 0;
}
.about-head-plain .about-quote { color: var(--madder); margin-top: clamp(1.5rem, 4vh, 2.5rem); }
/* about content below hero */
.about-content { padding: clamp(3rem, 8vh, 6rem) var(--gutter) clamp(5rem, 12vh, 10rem); }
.about-body { max-width: 680px; margin-bottom: clamp(2.5rem, 6vh, 4rem); font-size: clamp(1rem, 1.5vw, 1.18rem); color: var(--ink-soft); }
.about-body p { margin: 0 0 1rem; line-height: 1.7; }
.about-section-title {
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
}
.about-video { margin-top: clamp(3rem, 7vh, 5rem); margin-bottom: clamp(2rem, 5vh, 3.5rem); max-width: 900px; }
.about-video-title { margin-bottom: 1.2rem; }
.video-wrap { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; background: var(--ink); }
.video-wrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.about-links { display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem; margin-top: clamp(2rem, 5vh, 4rem); border-top: 1px solid var(--line); padding-top: 2rem; }
.about-links a { font-family: var(--serif); font-style: italic; font-size: clamp(1.2rem, 2.4vw, 1.8rem); }
.about-links a:hover { color: var(--madder); }

.exhibitions-video { padding: 0 var(--gutter); max-width: 900px; }

/* ---- Exhibitions timeline + filter --------------------------------------- */
.exh-layout { padding: clamp(2rem, 5vh, 4rem) var(--gutter) clamp(5rem, 12vh, 10rem); }
.exh-filters { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: clamp(2rem, 4vh, 3rem); }
.exh-pill {
  padding: 0.35rem 1rem;
  border: 1px solid var(--line);
  background: transparent;
  font-family: inherit;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 2rem;
  transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.exh-pill:hover { border-color: var(--ink); color: var(--ink); }
.exh-pill.is-active { background: var(--ink); color: var(--bone); border-color: var(--ink); }
.exh-list { list-style: none; margin: 0; padding: 0; }
.exh-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr auto;
  gap: 1rem 1.5rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
.exh-row.is-hidden { display: none; }
.exh-row.is-leaving { opacity: 0; transform: translateY(-4px); transition-duration: 0.12s; transition-delay: 0s !important; }
.exh-row.is-entering { opacity: 0; transform: translateY(6px); transition-duration: 0s; }
.exh-year { font-size: 0.82rem; color: var(--ink-faint); letter-spacing: 0.06em; white-space: nowrap; }
.exh-text { font-size: 1rem; color: var(--ink-soft); }
.exh-tag { font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; padding: 0.2rem 0.55rem; border-radius: 1rem; }
.exh-tag--solo       { background: #e8e0d8; color: #5a4a3a; }
.exh-tag--group      { background: #dde4e0; color: #2a4a3a; }
.exh-tag--awards     { background: #f0e4d0; color: #6a3a10; }
.exh-tag--collections{ background: #e4dcea; color: #3a2a5a; }
.exh-tag--education  { background: #dde8f0; color: #1a3a5a; }
.exh-tag--media      { background: #e8e8d8; color: #4a4a2a; }
.exh-tag--membership { background: #f0e8e0; color: #5a3a2a; }
@media (prefers-color-scheme: dark) {
  /* Same hue families, inverted to muted dark chips — the light pastel
     versions would sit on a dark page like bright sticky notes. */
  :root:not([data-theme="light"]) .exh-tag--solo { background: #3a3128; color: #d9c9a8; }
  :root:not([data-theme="light"]) .exh-tag--group { background: #24352c; color: #a8d0b8; }
  :root:not([data-theme="light"]) .exh-tag--awards { background: #3a2c18; color: #e0b878; }
  :root:not([data-theme="light"]) .exh-tag--collections { background: #2e2638; color: #c8aee0; }
  :root:not([data-theme="light"]) .exh-tag--education { background: #1e2c3a; color: #a0c4e0; }
  :root:not([data-theme="light"]) .exh-tag--media { background: #302f20; color: #d0d090; }
  :root:not([data-theme="light"]) .exh-tag--membership { background: #382a22; color: #e0b8a0; }
}
:root[data-theme="dark"] .exh-tag--solo { background: #3a3128; color: #d9c9a8; }
:root[data-theme="dark"] .exh-tag--group { background: #24352c; color: #a8d0b8; }
:root[data-theme="dark"] .exh-tag--awards { background: #3a2c18; color: #e0b878; }
:root[data-theme="dark"] .exh-tag--collections { background: #2e2638; color: #c8aee0; }
:root[data-theme="dark"] .exh-tag--education { background: #1e2c3a; color: #a0c4e0; }
:root[data-theme="dark"] .exh-tag--media { background: #302f20; color: #d0d090; }
:root[data-theme="dark"] .exh-tag--membership { background: #382a22; color: #e0b8a0; }

@media (max-width: 600px) {
  .exh-row { grid-template-columns: 3.5rem 1fr; }
  .exh-tag { display: none; }
}

/* ---- CV / exhibitions ---------------------------------------------------- */

.cv-layout { padding: clamp(3rem, 7vh, 6rem) var(--gutter) clamp(5rem, 12vh, 10rem); columns: 2; column-gap: clamp(2rem, 6vw, 6rem); }
.cv-block { break-inside: avoid; margin-bottom: clamp(2.5rem, 6vh, 4rem); display: inline-block; width: 100%; }
.cv-heading { font-size: clamp(1.3rem, 2.4vw, 1.9rem); font-weight: 350; margin-bottom: 1.2rem; padding-bottom: 0.8rem; border-bottom: 1px solid var(--line); }
.cv-list { list-style: none; margin: 0; padding: 0; }
.cv-row { display: grid; grid-template-columns: 4.5rem 1fr; gap: 1rem; padding: 0.55rem 0; align-items: baseline; }
.cv-year { font-size: 0.82rem; color: var(--ink-faint); letter-spacing: 0.06em; }
.cv-text { font-size: 1rem; color: var(--ink-soft); }
.cv-text strong { color: var(--ink); font-weight: 500; }

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

.contact {
  min-height: 78vh;
  padding: clamp(8rem, 20vh, 15rem) var(--gutter) clamp(5rem, 12vh, 10rem);
}
.contact-head { max-width: 28rem; margin-bottom: clamp(2.5rem, 6vh, 4rem); }
.contact-body {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: clamp(3rem, 7vw, 7rem);
  align-items: start;
}
.contact-title { font-size: clamp(2.8rem, 8vw, 7rem); font-weight: 330; }
.contact-intro { font-family: var(--serif); font-style: italic; font-size: clamp(1.3rem, 2.6vw, 2rem); line-height: 1.35; color: var(--ink-soft); margin: 1.5rem 0 0; max-width: 24ch; }
.contact-line { margin: 0 0 0.8rem; }
.contact-studio { color: var(--ink-soft); max-width: 30ch; margin-top: 1.5rem; }
/* Contact form */
.contact-form { display: flex; flex-direction: column; gap: 1.2rem; }
.cf-row { display: flex; gap: 1rem; }
.cf-row--half .cf-field { flex: 1; }
.cf-field { display: flex; flex-direction: column; gap: 0.35rem; }
.cf-label { font-size: 0.8rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft); }
.cf-label span { color: var(--madder); }
.contact-form input,
.contact-form textarea {
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--line);
  background: transparent;
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  border-radius: 0;
  transition: border-color 0.2s;
  box-sizing: border-box;
}
.contact-form input:focus,
.contact-form textarea:focus { outline: none; border-color: var(--ink); }
.contact-form textarea { resize: vertical; min-height: 9rem; }
.cf-submit {
  align-self: flex-start;
  padding: 0.75rem 2rem;
  background: var(--ink);
  color: var(--bone);
  border: none;
  font-family: inherit;
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s;
}
.cf-submit:hover { background: var(--madder); }
.contact-flash { margin-bottom: 1.5rem; padding: 1rem 1.2rem; font-size: 0.95rem; }
.contact-flash--ok { background: #eef5ee; color: #2a5a2a; border-left: 3px solid #4a9a4a; }
.contact-flash--err { background: #fdf0f0; color: #7a2a2a; border-left: 3px solid var(--madder); padding-left: 1.5rem; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .contact-flash--ok { background: #1c2c1e; color: #a8d8a8; border-left-color: #4a9a4a; }
  :root:not([data-theme="light"]) .contact-flash--err { background: #2c1e1e; color: #e0a8a0; }
}
:root[data-theme="dark"] .contact-flash--ok { background: #1c2c1e; color: #a8d8a8; border-left-color: #4a9a4a; }
:root[data-theme="dark"] .contact-flash--err { background: #2c1e1e; color: #e0a8a0; }

.contact-details { padding-top: 0.5rem; }
.contact-social { display: flex; flex-wrap: wrap; gap: 1rem 1.5rem; margin-top: 2rem; }
@media (max-width: 700px) { .contact-body { grid-template-columns: 1fr; } .cf-row--half { flex-direction: column; } }
.contact-social a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
  text-decoration: none;
}
.contact-social a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.social-icon { width: 1.1em; height: 1.1em; flex-shrink: 0; }
.contact-context { margin-top: 2.5rem; color: var(--ink-faint); font-size: 0.95rem; }

/* ---- Invitation / CTA ---------------------------------------------------- */

.invitation { padding: clamp(6rem, 16vh, 13rem) var(--gutter); text-align: center; }
.invitation-text { font-family: var(--serif); font-style: italic; font-size: clamp(1.6rem, 4vw, 3.2rem); line-height: 1.25; font-weight: 330; max-width: 20ch; margin: 0 auto 2.5rem; text-wrap: balance; }
.invitation-cta {
  display: inline-block;
  padding: 1rem 2.2rem;
  border: 1px solid var(--ink);
  border-radius: 100px;
  font-size: 0.8rem; letter-spacing: 0.16em; text-transform: uppercase;
  transition: all 0.4s var(--ease);
}
.invitation-cta:hover { background: var(--ink); color: var(--bone); }

/* ---- Footer -------------------------------------------------------------- */

.site-footer { padding: clamp(3rem, 8vh, 6rem) var(--gutter); border-top: 1px solid var(--line); }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: 2rem; align-items: start; }
.footer-name { font-family: var(--serif); font-size: clamp(1.6rem, 3vw, 2.4rem); margin: 0; }
.footer-tag { color: var(--ink-faint); font-size: 0.85rem; margin: 0.5rem 0 0; }
.footer-nav { display: flex; flex-direction: column; gap: 0.7rem; font-size: 0.85rem; letter-spacing: 0.1em; text-transform: uppercase; }
.footer-nav a { color: var(--ink-soft); width: fit-content; }
.footer-nav a:hover { color: var(--madder); }
.footer-meta { display: flex; flex-direction: column; gap: 0.7rem; font-size: 0.85rem; color: var(--ink-faint); text-align: right; align-items: flex-end; }
.footer-meta a:hover { color: var(--ink); }
.theme-switch { display: flex; gap: 0.9rem; }
.theme-switch a[aria-current="true"] { color: var(--ink); text-decoration: underline; text-underline-offset: 0.3em; text-decoration-thickness: 1px; }

/* ---- Error --------------------------------------------------------------- */

.error-page { min-height: 80vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: var(--gutter); gap: 1.5rem; }
.error-code { font-size: clamp(5rem, 20vw, 14rem); font-weight: 320; }
.error-text { font-family: var(--serif); font-style: italic; font-size: clamp(1.2rem, 3vw, 2rem); color: var(--ink-soft); }

.empty-note { padding: 4rem var(--gutter); color: var(--ink-faint); font-style: italic; font-family: var(--serif); }

/* ---- Reveal animations --------------------------------------------------- */

/* A smoky dissolve, not a slide-in: no translate/scale, so nothing shifts
   position — opacity and blur clear together as one motion. (Tried giving
   filter a longer duration than opacity, so the shape would "resolve" and
   then keep sharpening — read as two separate effects instead of one
   dissolve, especially across staggered words, so both share a single
   duration now.) */
[data-reveal] {
  opacity: 0;
  filter: blur(22px);
  transition: opacity 1.3s var(--ease), filter 1.3s var(--ease);
  will-change: opacity, filter;
}
[data-reveal].is-visible {
  opacity: 1;
  filter: blur(0);
}

/* Standalone images used directly as reveal targets */
img[data-reveal] {
  filter: blur(18px) saturate(0.5);
  transition: filter 1.4s var(--ease), opacity 1.4s var(--ease);
  opacity: 0;
}
img[data-reveal].is-visible {
  filter: blur(0) saturate(1);
  opacity: 1;
}

.word {
  display: inline-block;
  opacity: 0;
  filter: blur(12px);
  transition: opacity 0.9s var(--ease), filter 0.9s var(--ease);
}
.word.is-visible {
  opacity: 1;
  filter: blur(0);
}

.hero-line span.letter,
.hero-line .word { transition-duration: 1.1s; }

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

@media (max-width: 980px) {
.artwork-body { grid-template-columns: 1fr; grid-template-areas: "head" "images" "info"; grid-template-rows: auto; row-gap: 2.5rem; }
  .artwork-head { margin: 0; }
  .artwork-head, .artwork-info { justify-self: stretch; width: auto; }
  .artwork-image img { max-height: 70vh; }
  .artwork-info-sticky { position: static; }
  .about, .contact { grid-template-columns: 1fr; }
  .collection-hero { grid-template-columns: 1fr; align-items: start; }
  .collection-hero-media { order: -1; aspect-ratio: 16 / 10; }
  .collection-feature, .collection-feature:nth-child(even) .collection-feature-media { grid-template-columns: 1fr; order: 0; }
  .collection-feature-media { order: -1 !important; }
  .cv-layout { columns: 1; }
}

@media (max-width: 760px) {
  .nav-toggle {
    display: flex; flex-direction: column; gap: 5px;
    background: none; border: 0; cursor: pointer; padding: 0.5rem; z-index: 120;
  }
  .nav-toggle span { width: 26px; height: 1.5px; background: var(--ink); transition: transform 0.4s var(--ease), opacity 0.3s; }
  .nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(6.5px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:last-child { transform: translateY(-6.5px) rotate(-45deg); }
  .site-nav {
    position: fixed;
    inset: 0;
    background: var(--paper);
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 1.6rem;
    padding: var(--gutter);
    font-size: 1.4rem;
    transform: translateY(-100%);
    transition: transform 0.6s var(--ease);
    z-index: 110;
  }
  .site-nav.is-open { transform: none; }
  .footer-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .footer-meta { text-align: left; align-items: flex-start; }
  .collection-row a { grid-template-columns: 2rem 1fr; }
  .collection-sub, .collection-year { display: none; }
  /* Phones: same true-to-size wall, scaled to the narrow screen. */
  .works-grid { --base: clamp(120px, 34vw, 170px); --max-h: 62vh; gap: 2.5rem 1.2rem; }
  .artwork-nav { flex-direction: column; gap: 1.5rem; }
  .artwork-nav-link, .artwork-nav-next { max-width: 100%; text-align: left; margin: 0; }
  .showcase-link {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    height: min(86svh, 52rem);
    gap: 1.2rem;
  }
  .showcase-title { font-size: 1.7rem; }
  .showcase-more { display: none; }
  .showcase-controls { justify-content: center; }
  .collection-feature { gap: 1.5rem; }
  .about-hero { min-height: 65vh; }
}

/* ---- Reduced motion ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
  [data-reveal], .word, img[data-reveal] { opacity: 1 !important; filter: none !important; transform: none !important; }
}

/* Admin preview of an unpublished work (routes/public.js /works/:slug). */
.preview-banner {
  margin: 0;
  padding: 0.8rem var(--gutter);
  background: var(--madder);
  color: var(--bone);
  font-size: 0.9rem;
  text-align: center;
}
