/* ============================================================
   Axel Schoterman — Portfolio 2026
   Single shared stylesheet for all pages.

   Indentation convention:
   Rules are indented to mirror the HTML nesting. A selector that
   targets a child element is tabbed one level in from its parent's
   rule, so the stylesheet reads top-to-bottom like the page's DOM
   tree. (Indentation is cosmetic — CSS ignores leading whitespace.)

   Layout model:
   - Header / project text / info / footer sit inside a left+right
     edge padding (--pad) so everything lines up to the same margin.
   - Project GALLERIES break out of that padding and run full-bleed
     (edge to edge of the browser).
   ============================================================ */

/* ---- 1. Design tokens (edit these to restyle the whole site) ---- */
:root {
  /* Font.
     Real Arial/Helvetica appear on Windows & Mac.
     On Android these don't exist, so the browser falls back to
     sans-serif (= Roboto). To force an Arial look on Android too,
     self-host "Arimo" (Arial-identical) later and add it to this list. */
  --font: Arial, Helvetica, sans-serif;

  --color-bg: #ffffff;
  --color-fg: #111111;
  --color-muted: #888888;     /* secondary text: years, credits, nav-current */
  --color-line: #e6e6e6;      /* hairline dividers */

  --pad: 24px;                /* left/right edge margin for text + header */
  --gallery-gap: 8px;         /* gap between images sitting in the same row (set 0 for seamless) */

  /* Spacing scale (multiples of a base unit) */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 32px;
  --space-4: 64px;
  --space-5: 120px;           /* gap between projects */

  --fs-base: 14px;
  --fs-small: 12px;

  --info-width: 820px;        /* width of the info page content area (holds both columns) */
}

/* ---- 2. Reset / base ---- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-width: none;        /* Firefox: hide the scrollbar (scrolling still works) */
  -ms-overflow-style: none;     /* old Edge / IE */
}
html::-webkit-scrollbar { display: none; }   /* Chrome, Safari, new Edge */

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--color-fg);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

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

a { color: inherit; text-decoration: none; }
a:hover { opacity: 0.5; }

/* Helper: apply the standard left/right edge padding */
.edge { padding-left: var(--pad); padding-right: var(--pad); }

/* ---- 3. Site header / nav ---- */
.site-header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  justify-content: space-between;
  align-items: flex-start;
  padding: 6px;

  padding-bottom: 24vh;
}
  /* Column 1: artist name */
  .site-title {}

  /* Column 2: information */
  .site-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
  }
    .site-nav a[aria-current="page"] { color: var(--color-fg); }

  /* Column 3: contact links, each on its own line */
  .site-contact {
    display: flex;
    flex-direction: column;
    align-items: flex-end;     /* shrink each link to its text width (right-aligned) so the hover/click area isn't the full column */
  }

    .site-contact a {
      text-align: right;
      line-height: 1.2;
    }

/* ---- 3b. Work-category sub-nav (its own bar, directly below the header) ---- */
.site-worknav {
  display: block;

  padding: 0 6px var(--space-2);   /* left padding matches the header's edge */
}

  .site-worknav a {
    color: var(--color-muted);
    display: block;
    width: fit-content;        /* each category on its own line, but only as wide as its text (not the full bar) */
  }

  .site-worknav a[aria-current="page"] {
    color: var(--color-fg);
  }
    /* Tiny flower marker in front of the active link. Shared by the work
       sub-nav (current category) and the header nav (current page), so the
       page you're on is always flagged with the same icon. */
    .site-worknav a[aria-current="page"]::before,
    .site-nav a[aria-current="page"]::before {
      content: "";
      display: inline-block;
      width: 12px;
      height: 12px;
      margin-right: 4px;
      vertical-align: middle;
      background: url("/assets/active_flower.svg") no-repeat center / contain;

      position: relative;
      top:-2px;
    }

