/*
  Amiri Fine Arts.

  Every value here was measured off the live Squarespace site with a headless
  browser reading computed styles, not guessed from its CSS bundle. That
  distinction cost a round: the bundle's most common background colour is
  #272727, which is nowhere on the rendered page -- the body is #616161, a mid
  grey, and building against the stylesheet produced a site that was far too
  dark and looked nothing like the original.

      body            #616161
      site title      futura-pt 700, 42px, uppercase, 1px tracking,  #222
      nav             futura-pt 400, 13px, uppercase, 1px tracking,  #999
      nav (current)                                                  #111
      section label   futura-pt 300, 14px, uppercase, 0.84px,        #bfbfbf
      body text       #fff
      content column  960px, centred
      covers          4 across, 204px each, 48px apart  (4x204 + 3x48 = 960)

  The image drop shadow is from Fahimeh's own custom CSS -- the only styling
  she had written herself, so it is the one rule that is certainly deliberate:

      .image img, .project-image { box-shadow: 5px 5px 40px rgba(0,0,0,.3) }
*/

:root {
  --bg: #616161;
  --bg-raised: #565656;
  --ink: #fff;
  --ink-dim: #bfbfbf;
  --ink-dark: #222;
  --ink-darker: #111;
  --nav: #999;
  --rule: rgba(255, 255, 255, 0.18);

  /*
    futura-pt and proxima-nova were licensed through Squarespace and cannot
    come with the content. Jost is the closest free geometric sans to
    futura-pt; Nunito Sans stands in for proxima-nova.
  */
  --display: "Jost", "Futura", "Century Gothic", sans-serif;
  --body: "Nunito Sans", "Helvetica Neue", Arial, sans-serif;

  --content: 960px;
  --outer-padding: 24px;
  --page-padding: 50px;
  --gutter: 48px;
  --thumb-max: 400px;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------- announcement */

/*
  A line of news above everything else, full width, in the wordmark's own
  near-black -- so it reads as the masthead speaking rather than as something
  pasted on top of it. Set in _config.yml.
*/
/*
  Text a step down from white, and underlines a step down from that: on the
  near-black, full white and white underlines read louder than a line of news
  should.
*/
.announcement {
  background: var(--ink-dark);
  color: #d4d4d4;
  padding: 0.7rem var(--outer-padding);
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
}

.announcement p { margin: 0; }
.announcement a {
  color: inherit;
  text-decoration-color: rgba(212, 212, 212, 0.4);
  text-underline-offset: 3px;
}
.announcement a:hover { color: #fff; text-decoration-color: currentColor; }

/* ---------------------------------------------------------------- header */

/*
  The header and every page share one 960px column, centred. The old site put
  the title hard left and the nav hard right on that same column.
*/
.site-header,
.site-main {
  max-width: var(--content);
  margin: 0 auto;
  padding-left: var(--outer-padding);
  padding-right: var(--outer-padding);
  box-sizing: content-box;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: 3.5rem;
}

/* Dark on the grey ground, not light -- this is the one piece of the page
   that is nearly black, and it carries the whole masthead. */
.site-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 42px;
  line-height: 1;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-dark);
  text-decoration: none;
}

.site-nav { display: flex; flex-wrap: wrap; gap: 1.9rem; }

.site-nav a {
  font-family: var(--display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--nav);
  text-decoration: none;
}

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

/* ------------------------------------------------------------------ main */

.site-main { padding-top: var(--page-padding); padding-bottom: 4rem; }

.prose { max-width: 42rem; }
.prose p { margin: 0 0 1.25rem; }
.prose a { color: var(--ink); }

/*
  Two heading sizes, both futura-pt light and uppercase, measured off the old
  site: 32px for a page's own title, 25.6px for a heading within it.
*/
h1,
h2.section-heading,
.section-meta h1 {
  font-family: var(--display);
  font-weight: 300;
  text-transform: uppercase;
  color: var(--ink);
}

h1 {
  margin: 0 0 1.5rem;
  font-size: 32px;
  line-height: 1.5;
  letter-spacing: 1.92px;
}

h2.section-heading {
  margin: 3.5rem 0 1.5rem;
  font-size: 25.6px;
  line-height: 1.2;
  letter-spacing: 1.536px;
}

/* ------------------------------------------------- collection index (home) */

/*
  Four covers, one per section. Squarespace cropped these to squares and gave
  them the same drop shadow as everything else; the source images are already
  square (432x432, 461x461, ...), so object-fit only guards against a future
  cover that is not.
*/
.index {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  gap: var(--gutter);
  grid-template-columns: repeat(auto-fill, minmax(min(204px, 100%), 1fr));
}

