/* ----------------------------------------------------------------------------
   Annette Meier — a single, quiet page.
   Palette drawn from the painting: dusk slate, soft grey, warm skin-tone light.
   ------------------------------------------------------------------------- */

:root {
  --bg:        #12161b;  /* deep dusk slate, like the dark hills            */
  --bg-edge:   #0c0f13;  /* slightly darker, for a soft vignette           */
  --ink:       #e9e3d8;  /* warm off-white, echoing the lit skin           */
  --ink-soft:  #b8b1a4;  /* muted, for the title                           */
  --ink-faint: #8b8579;  /* quietest, for the email at rest                */
  --serif: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: radial-gradient(120% 120% at 50% 35%, var(--bg) 0%, var(--bg-edge) 100%);
  color: var(--ink);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The page as a single centered composition --------------------------------- */

.stage {
  min-height: 100vh;
  min-height: 100svh;   /* iOS: fit the visible viewport, not the area behind toolbars */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.6rem, 4vh, 3rem);
  padding: clamp(2rem, 6vh, 5rem) clamp(1.25rem, 5vw, 4rem);
}

.name {
  margin: 0;
  font-weight: 400;
  font-size: clamp(1.6rem, 4.2vw, 2.6rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}

/* The painting -------------------------------------------------------------- */

.work {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.9rem, 2.4vh, 1.6rem);
}

/* The series shares one frame. All paintings are stacked in the same cell;
   only opacity changes, so one dissolves softly into the next. The frame keeps
   a steady height so the page never shifts as the canvases turn. */
.gallery {
  position: relative;
  z-index: 2;               /* stays lit above the veil when a visitor lingers */
  display: grid;
  place-items: center;
  width: 100%;
  max-width: min(860px, 92vw);
  height: 70vh;
  height: 70svh;
}

.slide {
  grid-area: 1 / 1;         /* every painting occupies the same cell, centered */
  max-width: 100%;
  max-height: 70vh;
  max-height: 70svh;
  width: auto;
  height: auto;
  object-fit: contain;
  opacity: 0;
  border: 1px solid rgba(233, 227, 216, 0.08);
  box-shadow:
    0 1px 0 rgba(233, 227, 216, 0.04),
    0 30px 70px -30px rgba(0, 0, 0, 0.85);
  transition: opacity 0s ease-in-out;  /* duration is set, per fade, in JS */
}

.slide.is-visible { opacity: 1; }

/* The veil: a slow darkening that rises only while a visitor rests on a
   painting, sinking the name, title and contact into the dusk. */
.veil {
  position: fixed;
  inset: 0;
  z-index: 1;
  background: var(--bg-edge);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.6s ease;
}

body.is-lingering .veil { opacity: 0.86; }

.work__caption {
  text-align: center;
}