/* ---- 4. Home: projects ---- */
main { padding-bottom: var(--space-5); }

  .project { margin-top: var(--space-5); }
  .project:first-child { margin-top: var(--space-3); }

    /* 4a. Gallery — full-bleed, equal-height justified rows.

       How the equal-height trick works:
       Each row is a flex container. Every item's flex-grow is set to its
       ASPECT RATIO (width / height) via the .ar-* classes below. Flexbox
       then hands out width in proportion to those ratios, which makes every
       image in the row come out at the SAME height — no cropping, no JS.
       Just tag each item with the class that matches the image's shape. */
    .gallery { margin: 0; }

      .gallery-row {
        display: flex;
        gap:0;
        margin: 0;
      }

      .gallery-row:last-child { margin-bottom: 0; }

        .gallery-item {
          flex: 1 1 0;        /* grow / shrink / basis — grow is overridden per ratio */
          min-width: 0;       /* lets items shrink below their content size */
          margin: 0;
          position: relative; /* anchor for the optional .credit overlay below */
        }
          .gallery-item picture { display: block; height: 100%; }   /* wrapper for AVIF/WebP <source>s must fill the item, so the img's height:100% has a box to fill */
          .gallery-item img,
          .gallery-item video {
            width: 100%;
            height: 100%;
            object-fit: cover;   /* fill the ratio box (crops only if the class ≠ the file's true ratio) */
          }

          /* Optional per-image credit, e.g. when you art-directed a project
             and want to name the artist who made a specific image/video.
             Add this as the LAST child inside the <figure class="gallery-item">:
                 <figcaption class="credit">CGI Artist — Name</figcaption>
             Subtle, always visible (so credit shows on phones too), white with
             a soft shadow so it stays legible over light or dark images. */
          .gallery-item .credit {
            position: absolute;
            left: var(--space-1);
            bottom: var(--space-1);
            margin: 0;
            font-size: var(--fs-small);
            line-height: 1.4;
            color: #fff;
            opacity: 0.6;
            mix-blend-mode: difference;
            pointer-events: none;   /* never intercepts clicks/hover on the image */
            user-select: none;
          }

        /* Aspect-ratio helper classes — pick the one matching each image's shape.
           Each sets BOTH the flex-grow (so a row's images share one height) AND
           the aspect-ratio (which reserves the space). Because the ratio lives
           here, you do NOT need width/height on the <img> — the class is the
           single source of truth. */
        .ar-16x9 { flex-grow: 1.7778; aspect-ratio: 16 / 9; }
        .ar-1x1  { flex-grow: 1;      aspect-ratio: 1 / 1; }
        .ar-9x16 { flex-grow: 0.5625; aspect-ratio: 9 / 16; }
        .ar-4x5  { flex-grow: 0.8;    aspect-ratio: 4 / 5; }

    /* 4b. Project title + credits below the gallery, side by side in two columns
           (left: title/year · right: credits). Aligned to the edge padding. */
    .project-info {
      padding: 6px;
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: var(--space-2);
      align-items: start;
      padding-bottom: 6vh;
    }

      .project-title {
        font-size: var(--fs-base);
        font-weight: 400;
        margin: 0;
      }
        .project-year { color: var(--color-muted); }

      .project-credits {
        margin: 0;
        max-width: 100ch;
        color: var(--color-fg);
        font-size: var(--fs-base);
        line-height: 1.3;
      }

/* ---- 5. Info page — four blocks filling the screen as a 2×2 grid ----
   The body is a full-height flex column (header on top, the grid fills the
   rest), so the four quadrants stretch edge-to-edge and top-to-bottom:
     About    ·  Past work for
     Studios  ·  Artistic practice
   The grid's own background shows through 1px gaps to draw hairline
   dividers between the quadrants. */
.info-page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
  /* Reclaim the home page's tall header gap so the grid can fill the screen */
  .info-page .site-header { padding-bottom:21vh; }

.info {
  flex: 1;                                      /* fill the height left below the header */
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;                  /* two equal-height rows */
  gap: 1px;                                     /* hairline dividers (grid bg shows through) */
  margin: 0;
  padding: 0;
}
  .info h1 { font-size: 16px; font-weight: 700; margin: 0 0 var(--space-3); }

  .info-section {
    margin: 0;
    padding: 6px 60px 6px 6px;            
  }
    .info-section h2 {
      font-size: 16px;
      font-weight: 400;
      margin: 0;
      text-decoration: underline;
    }
    .info-section p {
      margin: 0 0 var(--space-1);
      max-width: 90ch;
      font-size: 16px;
      line-height: 1.3;
     }
    .info-section ul { margin: 0; padding: 0; list-style: none; }
      .info-section li { margin: 0;       font-size: 16px;}
      .info-section .fade {opacity: 0.54;}

