/* Illustration section — imports the shared chrome/vars from site.css like
   home.css and cv.css do, then widens <main> to double the standard 44rem
   reading width used on every other content page. Both the index page and
   the detail sub-pages (work/illustration/<collection>.html) share this same
   doubled width, matching the Animation page's width too — the piece grid
   and its images just scale up to fill it rather than being pinned to the
   959px title-card size. */

@import url("site.css");

main {
  max-width: calc(var(--max-width) * 2);
  padding-top: 6rem; /* doubled from site.css's shared 3rem — the gap
    below the top nav felt cramped on these pages specifically, so this
    overrides just here rather than changing every content page's main */
}

/* ---- Illustration index (work/illustration.html) — card grid ---- */
/* Each card links straight to that collection's detail page. Collections
   without their own hero image still show a plain tinted placeholder in
   .illustration-card-media until one's added — the hover/fade behaviour
   works the same either way. Title is hidden by default and fades in over
   the (dimmed) media on hover/focus, per spec: "card fades to reveal the
   title, click anywhere to open it". */
.illustration-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.illustration-card-link {
  position: relative;
  display: block;
  aspect-ratio: 924 / 518; /* matches the current title-card artwork's real
    pixel size (~1.784:1) — pinnacle-valley-title.webp is still the older
    1918x1071 export (~1.791:1), 0.4% off this ratio, imperceptible once
    re-exported at the same size as the other five it'll line up exactly.
    Using the artwork's own ratio here (instead of an unrelated number)
    means object-fit: cover below has nothing left to crop — the box shape
    matches the image exactly. */
  border-radius: 24px; /* matches .illustration-piece img in site.css and
    .illustration-lightbox-image below - one radius, everywhere a piece of
    artwork shows up on the site (this card is what Home's own showcase
    cards use too, via home.css's @import above) */
  overflow: hidden;
  box-shadow: 0 8px 36px rgba(0, 0, 0, 0.12); /* replaces the faint 1px
    border with a subtle drop shadow instead */
  text-decoration: none;
  will-change: transform; /* js/illustration-magnetic.js drives this
    element's transform continuously via requestAnimationFrame while
    hovered (translate/rotate/scale, easing toward the cursor) — no CSS
    transition here, since one racing against a value that's already
    updating every frame is what made the very first version of this
    effect feel janky. The rAF loop's own lerp is the only smoothing. */
}
.illustration-card-media {
  position: absolute;
  inset: 0;
  display: block;
  background: color-mix(in srgb, var(--cream) 8%, transparent); /* placeholder
    tint shown until a hero <img> is added inside this span */
  transition: opacity 0.3s ease;
}
/* Breakfast's showcase tile — the one animation among these illustration
   "cards". Wherever it's shown as a clickable card (Home, the Animation
   index), its markup carries BOTH .illustration-card-link and this class
   together on the same <a> — .illustration-card-link supplies the shared
   box-shadow, hover-dim/title-reveal and (wherever js/illustration-
   magnetic.js is loaded) the magnetic pull generically, so none of that
   needs repeating here. This block only holds what's genuinely different
   about it: a wide banner aspect-ratio instead of the illustration cards'
   tall one, and a lottie-tinted background instead of a placeholder tint
   for a not-yet-loaded photo. Its own detail page (work/illustration/
   breakfast.html) reuses this same class for the big showcase there too,
   just without .illustration-card-link, since that instance isn't a link.
   Width is deliberately left at a plain 100% default here — home.css and
   work.css each override it locally, since that's the one thing that
   actually differs by page (Home's ported section vs. the standalone
   Animation page's narrower two-card-width column); breakfast.html has
   no override, so it just fills its full-width <main> like this. */
.illustration-card-frame {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 959 / 259;
  border-radius: 12px;
  overflow: hidden;
}
.illustration-card-anim {
  background: #daedff;
}
.illustration-card-anim svg {
  display: block;
  width: 100%;
  height: 100%;
}
.illustration-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.illustration-card-title {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  text-align: center;
  color: var(--cream);
  font-weight: 700; /* bold, up from 600 */
  font-size: 2.3rem; /* doubled from 1.15rem */
  opacity: 0;
  transition: opacity 0.3s ease;
}
/* Photoshop badge — sits above .illustration-card-media (not inside it), so
   it stays fully visible through the hover dim rather than fading with the
   image underneath it. */
.illustration-card-badge {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  width: 28px;
  height: 28px;
  display: block;
  z-index: 1;
}
/* Same top-left spot as .illustration-card-badge above, but for a card
   that needs more than one tool icon side by side — the Breakfast lottie
   was made in both After Effects and Lottie, so it shows both rather than
   picking one. The group itself sits exactly where a single badge would;
   the icons inside just lay out in a row instead of being individually
   positioned. */
