/* caricaburu.com
 *
 * One stylesheet, replacing Bootstrap, the inherited theme's style.css, animsition, magnific
 * popup, simpletextrotator and the rest. The grid that Isotope used to compute in JavaScript
 * after every image loaded is now plain CSS, because the server knows each painting's
 * proportions and writes them into the markup.
 */

:root {
  --ink: #1a1a1a;
  --ink-soft: #5a5a5a;
  --ink-faint: #8a8a8a;
  --paper: #ffffff;
  --rule: #e4e4e4;
  --accent: #1a1a1a;

  --measure: 34rem;
  --gutter: clamp(1rem, 3vw, 2.5rem);
  --header-height: 4.5rem;

  --sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: Georgia, "Times New Roman", serif;
}

/* The site commits to a light presentation: these are paintings, and a dark canvas would
   change how every one of them reads. Only the chrome softens in dark mode. */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f0f0f0;
    --ink-soft: #b4b4b4;
    --ink-faint: #8a8a8a;
    --paper: #141414;
    --rule: #2e2e2e;
    --accent: #ffffff;
  }
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

/* Cross-document view transitions bring back the page fade that Animsition provided, without
   the library or the single-page app it depended on. Browsers that do not support it simply
   navigate normally. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--paper);
  color: var(--ink);
  padding: 0.75rem 1rem;
  z-index: 100;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.container {
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

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

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 var(--gutter);
  height: var(--header-height);
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  background: var(--paper);
  z-index: 20;
}

.logo a {
  font-family: var(--serif);
  font-size: 1.25rem;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.site-nav ul {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.25rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav a {
  text-decoration: none;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.5rem 0;
  border-bottom: 1px solid transparent;
}

.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); }

.site-nav .instagram a { display: flex; align-items: center; gap: 0.4rem; }
.site-nav .instagram .label { display: none; }

/* The menu button and its checkbox exist only below the breakpoint. */
.menu-toggle, .menu-button { display: none; }

@media (max-width: 46rem) {
  .menu-button {
    display: block;
    width: 2rem;
    height: 2rem;
    position: relative;
    cursor: pointer;
  }
  .menu-button span,
  .menu-button span::before,
  .menu-button span::after {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: 1px;
    background: var(--ink);
    transition: transform 0.2s ease;
  }
  .menu-button span { top: 50%; }
  .menu-button span::before { top: -7px; }
  .menu-button span::after { top: 7px; }

  .site-nav {
    position: absolute;
    top: var(--header-height);
    left: 0;
    right: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    display: none;
  }
  .site-nav ul { flex-direction: column; align-items: flex-start; gap: 0; padding: 0.5rem var(--gutter) 1.25rem; }
  .site-nav li { width: 100%; }
  .site-nav a { display: block; padding: 0.7rem 0; }

  .menu-toggle:checked ~ .site-nav { display: block; }
  .menu-toggle:checked ~ .menu-button span { background: transparent; }
  .menu-toggle:checked ~ .menu-button span::before { transform: translateY(7px) rotate(45deg); }
  .menu-toggle:checked ~ .menu-button span::after { transform: translateY(-7px) rotate(-45deg); }

  .site-nav .instagram .label { display: inline; }
}

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

/* The hero appears on the landing page only. On the works pages it used to remain in the flow
   while hidden, which is where the roughly 250px of dead space above the gallery filters came
   from; those pages no longer render it at all. */
.hero {
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

/* The anchor has to be a block, or it takes the line height of the text it is not made of and
   leaves a gap under the image. */
.hero-link {
  display: block;
}

.hero img {
  display: block;
  width: 100%;
  height: clamp(20rem, 62vh, 40rem);
  object-fit: cover;

  /* The band is far wider than a canvas, so most of a painting's height is cropped away. This
     is where that crop sits when nothing says otherwise; a chosen hero overrides it inline with
     its own focal point, since where the subject sits differs from work to work. */
  object-position: center 40%;
}

/* --- Gallery navigation ------------------------------------------------------------------ */

.gallery-heading {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 3.5vw, 2.25rem);
  margin: 0 0 0.35rem;
}

.gallery-intro {
  margin: 0 0 1.5rem;
  color: var(--ink-soft);
  max-width: var(--measure);
}

.gallery-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  list-style: none;
  margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
  padding: 0 0 1rem;
  border-bottom: 1px solid var(--rule);
}

.gallery-nav a {
  text-decoration: none;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

.gallery-nav a:hover { color: var(--ink); }
.gallery-nav a.current { color: var(--ink); }

/* A count per gallery, which the old filter buttons never showed. */
.gallery-nav .count {
  font-size: 0.6875rem;
  letter-spacing: 0;
  vertical-align: super;
  color: var(--ink-faint);
  margin-left: 0.15rem;
}

/* --- Works grid -------------------------------------------------------------------------- */

/* A grid rather than a masonry library, and specifically a grid rather than CSS columns.
 *
 * Columns would give the masonry look, but they fill top-to-bottom before moving right: with 24
 * works in two columns the reader sees item 1 beside item 13, while the previous/next links on
 * each painting follow the curated order. The eye and the links would disagree.
 *
 * Masonry costs little here anyway. Of the forty works with recorded dimensions, thirty-five are
 * exactly square; the collection is a square grid with five exceptions. Those five keep their
 * own proportions and the row simply grows to fit them.
 */
.works-grid {
  list-style: none;
  margin: 0 0 4rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  gap: clamp(1.25rem, 2.5vw, 2.25rem) clamp(0.75rem, 2vw, 1.75rem);
}

.works-grid a {
  text-decoration: none;
  display: block;
}

.work-frame {
  display: block;
  width: 100%;
  background: var(--rule);
  overflow: hidden;
}

.work-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.25s ease;
}