/* ---- 5b. Non-commercial page — justified thumbnail gallery ----
   A single full-bleed strip of thumbnails, edge to edge. Every row shares ONE
   height (--row-h); each image's WIDTH follows its own aspect ratio, so wide
   images get wide cells and tall images get narrow ones — all the same height.
   No cropping whitespace: images fill their cell.

   How the equal height + edge-to-edge ("justified") trick works:
   The script at the bottom of /noncommercial/index.html measures each image and
   writes its aspect ratio onto the item as a CSS variable, --ar. The CSS below
   then uses --ar for BOTH flex-basis and flex-grow, so within every row the
   widths come out proportional to the images' ratios — which makes the heights
   match and the row stretch to fill the full width.

   Click behaviour: clicking a thumbnail opens it in a full-screen lightbox
   (see section 5c). The grid itself never moves. */
.noncom-grid {
  /* ----- Size knob. Edit to dial in the look. ----- */
  --row-h: 15vw;                 /* resting height of every thumbnail row */

  display: flex;
  flex-wrap: wrap;
  gap: 6px;                         /* edge to edge, no seams */
}
  /* Trailing spacer: keeps the LAST (part-full) row from stretching its few
     images absurdly wide — they keep a natural size and left-align instead. */
  .noncom-grid::after { content: ""; flex-grow: 999999; }

  .noncom-item {
    margin: 0;
    height: var(--row-h);
    flex-grow: var(--ar, 1);              /* share of a row's spare width ∝ aspect ratio */
    flex-basis: calc(var(--ar, 1) * var(--row-h)); /* start each cell at the image's TRUE width at this row height (ratio × height), so cells aren't squeezed narrow and cropped */
    min-width: 0;
    overflow: hidden;
    cursor: nwse-resize;          /* diagonal "expand" arrows — opens the lightbox */
    background: var(--color-bg);
    display: flex;
  }
    .noncom-media { width: 100%; height: 100%; }
      .noncom-media picture { display: block; height: 100%; }  /* picture is inline by default; give the img's height:100% a box to fill (same fix as .gallery-item picture) */
      .noncom-media img,
      .noncom-media video {
        width: 100%;
        height: 100%;
        object-fit: cover;        /* fill the cell; widths are set to the true ratio so crop is negligible */
        display: block;
      }

    /* Description — hidden until the item is opened. */
    .noncom-text {
      display: none;
      margin: 0;
    }
      .noncom-text h3 {
        font-size: var(--fs-base);
        font-weight: 400;
        margin: 0 0 var(--space-1);
      }
      .noncom-text p {
        margin: 0;
        color: var(--color-muted);
        font-size: var(--fs-base);
        line-height: 1.3;
      }

      .noncom-num {display: none;}