.illustration-card-badges {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  display: flex;
  gap: 0.375rem;
  z-index: 1;
}
.illustration-card-badges img {
  display: block;
  width: 28px;
  height: 28px;
}
.illustration-card-link:hover .illustration-card-media,
.illustration-card-link:focus-visible .illustration-card-media {
  opacity: 0.35;
}
.illustration-card-link:hover .illustration-card-title,
.illustration-card-link:focus-visible .illustration-card-title {
  opacity: 1;
}
/* Touch devices have no hover state at all, so cards now just render
   plainly at rest on them (no dim, no title overlay) — same look as a
   desktop card before it's hovered. A previous version forced the dimmed
   + title-visible look here permanently (since a tap-through card would
   otherwise never reveal its title before navigating away), but every
   title card's own artwork already bakes the project name into the
   image, and the permanent dim/highlight read as a stuck hover state —
   most noticeable on breakfast.html's own showcase frame, which shares
   .illustration-card-media and was rendering visibly washed out. */

/* Below this, drop the 2-up grid to a single stacked column. The
   breakpoint is set on a title card's own natural width (959px — still the
   same width the aspect-ratio above and work.css's .illustration-card-frame
   both reference, even though the card link's height grew from 259 to
   1071), not an arbitrary phone-sized number: main has 1.5rem of padding
   on each side (48px total), so a 1007px viewport is exactly the point
   where the grid's own content width reaches 959px. Above that, two cards
   fit side by side without either one being squeezed narrower than its
   natural size; below it, a lone full-width card renders at roughly that
   same natural size instead of the pair keeping shrinking together. */
@media (max-width: 1007px) {
  .illustration-grid { grid-template-columns: 1fr; }
}

/* ---- Illustration detail rows (work/animation/breakfast.html) ----
   A row of the breakfast page's individual character Lotties, sitting below
   the main showcase frame. Two per row (four characters left once toaster
   is pulled out for its own row below, so this grid always divides evenly,
   no odd-one-out to centre). .illustration-detail-media reuses
   .illustration-card-anim above for its svg sizing, but resets the
   background back to transparent since these characters don't want the
   tinted backdrop the showcase frame and index cards use.

   .illustration-detail-row--process is the one row that pairs a Lottie with
   copy instead: toaster alongside both bits of write-up (the "fun
   experiment" intro and the Figma/Overlord story), as two <p>s stacked in
   one .illustration-detail-process-copy column rather than either one
   running the full width of the page as its own paragraph. */
.illustration-detail {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
  margin-top: 3rem;
}
.illustration-detail-row {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}
.illustration-detail-media {
  flex: 1 1 0;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  overflow: hidden;
  background: transparent;
}
.illustration-detail-row--process {
  margin: 2rem 0;
}
.illustration-detail-process-copy {
  flex: 1 1 0;
  font-weight: 500;
  font-size: 17.5px;
  line-height: 1.7;
  color: var(--cream); /* matches the page title's own colour rather than
    a fixed black, so dark mode gets the title's cream instead of
    unreadable black-on-navy - light mode still reads as near-black since
    bulb.js points --cream at the ink colour there */
}
.illustration-detail-process-copy p { margin: 0 0 1rem; }
.illustration-detail-process-copy p:last-child { margin-bottom: 0; }
.illustration-detail-process-copy a { color: var(--cream); }

@media (max-width: 640px) {
  .illustration-detail-row {
    flex-direction: column;
  }
  .illustration-detail-media {
    flex: 0 0 auto; /* stacked (column) rows still had flex: 1 1 0 from
      the row layout, which collapses to 0 height here since flex-basis 0
      applies along whichever axis is now "main" (vertical) with nothing
      to grow into - width was already left to shrink-to-fit (align-items:
      center, no width of its own), so with 0 height too, aspect-ratio had
      nothing to size from and every one of these Lotties rendered at
      0x0. A zero-size element never intersects js/work-grid.js's lazy-
      load observer either, so the animation never even loaded - not just
      a visual glitch. Explicit width below fixes both. */
    width: 100%;
  }
  .illustration-detail-process-copy {
    font-size: 14px;
  }
}

/* ---- Piece lightbox (work/illustration/<collection>.html detail pages) ----
   Trial on pinnacle-valley.html (js/illustration-lightbox.js) before rolling
   out to the other collections: clicking one of that page's own images
   (.illustration-piece img, styled in site.css) opens it centred over a
   dimmed, blurred backdrop, with left/right arrows to cycle through that
   same page's images. The overlay and its controls are injected by the
   script, not present in the page's own HTML, so this CSS is inert until
   that script runs. z-index 999 clears the header/bulb/mobile-menu stack in
   site.css (highest there is 20) with plenty of room. */
