@charset "utf-8";

/* =============================================================================
   grantbayart.com — DESIGN 2: "GROTESK" (Instrument Sans edition)
   Hand-written, dependency-free. No frameworks, no external requests.

   Design 2's layout and voice — lowercase wordmark, tight tracking, big
   display-size gallery headings on the warm paper — set in Instrument Sans
   (self-hosted, SIL OFL), the typeface from design 1.
   ========================================================================== */

@font-face {
  font-family: "Instrument Sans";
  src: url("../fonts/instrument-sans.woff2") format("woff2");
  font-weight: 400 700;   /* variable file: one download covers every weight */
  font-style: normal;
  font-display: swap;
}

/* --- tokens --------------------------------------------------------------- */

:root {
  --paper:        #f6f5f2;
  --paper-raised: #ffffff;
  --ink:          #17130d;
  --ink-muted:    #6a675f;
  --ink-faint:    #a5a29a;
  --rule:         #e0ded7;
  --backdrop:     #0c0c0d;

  --font: "Instrument Sans", -apple-system, "Helvetica Neue", Arial, sans-serif;

  --measure: 34rem;          /* comfortable reading width for prose */
  --shell:   96rem;          /* outer page width */
  --pad:     clamp(1.25rem, 5vw, 4rem);
  --gap:     clamp(0.75rem, 2.2vw, 1.75rem);

  --step--1: clamp(0.75rem, 0.72rem + 0.15vw, 0.82rem);
  --step-0:  clamp(0.95rem, 0.9rem + 0.2vw, 1.05rem);
  --step-1:  clamp(1.1rem, 1rem + 0.4vw, 1.3rem);
  --step-2:  clamp(1.6rem, 1.3rem + 1.4vw, 2.4rem);
  --step-3:  clamp(2.2rem, 1.6rem + 3vw, 4.5rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --header-h: 4.5rem;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:        #100f10;
    --paper-raised: #191819;
    --ink:          #eceae4;
    --ink-muted:    #9a968d;
    --ink-faint:    #66635c;
    --rule:         #2a2927;
    --backdrop:     #000000;
  }
}

/* --- reset ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

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

h1, h2, h3, h4 {
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

ul { margin: 0; padding: 0; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:hover { text-decoration-color: var(--ink-faint); }

button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--pad);
  top: -100%;
  z-index: 100;
  padding: 0.7rem 1.1rem;
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
}
.skip-link:focus { top: 0.75rem; }

/* --- layout --------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.page { padding-block: clamp(3rem, 9vw, 7rem); }

.prose { max-width: var(--measure); }

.eyebrow {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin: 0 0 0.9rem;
}

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

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Opaque fallback first: an engine without color-mix() would drop the
     declaration entirely and leave the header transparent over the artwork. */
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}

@supports (backdrop-filter: blur(1px)) {
  .header { backdrop-filter: saturate(1.6) blur(14px); }
}

.header[data-scrolled="true"] { border-bottom-color: var(--rule); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--header-h);
}

/* Slightly oversized and tightly tracked — the wordmark reads as a signature
   rather than signage. Sentence case, as authored in the markup. */
.wordmark {
  font-size: clamp(1.3rem, 1.15rem + 0.7vw, 1.65rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  text-decoration: none;
  white-space: nowrap;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.6vw, 2.4rem);
  list-style: none;
}

.nav__link {
  display: inline-block;
  padding-block: 0.35rem;
  font-size: var(--step-0);
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--ink-muted);
  position: relative;
  transition: color 0.25s var(--ease);
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}

.nav__link:hover { color: var(--ink); }
.nav__link:hover::after { transform: scaleX(1); }

.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* mobile disclosure */

.nav__toggle {
  display: none;
  background: none;
  border: 0;
  padding: 0.6rem;
  margin-right: -0.6rem;
  cursor: pointer;
}

.nav__toggle svg { width: 1.35rem; height: 1.35rem; }
.nav__toggle .icon--close,
.nav__toggle[aria-expanded="true"] .icon--open { display: none; }
.nav__toggle[aria-expanded="true"] .icon--close { display: block; }

@media (max-width: 46em) {
  .nav__toggle { display: block; }

  .nav__list {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 0.5rem var(--pad) 1.75rem;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    transform: translateY(-0.5rem);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease),
                visibility 0.25s;
  }

  .nav[data-open="true"] .nav__list {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .nav__link {
    width: 100%;
    padding-block: 0.85rem;
    font-size: var(--step-0);
    letter-spacing: 0.1em;
    border-bottom: 1px solid var(--rule);
  }
  .nav__list li:last-child .nav__link { border-bottom: 0; }
  .nav__link::after { display: none; }
}