.works-grid a:hover .work-frame img { opacity: 0.82; }

/* Titles used to live in a hover overlay, which meant the grid was completely untitled on any
   touch device. They are part of the tile now. */
.work-caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.1rem 0;
}

.work-name {
  font-size: 0.875rem;
  color: var(--ink);
}

.work-sold,
.painting-facts .sold {
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

@media (max-width: 62rem) {
  .works-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Two columns on a phone rather than one. The default gallery holds 24 works, which at one
   per row was 24 screens of scrolling. */
@media (max-width: 30rem) {
  .works-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 0.6rem;
  }
  .work-name { font-size: 0.75rem; }
}

.empty { color: var(--ink-faint); margin: 2rem 0 4rem; }

/* --- Painting page ----------------------------------------------------------------------- */

.painting-layout {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  grid-template-areas:
    "breadcrumb breadcrumb"
    "figure     details"
    "pager      pager";
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding-top: 1.5rem;
  padding-bottom: 4rem;
}

.breadcrumb { grid-area: breadcrumb; font-size: 0.8125rem; color: var(--ink-faint); }
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb span { margin: 0 0.4rem; }

.painting-figure { grid-area: figure; margin: 0; }
.painting-frame { display: block; width: 100%; background: var(--rule); }
.painting-frame img { width: 100%; height: 100%; object-fit: contain; }

.painting-details { grid-area: details; }

.painting-name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.35rem, 3vw, 1.9rem);
  margin: 0 0 0.75rem;
}

.painting-description { color: var(--ink-soft); max-width: var(--measure); }

.painting-facts {
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1.25rem;
  font-size: 0.9375rem;
}

.painting-facts dt {
  color: var(--ink-faint);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  align-self: baseline;
}

.painting-facts dd { margin: 0; }

.painting-enquire { margin-top: 1.75rem; }

.painting-enquire a {
  display: inline-block;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--ink);
  text-decoration: none;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.painting-enquire a:hover { background: var(--ink); color: var(--paper); }

.painting-pager {
  grid-area: pager;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.painting-pager a, .painting-pager .disabled {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  max-width: 45%;
}

.painting-pager .next { text-align: right; align-items: flex-end; }

.painting-pager .direction {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.painting-pager .title {
  font-size: 0.9375rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Kept in the layout rather than removed, so the remaining control does not jump sides at the
   ends of a gallery. */
.painting-pager .disabled { opacity: 0.3; }

@media (max-width: 52rem) {
  .painting-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "breadcrumb" "figure" "details" "pager";
  }
}

/* --- Prose pages ------------------------------------------------------------------------- */

.prose-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
  padding-top: clamp(2rem, 5vw, 3.5rem);
  padding-bottom: 4rem;
}

@media (max-width: 52rem) {
  .prose-layout { grid-template-columns: minmax(0, 1fr); }
  .prose-layout .portrait { order: -1; max-width: 22rem; }
}

.prose { max-width: var(--measure); padding-top: clamp(2rem, 5vw, 3rem); }
.prose-layout .prose { padding-top: 0; }

.prose h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 3.5vw, 2.25rem);
  margin: 0 0 1rem;
}

.prose p { margin: 0 0 1.1rem; color: var(--ink-soft); }

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

.contact-form {
  display: grid;
  gap: 0.35rem;
  max-width: 32rem;
  margin: 2rem 0 4rem;
}

.contact-form label {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: 0.75rem;
}

.contact-form input,
.contact-form textarea {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 1px solid var(--rule);
  padding: 0.65rem 0.75rem;
  width: 100%;
}

.contact-form input:focus,
.contact-form textarea:focus { border-color: var(--ink); outline: none; }

.contact-form textarea { resize: vertical; }

.contact-form button {
  font: inherit;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 1.25rem;
  padding: 0.75rem 1.5rem;
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
  cursor: pointer;
  justify-self: start;
}

.contact-form button:hover { background: transparent; color: var(--ink); }

.notice {
  max-width: 32rem;
  margin: 1.5rem 0 0;
  padding: 0.85rem 1rem;
  border-left: 2px solid var(--ink);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}

.notice.error { border-left-color: #b3261e; }

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

.site-footer {
  border-top: 1px solid var(--rule);
  padding: 2rem var(--gutter);
  text-align: center;
}

.site-footer p {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

/* --- Lightbox ---------------------------------------------------------------------------- */

/* Created by site.js on painting pages. A <dialog> handles the backdrop, focus trapping and
   Escape for free, which is what Magnific Popup was carried for. */
.painting-frame.zoomable { cursor: zoom-in; }

.lightbox {
  border: none;
  padding: 0;
  max-width: 100vw;
  max-height: 100vh;
  width: 100%;
  height: 100%;
  background: transparent;
  overscroll-behavior: contain;
}

.lightbox::backdrop { background: rgba(0, 0, 0, 0.92); }

.lightbox img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: zoom-out;
}

.lightbox-close {
  position: fixed;
  top: 1rem;
  right: 1.25rem;
  z-index: 1;
  width: 2.75rem;
  height: 2.75rem;
  font-size: 2rem;
  line-height: 1;
  color: #fff;
  background: transparent;
  border: none;
  cursor: pointer;
}

/* Available to screen readers and to a search engine, absent from the visual design. Used for
   the home page's h1, where the artist's name is the subject of the page but the hero image is
   what should be seen. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