@media (min-width: 760px) {
  .index { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.index a {
  display: block;
  text-align: center;
  text-decoration: none;
  color: var(--ink-dim);
}

.index-cover { display: block; }

.index-cover img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 4%;
  box-shadow: 5px 5px 40px rgba(0, 0, 0, 0.3);
  transition: transform 150ms ease;
}

.index a:hover .index-cover img { transform: translateY(-2px); }

.index-title {
  display: block;
  margin-top: 1rem;
  font-family: var(--display);
  font-weight: 300;
  font-size: 14px;
  letter-spacing: 0.84px;
  text-transform: uppercase;
}

.index a:hover .index-title { color: var(--ink); }

/* ------------------------------------------------------------- a section */

/*
  Works down the left, the section's name and description on the right.
  420 + 50 + 490 = the 960px content column, measured off the old site.
*/
.section { display: grid; gap: 2.5rem; }

@media (min-width: 860px) {
  .section {
    grid-template-columns: 420px 490px;
    column-gap: 50px;
    align-items: start;
  }
}

/* A section's name sits at 25.6px, the in-page heading size. */
.section-meta h1 {
  font-size: 25.6px;
  line-height: 1.2;
  letter-spacing: 1.536px;
}

.section-meta p { margin: 0 0 1.25rem; }

/* 32px between works, as the old site had. */
.section-works { display: flex; flex-direction: column; gap: 32px; }

.work { margin: 0; }

/*
  The dark frame is Fahimeh's, out of her custom CSS -- a 10px mat around every
  painting, with the drop shadow outside it. Together they are what makes the
  work read as hung rather than pasted onto the page.
*/
.work img {
  display: block;
  width: 100%;
  height: auto;
  border: 10px solid #2b2b2b;
  box-sizing: border-box;
  box-shadow: 5px 5px 40px rgba(0, 0, 0, 0.3);
}

.work-link { display: block; cursor: zoom-in; }

.work figcaption {
  margin-top: 0.6rem;
  text-align: center;
}

.work-title { display: block; font-weight: 700; }
.work-note { display: block; }
.work-price { display: block; color: var(--ink-dim); }

/* ------------------------------------------------------------- lightbox */

/*
  A section's works, full screen. Three columns: a rail either side for the
  arrows, the painting between them. The rails are always there, even with the
  arrows hidden, so a painting never sits under a control.

  The ground is near-black rather than the site's grey: this is the one place
  the work is shown bare, without its mat, and a dark surround is what lets a
  painting's own colour read true.
*/
.lightbox {
  --rail: 72px;

  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: #1c1c1c;
  color: var(--ink);
  overflow: hidden;

  /*
    Nothing in here is for selecting. Clicking the arrows quickly counts as a
    double- or triple-click to the browser, which selects the caption or tints
    the painting blue; a long press on a phone does the same. The image is also
    draggable="false", for the same reason with a mouse.
  */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

.lightbox[open] {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr) var(--rail);
  align-items: center;
}

.lightbox::backdrop { background: #1c1c1c; }
.lightbox:focus { outline: none; }

/* The page underneath stays put while the view is open. */
html:has(.lightbox[open]) { overflow: hidden; }

.lightbox-figure {
  grid-column: 2;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 0;
  padding: 3.5rem 0 1.5rem;
}

/*
  As large as fits, never cropped -- and scaled up to get there. Many of the
  originals are small (Blue Hair is 436x576), and left at their own size they
  sat in the middle of the screen looking like a mistake; filled, the small
  ones go a little soft, which is the photograph's limit rather than the page's.

  lightbox.js sets --ratio, the work's width over its height. The painting is
  then as wide as the space allows, unless that would make it taller than the
  screen less room for the caption, in which case the height decides. Sizing
  it this way, rather than filling a box with object-fit, keeps the caption
  directly under the painting instead of under an invisible letterbox.

  dvh is the height a phone actually shows once its toolbars are accounted
  for; vh is the fallback where it is not understood.
*/
.lightbox-figure img {
  --avail-height: calc(100vh - 9rem);
  --avail-height: calc(100dvh - 9rem);

  display: block;
  width: min(100%, calc(var(--avail-height) * var(--ratio, 1)));
  height: auto;
  aspect-ratio: var(--ratio, auto);

  /* What shows in the frame before the first of the painting arrives. */
  background: #262626;
}

.lightbox-figure figcaption {
  margin-top: 1rem;
  text-align: center;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-dim);
}

.lightbox-figure figcaption strong { display: block; color: var(--ink); }
.lightbox-figure figcaption span { display: block; }

.lightbox-control {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  background: none;
  border: 0;
  color: #fff;
  opacity: 0.6;
  cursor: pointer;
  transition: opacity 150ms ease;
}

.lightbox-control:hover { opacity: 1; }
.lightbox-control:focus-visible { outline: 1.5px solid #fff; outline-offset: 2px; opacity: 1; }

.lightbox-control svg {
  width: 28px;
  height: 28px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5px;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

.lightbox-control svg path { vector-effect: non-scaling-stroke; }

.lightbox-prev { grid-column: 1; grid-row: 1; justify-self: center; }
.lightbox-next { grid-column: 3; grid-row: 1; justify-self: center; }
.lightbox-figure { grid-row: 1; }

.lightbox-close {
  position: absolute;
  top: 12px;
  right: 12px;
}

.lightbox.is-single .lightbox-prev,
.lightbox.is-single .lightbox-next { visibility: hidden; }

/* A phone has no room to spare for the rails; they narrow to the button. */
@media (max-width: 700px) {
  .lightbox { --rail: 44px; }
  .lightbox-control { width: 44px; height: 44px; }
  .lightbox-control svg { width: 24px; height: 24px; }
  .lightbox-close { top: 6px; right: 6px; }
}

/* ---------------------------------------------------------------- split */

/*
  Prose beside a carousel: Profile's 5 | 7 split. One column on a narrow
  screen, with the carousel first, because a portrait photograph reads better
  above a bio than below it.
*/
.split { display: grid; gap: 2.5rem; align-items: start; }

/*
  Grid items default to min-width:auto, which lets a wide image push its column
  past the track it was given -- a 4000px photograph then drags the carousel
  across the prose beside it. min-width:0 lets the track do its job.
*/
.split > * { min-width: 0; }

@media (min-width: 950px) {
  .split { gap: 4rem; }
  .split-narrow-first { grid-template-columns: 5fr 7fr; }
}

.split .prose { max-width: none; }

/* -------------------------------------------------------------- carousel */

.carousel { min-width: 0; }

.carousel-stage {
  position: relative;
  display: flex;
  align-items: center;
}

.carousel-slides {
  position: relative;
  flex: 1;
  min-width: 0;
}

/*
  Every slide is in the DOM. The non-current ones are taken out of the layout
  with position:absolute rather than display:none, so the stage keeps the
  height of whichever slide is showing and the page does not jump on advance.
  visibility (not just opacity) so a hidden slide is skipped by screen readers
  and cannot be tabbed into.
*/
.carousel-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 220ms ease;
}

.carousel-slide.is-current {
  position: relative;
  opacity: 1;
  visibility: visible;
}

.carousel-slide img {
  display: block;
  width: 100%;
  height: auto;
  box-shadow: 5px 5px 40px rgba(0, 0, 0, 0.3);
}

.carousel-slide figcaption {
  margin-top: 0.85rem;
  font-size: 0.9rem;
  color: var(--ink-dim);
}

/*
  The arrows sit over the image, as they did on the old site. They are real
  buttons, so they are reachable by keyboard; the arrow keys work too, once the
  carousel has focus.
*/
.carousel-arrow {
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  padding: 0 0.85rem;
  background: none;
  border: 0;
  cursor: pointer;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
  opacity: 0.75;
  transition: opacity 150ms ease;
}

.carousel-arrow:hover { opacity: 1; }
.carousel-arrow:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

[data-carousel-prev] { left: 0; }
[data-carousel-next] { right: 0; }

/* One image is not a slideshow; carousel.js says so and the controls go. */
.carousel.is-single .carousel-arrow,
.carousel.is-single .carousel-thumbs { display: none; }

/*
  One row, scrolling sideways when it does not fit -- the old site's strip runs
  off the edge of its column rather than wrapping, which is what keeps a
  17-image slideshow from pushing the page down by three rows of thumbnails.

  Thumbnails keep their own proportions at a fixed height, so a portrait and a
  landscape photograph both read correctly in the same strip.
*/
.carousel-thumbs {
  display: flex;
  flex-wrap: nowrap;
  gap: 0;
  margin-top: 0.75rem;
  overflow-x: auto;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}

.carousel-thumb {
  flex: 0 0 auto;
  height: var(--thumb-height, 80px);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 150ms ease;
}

.carousel-thumb img {
  display: block;
  width: auto;
  height: 100%;
}

.carousel-thumb:hover { opacity: 0.8; }
.carousel-thumb.is-current { opacity: 1; }
.carousel-thumb:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* Per-page thumbnail heights, as the old site had them. */
#profile { --thumb-height: 80px; }


@media (prefers-reduced-motion: reduce) {
  .carousel-slide { transition: none; }
  .index-cover img { transition: none; }
}

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

.message-form { max-width: 32rem; margin-top: 1.5rem; }

.message-form label {
  display: block;
  margin-bottom: 1.25rem;
  font-family: var(--display);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.message-form input,
.message-form textarea {
  display: block;
  width: 100%;
  margin-top: 0.5rem;
  padding: 0.7rem 0.8rem;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
}

.message-form input:focus,
.message-form textarea:focus { outline: 2px solid var(--ink-dim); outline-offset: 1px; }

.message-form textarea { min-height: 9rem; resize: vertical; }

.message-form button {
  font-family: var(--display);
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.75rem 1.75rem;
  background: var(--ink);
  color: var(--bg);
  border: 0;
  cursor: pointer;
}

.message-form button:disabled { opacity: 0.5; cursor: default; }

/*
  The honeypot. Not display:none -- some bots skip hidden fields, and some
  password managers refuse to fill them. Off-screen and untabbable catches
  more, and no human ever sees it.
*/
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status { margin-top: 1rem; min-height: 1.4em; color: var(--ink-dim); }
.form-status[data-state="error"] { color: #f0523d; }

/* ---------------------------------------------------------------- mobile */

@media (max-width: 700px) {
  :root { --page-padding: 28px; --gutter: 24px; }
  .site-header { padding-top: 1.75rem; }
  .site-title { font-size: 26px; }
  .site-nav { gap: 1rem; }
}