/* --- hero ----------------------------------------------------------------- */

/* Height comes from the .home flex column above, not from a viewport unit —
   that way the carousel and footer together fill the screen exactly, with no
   stray scrollbar and no guessing at the footer's height. */
.hero {
  position: relative;
  padding-bottom: 3.25rem;   /* clearance for the dot controls */
  background: var(--paper);
  overflow: hidden;
}

.hero__track {
  position: relative;
  list-style: none;
  height: 100%;
}

.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.1s var(--ease);
  pointer-events: none;
}

.hero__slide[data-active="true"] { opacity: 1; }

.hero__slide picture,
.hero__slide img {
  width: 100%;
  height: 100%;
}

.hero__slide img { object-fit: contain; object-position: center; }

.hero__controls {
  position: absolute;
  left: 50%;
  bottom: 0.6rem;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.7rem;
  border-radius: 999px;
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 72%, transparent);
}

@supports (backdrop-filter: blur(1px)) {
  .hero__controls { backdrop-filter: blur(10px); }
}

.hero__dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink-faint);
  cursor: pointer;
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}

.hero__dot[aria-current="true"] {
  background: var(--ink);
  transform: scale(1.35);
}

.hero__pause {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin-left: 0.2rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  color: var(--ink-muted);
}
.hero__pause:hover { color: var(--ink); }
.hero__pause svg { width: 0.85rem; height: 0.85rem; }
.hero__pause .icon--play { display: none; }
.hero__pause[data-paused="true"] .icon--play { display: block; }
.hero__pause[data-paused="true"] .icon--pause { display: none; }

/* --- homepage: one screen, nothing else ----------------------------------- */
/* The carousel takes whatever height the header and footer leave, so the page
   holds no scroll at all and the work is the entire homepage. Measured with
   flexbox rather than subtracting fixed heights, so it stays correct when the
   footer wraps to two lines on a narrow screen. */

.home {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.home > main {
  flex: 1 1 auto;
  display: flex;
  min-height: 0;
}

.home .hero {
  flex: 1 1 auto;
  width: 100%;
  height: auto;          /* overrides the fixed viewport height below */
  min-height: 16rem;     /* landscape phones still get a usable image */
}

/* --- section headings ----------------------------------------------------- */

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-bottom: clamp(1.75rem, 4vw, 3rem);
}

/* Full display size — this variant lets the headline be a graphic element. */
.section-head__title {
  font-size: var(--step-3);
  font-weight: 500;
}

.section-head__count {
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* --- gallery grid --------------------------------------------------------- */
/* Multi-column masonry: preserves every work's true aspect ratio, needs no JS,
   and produces zero layout shift because each img carries width/height. */

.grid {
  columns: 1;
  column-gap: var(--gap);
  list-style: none;
}

@media (min-width: 34em) { .grid { columns: 2; } }
@media (min-width: 62em) { .grid { columns: 3; } }
@media (min-width: 88em) { .grid { columns: 4; } }

.grid__item {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  margin-bottom: var(--gap);
}

.work {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-decoration: none;
  cursor: zoom-in;
  position: relative;
  overflow: hidden;
}

.work img {
  width: 100%;
  transition: transform 0.65s var(--ease), opacity 0.35s var(--ease);
  background: var(--rule);
}

/* Hairline edge so pale works don't bleed into the page background. */
.work::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.16);
  pointer-events: none;
}

@media (hover: hover) {
  .work:hover img { transform: scale(1.028); }
  .grid:hover .work:not(:hover) img { opacity: 0.62; }
}

/* --- lightbox ------------------------------------------------------------- */
/* Markup is created by site.js so it exists once per page and only when needed. */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  grid-template-rows: 1fr auto;
  background: var(--backdrop);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease), visibility 0.3s;
}

.lightbox[data-open="true"] { opacity: 1; visibility: visible; }

.lightbox__stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: clamp(2.75rem, 6vw, 4rem) clamp(0.75rem, 5vw, 5.5rem) 0.5rem;
}

.lightbox__figure {
  margin: 0;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-height: 0;
}

/* The <picture> wrapper needs a definite height of its own, otherwise the
   max-height:100% on the image below has nothing to resolve against and tall
   works overflow the viewer and cover the caption.
   Flex, not grid, on purpose: as a grid item the image's percentage max-height
   is not applied against the grid area and it overflows anyway. Verified in
   Chrome — a portrait work rendered 1169px tall inside a 641px box. */