/* ---- 5c. Lightbox — full-screen viewer for the non-commercial grid ----
   Hidden until a thumbnail is clicked; the grid stays put underneath. Fades the
   page out, centres the image with a subtle caption bottom-aligned to its right,
   and shows prev/next arrows at the screen edges. Click the image to toggle
   real-size (100%) zoom; click the faded background to close. Cursors hint each
   action. Tweak the backdrop colour on .lightbox below. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5vh 6vw;
  background: rgba(255, 255, 255, 0.94);   /* the "fade out" scrim — edit to taste */
  cursor: default;                         /* plain arrow over the faded backdrop */
  opacity: 0;
  transition: opacity 0.25s ease;
}
.lightbox[hidden] { display: none; }
.lightbox.is-visible { opacity: 1; }       /* fade in once shown */
html.lightbox-open { overflow: hidden; }   /* lock page scroll while open */

  /* Image + caption, centred together; caption bottom-aligns to the image. */
  .lightbox-stage {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
    max-width: 100%;
    max-height: 100%;
    margin: 0;
  }
    .lightbox-img {
      display: block;
      max-width: 72vw;
      max-height: 90vh;
      width: auto;
      height: auto;
      object-fit: contain;
      cursor: zoom-in;                     /* click to view at real size */
      background: var(--color-bg);
    }
    /* Video items show a player here instead of the zoomable image (no pixel
       zoom for video — it just plays larger). Same sizing as the image. */
    .lightbox-video {
      display: block;
      max-width: 72vw;
      max-height: 90vh;
      width: auto;
      height: auto;
      object-fit: contain;
      background: var(--color-bg);
    }
    .lightbox-img[hidden], .lightbox-video[hidden] { display: none; }
    /* Subtle caption to the RIGHT of the image, bottom-aligned. */
    .lightbox-caption {
      flex: none;
      width: 26ch;
      color: var(--color-muted);
      cursor: default;
    }
      .lightbox-caption h3 {
        margin: 0 0 var(--space-1);
        font-size: var(--fs-base);
        font-weight: 400;
        color: var(--color-fg);
      }
      .lightbox-caption p {
        margin: 0;
        font-size: var(--fs-small);
        line-height: 1.4;
      }

  /* Prev / next arrows pinned to the screen edges. */
  .lightbox-nav {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: none;
    font-family: var(--font);
    font-size: 40px;
    line-height: 1;
    padding: 8px 14px;
    color: var(--color-muted);
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.15s ease;
  }
  .lightbox-nav:hover { opacity: 1; }
  .lightbox-prev { left: 8px; }
  .lightbox-next { right: 8px; }

  /* Zoomed to real size: natural pixels, centred and DRAGGED to pan (the JS
     clamps the offset so the image can't be pushed out of frame). Caption and
     arrows get out of the way; padding is dropped so the image can use the
     whole screen. */
  .lightbox.is-zoomed {
    overflow: hidden;
    padding: 0;
    cursor: grab;
  }
    .lightbox.is-zoomed .lightbox-stage {
      align-items: center;        /* centre the oversized image so panning is symmetric */
      max-width: none;
      max-height: none;
    }
    .lightbox.is-zoomed .lightbox-img {
      max-width: none;
      max-height: none;
      cursor: grab;
      will-change: transform;
    }
    /* While actively dragging, show the closed-hand cursor. */
    .lightbox.is-grabbing,
    .lightbox.is-grabbing .lightbox-img { cursor: grabbing; }
    /* Release after a drag: ease the image back inside its bounds (a gentle
       spring). Only applied during the spring, so live dragging stays instant. */
    .lightbox-img.is-springing { transition: transform 0.35s cubic-bezier(0.34, 1.3, 0.7, 1); }
    .lightbox.is-zoomed .lightbox-caption,
    .lightbox.is-zoomed .lightbox-nav { display: none; }

/* ---- 6. Footer ---- */
.site-footer {
  margin-top: var(--space-4);
  padding: 6px 6px 6px 6px;
  color: var(--color-muted);
  font-size: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
}

/* ---- 7. Small screens: stack each gallery image full-width ---- */
@media (max-width: 600px) {
  :root { --space-5: 72px; }

  /* Header stacks vertically and left-aligned, sitting at the standard
     6px edge so it lines up with every other text block on the page. */
  .site-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    padding: 6px 6px 20vh;
  }
    .site-contact { align-items: flex-start; }   /* on mobile the header stacks left, so left-align the contact links too */
    .site-contact a { text-align: left; }    /* contact links left-align to match the stack */

  .gallery-row { flex-wrap: wrap; }
    .gallery-item { flex-basis: 100%; }        /* one image per line */
  .project-info { grid-template-columns: 1fr; gap: var(--space-1); }  /* stack title over credits */

  /* Info page: stack the four blocks in one column with real vertical
     breathing room, and drop the wide desktop right padding so copy
     uses the full width. */
  .info { grid-template-columns: 1fr; grid-template-rows: auto; gap: var(--space-3); padding-bottom: var(--space-4); }
    .info-section { padding: 6px; }

  /* Non-commercial grid: smaller cells so a few thumbnails still fit per row. */
  .noncom-grid { --row-h: 120px; }                /* phone: shorter rows so a few thumbnails still fit across */

  /* Lightbox on phones: stack the caption UNDER the image, smaller arrows. */
  .lightbox { padding: 4vh 4vw; }
    .lightbox-stage { flex-direction: column; align-items: flex-start; gap: var(--space-1); }
    .lightbox-img, .lightbox-video { max-width: 92vw; max-height: 70vh; }
    .lightbox-caption { width: auto; max-width: 92vw; }
    .lightbox-nav { font-size: 28px; padding: 8px; }
}