.work__title {
  font-style: italic;
  font-size: clamp(1.05rem, 2.4vw, 1.35rem);
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

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

.contact {
  text-align: center;
}

.contact__link {
  font-size: clamp(0.92rem, 2vw, 1.05rem);
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.5s ease, border-color 0.5s ease;
}

.contact__link:hover,
.contact__link:focus-visible {
  color: var(--ink);
  border-bottom-color: rgba(233, 227, 216, 0.4);
  outline: none;
}

/* ----------------------------------------------------------------------------
   The controls: four rehearsal marks in the lower-right corner — M H N A,
   barely visible at rest, surfacing only when the visitor stirs.
   The letter is also the keyboard shortcut.
   ------------------------------------------------------------------------- */

.controls {
  position: fixed;
  right: calc(clamp(0.8rem, 2.5vw, 1.6rem) + env(safe-area-inset-right));
  bottom: calc(clamp(0.8rem, 2.5vh, 1.6rem) + env(safe-area-inset-bottom));
  z-index: 10;                /* above everything, always reachable */
  display: flex;
  gap: 0.4rem;
  opacity: 0.1;               /* barely there until something moves */
  transition: opacity 1.2s ease;
}

body.controls-awake .controls { opacity: 0.42; }
.controls:hover,
.controls:focus-within { opacity: 0.9; }

.mark {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 0.8rem;
  line-height: 1;
  color: var(--ink-faint);
  background: transparent;
  border: 1px solid currentColor;   /* the rehearsal-mark rectangle */
  border-radius: 1px;
  cursor: pointer;
  transition: color 0.5s ease, background-color 0.5s ease, border-color 0.5s ease;
}

.mark:hover { color: var(--ink); }
.mark:focus-visible {
  color: var(--ink);
  outline: none;
  box-shadow: 0 0 0 2px rgba(233, 227, 216, 0.35);
}

/* An engaged toggle (mute on, hover mode on, mosaic open) reads like a marked
   rehearsal letter: filled and inverted. */
.mark[aria-pressed="true"] {
  color: var(--bg);
  background: var(--ink-soft);
  border-color: var(--ink-soft);
}

/* A brief glow when a mark is triggered — especially by keyboard. */
@keyframes mark-flash {
  from { color: var(--ink); border-color: var(--ink); }
  to   { color: var(--ink-faint); border-color: var(--ink-faint); }
}
.mark.is-flash { animation: mark-flash 0.7s ease; }

/* ----------------------------------------------------------------------------
   The "All" mosaic: the whole series at a glance. No painting is cropped.
   ------------------------------------------------------------------------- */

/* The mosaic lives in the page, taking the place of the single frame — so the
   name, title and contact stay present and the tune keeps playing. */
.mosaic {
  display: none;
  width: 100%;
  max-width: min(900px, 92vw);
  height: 70vh;               /* the same footprint as the single frame */
  height: 70svh;
  margin: 0 auto;
}

body.mosaic-open .gallery { display: none; }
body.mosaic-open .mosaic {
  display: block;
  animation: fade-soft 2s ease both;   /* the slow arrival into the wall */
}

/* A grid sized to fill the frame exactly — so the whole series fits with no
   scrollbars. Four columns over two rows; the wide group scene spans two cells,
   so all eight cells are filled by the seven paintings (no awkward gaps). The
   paintings keep their true shapes (centred, never cropped); with the gentle
   rotations the wall still reads as scattered, not gridded. */
.mosaic__grid {
  height: 100%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(0, 1fr);   /* minmax(0,…) lets rows shrink to fit */
  grid-auto-flow: dense;
  gap: clamp(0.5rem, 1.6vw, 1.1rem);
}
.mosaic__tile--wide { grid-column: span 2; }
@media (max-width: 720px) { .mosaic__grid { grid-template-columns: repeat(2, 1fr); } }

.mosaic__tile {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  padding: 0;
  min-width: 0;               /* allow the cell to shrink below content size */
  min-height: 0;
  overflow: hidden;
  background: transparent;
  border: none;
  cursor: pointer;
  opacity: 0.8;
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.mosaic__tile img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;        /* keep aspect within the cell, never crop */
}

/* A gentle, hand-pinned scatter. */
.mosaic__tile:nth-child(4n+1) { transform: rotate(-1.2deg); }
.mosaic__tile:nth-child(4n+2) { transform: rotate(0.8deg); }
.mosaic__tile:nth-child(4n+3) { transform: rotate(-0.5deg); }
.mosaic__tile:nth-child(4n+4) { transform: rotate(1.1deg); }

.mosaic__tile:hover,
.mosaic__tile:focus-visible {
  opacity: 1;
  transform: rotate(0deg) scale(1.04);   /* straightens and lifts on attention */
  outline: none;
}

/* ----------------------------------------------------------------------------
   Focus view: one painting, full size, with nothing else around it.
   ------------------------------------------------------------------------- */

.name, .work__caption, .contact { transition: opacity 1s ease; }

body.is-focused .name,
body.is-focused .work__caption,
body.is-focused .contact {
  opacity: 0 !important;       /* overrides the reveal animation */
  pointer-events: none;
}

body.is-focused .gallery {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;            /* iOS: fill the currently visible viewport */
  max-width: none;
  z-index: 7;                /* above the mosaic, so it blooms in over the wall */
  display: grid;             /* show even while the mosaic underneath stays open */
  background: var(--bg-edge);
  cursor: zoom-out;
  animation: fade-soft 0.8s ease both;   /* a gentle bloom when a painting opens */
}

body.is-focused .slide {
  max-width: 100vw;
  max-height: 100vh;
  max-height: 100dvh;
}

/* ----------------------------------------------------------------------------
   The quiet reveal: each element rises out of the dusk in turn —
   first the painting, then its title, then the way to reach her.
   ------------------------------------------------------------------------- */

@keyframes fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The name doesn't rise — it simply surfaces, in place, very gently. */
@keyframes fade-soft {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.reveal {
  opacity: 0;
  animation-name: fade-up;
  animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  animation-fill-mode: both;
}

/* Slow, staggered — about a seven-second unfolding. */
.reveal--name {
  animation-name: fade-soft;
  animation-timing-function: ease-in-out;
  animation-duration: 5s;
  animation-delay: 0.4s;
}
.reveal--title   { animation-duration: 2.0s; animation-delay: 13.5s; }
.reveal--contact { animation-duration: 1.8s; animation-delay: 15.3s; }

/* Respect anyone who prefers no motion — show everything, calmly, at once. */
@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    animation: none;
    transform: none;
  }
  .mark.is-flash { animation: none; }
  .mosaic { transition: opacity 0.2s ease, visibility 0s; }
  body.is-focused .gallery { animation: none; }
}