.lightbox__figure picture {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  min-height: 0;
}

.lightbox__img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.lightbox__img[data-loaded="true"] { opacity: 1; }

.lightbox__bar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.85rem clamp(0.9rem, 5vw, 2rem) clamp(1rem, 3vw, 1.6rem);
  color: #f2f1ee;
}

.lightbox__caption { min-width: 0; }

.lightbox__title {
  font-size: var(--step-0);
  font-style: italic;
  margin: 0;
}

.lightbox__meta {
  font-size: var(--step--1);
  color: #97948d;
  margin: 0.15rem 0 0;
}

.lightbox__count {
  font-size: var(--step--1);
  color: #97948d;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  white-space: nowrap;
}

.lightbox__btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.09);
  color: #f2f1ee;
  cursor: pointer;
  transition: background 0.25s var(--ease), opacity 0.25s var(--ease);
}

.lightbox__btn:hover { background: rgba(255, 255, 255, 0.2); }
.lightbox__btn[disabled] { opacity: 0.25; cursor: default; }
.lightbox__btn svg { width: 1.1rem; height: 1.1rem; }

.lightbox__btn--prev { left: clamp(0.5rem, 2vw, 1.5rem); top: 50%; margin-top: -1.5rem; }
.lightbox__btn--next { right: clamp(0.5rem, 2vw, 1.5rem); top: 50%; margin-top: -1.5rem; }
.lightbox__btn--close { right: clamp(0.5rem, 2vw, 1.5rem); top: clamp(0.5rem, 2vw, 1.5rem); }

@media (max-width: 34em) {
  .lightbox__btn--prev, .lightbox__btn--next { top: auto; bottom: 0.25rem; margin-top: 0; }
  .lightbox__btn--prev { left: 0.5rem; }
  .lightbox__btn--next { right: 0.5rem; }
  .lightbox__bar { justify-content: center; text-align: center; padding-bottom: 4rem; }
}

body[data-lightbox-open="true"] { overflow: hidden; }

/* --- CV / about ----------------------------------------------------------- */

.about__grid {
  display: grid;
  gap: clamp(2.5rem, 7vw, 6rem);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 62em) {
  .about__grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
  .about__cv { position: sticky; top: calc(var(--header-h) + 2rem); }
}

.statement p {
  font-size: var(--step-1);
  font-weight: 400;  /* Instrument Sans starts at 400 — declare what renders */
  line-height: 1.6;
}

.cv__group { margin-bottom: 2.25rem; }
.cv__group:last-child { margin-bottom: 0; }

.cv__heading {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  padding-bottom: 0.6rem;
  margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--rule);
}

.cv__list { list-style: none; }

.cv__entry {
  display: grid;
  grid-template-columns: 4.75rem 1fr;
  gap: 0 1rem;
  padding-block: 0.5rem;
  font-size: var(--step-0);
}

.cv__year {
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  font-size: var(--step--1);
  padding-top: 0.2em;
}

.cv__detail em { color: var(--ink-muted); font-style: italic; }
.cv__detail span { display: block; color: var(--ink-muted); font-size: var(--step--1); }

/* --- contact -------------------------------------------------------------- */

.contact__line { margin-bottom: clamp(2rem, 5vw, 3.5rem); }

.contact__mail {
  display: inline-block;
  font-size: var(--step-2);
  font-weight: 400;  /* Instrument Sans starts at 400 — declare what renders */
  letter-spacing: -0.015em;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.15em;
  transition: border-color 0.3s var(--ease);
}
.contact__mail:hover { border-bottom-color: var(--ink); }

/* --- footer --------------------------------------------------------------- */

.footer {
  border-top: 1px solid var(--rule);
  padding-block: 2.5rem 3rem;
  font-size: var(--step--1);
  color: var(--ink-faint);
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 2rem;
}

.footer__links { display: flex; gap: 1.5rem; list-style: none; }
.footer__links a { text-decoration: none; }
.footer__links a:hover { color: var(--ink); }

/* --- error page ----------------------------------------------------------- */

.error {
  min-height: 68svh;
  display: grid;
  align-content: center;
  justify-items: start;
}

.error__code {
  font-size: var(--step-3);
  font-weight: 400;  /* Instrument Sans starts at 400 — declare what renders */
  font-variant-numeric: tabular-nums;
}

/* --- motion preferences --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .hero__slide { transition: none; }
  .work:hover img { transform: none; }
}

/* --- print ---------------------------------------------------------------- */

@media print {
  .header, .footer, .hero__controls, .lightbox, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
  .grid { columns: 2; }
}