html.illustration-lightbox-locked {
  overflow: hidden; /* stop the page scrolling behind the open lightbox */
}
.illustration-lightbox {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4rem 5rem;
  background: rgba(10, 12, 20, 0.88);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}
.illustration-lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s linear 0s;
}
/* The pop-in (fade + scale-up) on open lives on this wrapper, not on the
   image itself - js/illustration-lightbox.js now gives the image its own
   magnetic hover (drift/tilt/scale toward the cursor, same as the grid
   cards, via js/illustration-magnetic.js), which drives that element's
   transform continuously through its own rAF loop. Two different pieces of
   motion competing for one element's transform is exactly the janky-CSS-
   transition problem documented in illustration-magnetic.js's own comment,
   so each gets its own element instead. */
.illustration-lightbox-frame {
  display: block;
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.illustration-lightbox.is-open .illustration-lightbox-frame {
  opacity: 1;
  transform: scale(1);
}
.illustration-lightbox-image {
  display: block;
  /* An explicit width (not just a max-width cap) so every image in a
     collection's lightbox renders at the same size on screen, regardless of
     what pixel resolution that particular file happens to be exported at -
     a hero piece and a regular piece haven't always shared a resolution
     (see site.css's .illustration-piece img comment), and max-width alone
     would just let each one fall back to its own native size whenever that
     was already smaller than the cap, which is exactly how they ended up
     looking "slightly different" sizes expanded. height stays auto (so each
     image's own aspect ratio still decides how tall it renders - pieces
     with a genuinely different crop shape SHOULD come out a different
     height), with max-height as a safety net on tall/narrow viewports,
     shrinking the width to match if a tall image would otherwise overflow.
     Sized at half of that (45vw/600px cap, 42.5vh max-height) rather than
     the full 90vw/1200px - these are fairly low-resolution source images,
     and stretched that wide they were reading as noticeably soft/blurry;
     showing them smaller keeps them closer to their native pixel size. */
  width: min(45vw, 600px);
  height: auto;
  max-height: 42.5vh;
  border-radius: 24px; /* matches .illustration-piece img in site.css, so a
    card looks the same rounded whether it's sitting in the grid or open in
    this lightbox */
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  will-change: transform; /* the magnetic hover above drives this every
    frame while hovered - no CSS transition here, same reasoning as
    .illustration-piece img in site.css */
}
/* Close/prev/next share the same round dark-glass button treatment, and the
   exact same springy hover/press feel used site-wide for the bulb, top nav
   links and the CV "Save as PDF" button — just a plain scale here since
   prev/next also need a translateY(-50%) baseline to stay vertically
   centred, which their own rules below layer on top of. */
.illustration-lightbox-close,
.illustration-lightbox-prev,
.illustration-lightbox-next {
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.illustration-lightbox-close:hover { background: rgba(255, 255, 255, 0.22); transform: scale(1.08); }
.illustration-lightbox-close:active { background: rgba(255, 255, 255, 0.22); transform: scale(0.92); transition-duration: 0.1s; }
.illustration-lightbox-close {
  top: 1.5rem;
  right: 1.5rem;
  font-size: 1.75rem;
}
.illustration-lightbox-prev,
.illustration-lightbox-next {
  top: 50%;
  transform: translateY(-50%);
}
.illustration-lightbox-prev:hover,
.illustration-lightbox-next:hover {
  background: rgba(255, 255, 255, 0.22);
  transform: translateY(-50%) scale(1.08);
}
.illustration-lightbox-prev:active,
.illustration-lightbox-next:active {
  background: rgba(255, 255, 255, 0.22);
  transform: translateY(-50%) scale(0.92);
  transition-duration: 0.1s;
}
.illustration-lightbox-prev { left: 1.5rem; }
.illustration-lightbox-next { right: 1.5rem; }

@media (max-width: 640px) {
  .illustration-lightbox { padding: 2rem 1rem; }
  .illustration-lightbox-close,
  .illustration-lightbox-prev,
  .illustration-lightbox-next { width: 40px; height: 40px; font-size: 1.25rem; }
  .illustration-lightbox-close { top: 1rem; right: 1rem; }
  .illustration-lightbox-prev { left: 0.5rem; }
  .illustration-lightbox-next { right: 0.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .illustration-lightbox,
  .illustration-lightbox-image,
  .illustration-lightbox-close,
  .illustration-lightbox-prev,
  .illustration-lightbox-next {
    transition: none;
  }
}
