/* one typeface, one weight, black on white. that's the system.
   (plus one handwritten accent: nayliSans1, traced from a napkin.) */

@font-face {
  font-family: "nayliSans1";
  src: url("fonts/nayliSans1.woff2") format("woff2"),
       url("fonts/nayliSans1.woff") format("woff");
  font-display: swap;
}

:root {
  /* Geist Mono everywhere (monospace), with system monos as fallback;
     also the fallback for nayliSans1 */
  --font: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* one ink for everything on the site — #303030, nothing else */
  --ink: #303030;
  --paper: #f7f5f0; /* off-white */
  --muted: #303030;
  --nav-w: 280px;
  /* subtle hand-drawn squiggle used for every underline (a few gentle waves per line) */
  --squiggle: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='18'%20height='5'%3E%3Cpath%20d='M0%202.5%20Q4.5%200.6%209%202.5%20T18%202.5'%20fill='none'%20stroke='%23303030'%20stroke-width='1'/%3E%3C/svg%3E");
}

/* ---------- scroll cursor ----------
   native scrollbar is hidden and replaced with one small black mark whose
   position tracks how far you've scrolled (set from JS). it travels down as
   you scroll down and back up as you scroll up — no perpetual animation.
   scrolling itself still works as normal (wheel / trackpad / keys). */
::-webkit-scrollbar {
  display: none;
}

* {
  scrollbar-width: none;
}

.scroll-cursor {
  position: absolute;
  top: 0;
  right: 8px; /* breathing room from the nav's divider line */
  width: 15px;
  height: 22px;
  background: url("cursor.svg") center / contain no-repeat;
  image-rendering: pixelated;
  pointer-events: none;
  transform-origin: center;
  /* glide to the new spot; flip smoothly when scroll direction changes */
  transition: top 0.12s ease-out, transform 0.2s ease;
}

/* scrolling down → cursor points down (U-turn flip); up → points up */
.scroll-cursor.down {
  transform: scaleY(-1);
}

.scroll-cursor-page {
  position: fixed;
  top: 0;
  right: 4px;
  height: 100vh;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

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

body {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  font-kerning: none;
}

a {
  color: var(--ink);
  text-underline-offset: 3px;
}

a:hover {
  text-decoration: none;
}

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

.frame {
  display: grid;
  /* minmax(0,…) lets the content column shrink below its min-content
     width — the about collage has a fixed-width stage that would
     otherwise force the page wider than the viewport */
  grid-template-columns: var(--nav-w) minmax(0, 1fr);
  min-height: 100dvh;
}

/* ---------- left nav ---------- */

.nav {
  padding: 3.75rem 1.5rem 2rem;
  font-size: 14px; /* same size as content */
  /* right hairline marks this off as the left nav */
  border-right: 1px solid var(--ink);
  /* the left panel is its own thing: sticky, full height. the wordmark
     stays put; .nav-scroll below is the part that actually scrolls, so
     the scroll-cursor (a direct child of .nav) can stay independent of it. */
  position: sticky;
  top: 0;
  align-self: start;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

.nav-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.wordmark {
  font-family: "nayliSans1", var(--font);
  font-size: inherit;
  font-weight: 300;
}

.wordmark a {
  text-decoration: none;
  display: inline-block;
}

/* the wordmark is plain — it opts out of the squiggle every other nav
   link gets */
.wordmark a::after {
  content: none;
}

.nav-body {
  margin-top: 5rem;
}

.nav .home {
  display: inline-block;
  text-decoration: none;
  margin-bottom: 1.75rem;
}

/* category filters: plain lowercase tabs, same squiggle-underline language
   as every other interactive text on the site (see .nav a below) — no
   border/chip shape, so they stay on one line instead of wrapping. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 2rem;
}

.filters span {
  position: relative;
  cursor: pointer;
  padding-bottom: 4px;
}

.filters span::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0%;
  height: 5px;
  background-image: var(--squiggle);
  background-repeat: repeat-x;
  background-size: 18px 5px;
  transition: width 0.4s ease;
}

.filters span:hover::after {
  width: 100%;
}

.filters span.active::after {
  width: 100%;
  transition: width 0.5s ease;
}

.filters span:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 3px;
}

.nav .empty {
  color: var(--muted);
}

.nav ul {
  list-style: none;
}

/* one continuous flowing list: title, year on one row. big serif titles
   need real room around them, hence the generous row margin. */
.nav li {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 0.6rem;
  margin: 0 0 0.95rem;
}

.nav a {
  text-decoration: none;
}

/* entry titles: sized to their own text so the year sits right next to
   the title. only shrinks (cutting short with …) once title + year can't
   both fit. */
.nav li a,
.nav li .marker {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  text-transform: lowercase;
}

/* years sit next to the title, same size as everything else */
.nav .item-year {
  flex-shrink: 0;
  font-size: 1em;
  color: var(--muted);
  white-space: nowrap;
}

/* locked entries: title reads muted since it isn't clickable, plus a
   small "locked" badge — a plain grey pill, no border, quiet by design */
.nav .marker.locked {
  color: var(--muted);
}

/* locked marker: a little scribbly padlock icon (see icons.js) */
.nav .locked-badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  align-self: center;
  color: var(--muted);
}

.nav .locked-badge svg {
  width: 15px;
  height: 15px;
}

/* content links: the squiggle is always fully drawn, static. */
.content a {
  text-decoration: none;
  background-image: var(--squiggle);
  background-repeat: repeat-x;
  background-position: left 100%;
  background-size: 18px 5px;
  padding-bottom: 4px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* nav links: the squiggle sweeps in left → right on hover, and locks in
   fully drawn (no animation) once the item is the selected page. */
.nav a {
  position: relative;
  padding-bottom: 4px;
}

.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0%;
  height: 5px;
  background-image: var(--squiggle);
  background-repeat: repeat-x;
  background-size: 18px 5px;
  transition: width 0.4s ease;
}

.nav a:hover::after {
  width: 100%;
}

.nav a.active::after {
  width: 100%;
  transition: width 0.5s ease;
}

.nav .foot {
  margin-top: 0.9rem;
  display: flex;
  align-items: center;
  gap: 1.1rem;
}

.nav .foot a {
  display: inline-flex;
  color: var(--ink);
  opacity: 0.7;
}

.nav .foot a:hover {
  opacity: 1;
}

/* ---------- right content ---------- */

.content {
  /* align the content's top with the "about" line in the left nav;
     equal side padding + auto margins keep the column centred */
  padding: 12.63rem 4.95rem 4rem;
  width: min(46rem, 100%);
  margin-inline: auto;
  position: relative;
  /* shrink below min-content when the window is narrow — the about
     collage's fixed-width stage would otherwise widen the page */
  min-width: 0;
}

.content h1 {
  font-size: inherit;
  font-weight: 300;
  margin-bottom: 2rem;
}

.content p {
  margin-bottom: 1.2rem;
}

.content p:last-child {
  margin-bottom: 0;
}

.content img,
.content video,
.content iframe {
  max-width: 100%;
  display: block;
  margin: 1.5rem 0;
}

/* portrait video embed (tella etc.): aspect-ratio keeps it 9:16 regardless
   of container width, so the iframe scales responsively */
.content .video-embed {
  width: 100%;
  max-width: 480px;
  aspect-ratio: 9 / 16;
  margin: 1.5rem auto;
}

.content .video-embed iframe {
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
}

/* photo set: a light 2-column grid, natural aspect ratios kept (no crop) */
.content .gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 1.5rem 0;
}

.content .gallery img {
  margin: 0;
  width: 100%;
  height: auto;
}

/* instagram embed: instagram renders it at a fixed 326x532px, so this
   scales the whole thing up 70% and centers it — the wrapper is sized to
   the scaled dimensions and flex-centers the unscaled embed inside it,
   so the visual growth from transform:scale() lands centered, not clipped. */
.content .ig-embed-wrap {
  width: 554px;
  height: 904px;
  max-width: 100%;
  margin: 1.5rem auto;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.content .ig-embed-wrap .instagram-media {
  transform: scale(1.7);
}

/* ---------- about collage ----------
   the about page is a little scrapbook: a greeting, three cards and a
   photo, each absolutely positioned to match the paper design and
   draggable (see the pointer handlers in index.html). coordinates are
   lifted 1:1 from the paper file — desktop artboard values here, mobile
   values in the media query below. */

.collage {
  position: relative;
  width: 578px;
  height: 823px;
  /* the design's stage sits 193px from the top; .content pads 202px */
  margin-top: -9px;
  transform-origin: top center;
}

.collage .piece {
  position: absolute;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.collage .piece.dragging {
  cursor: grabbing;
}

.collage .hello {
  left: 0;
  top: 58px;
  /* hitbox hugs the text — no invisible full-width strip to grab */
  width: max-content;
  font-family: "nayliSans1", var(--font);
  font-size: 27px;
  line-height: 21.7px;
  z-index: 2;
}

.collage .photo {
  left: 216px;
  top: 0;
  width: 323px;
  height: 377px;
  z-index: 1;
}

.collage .photo video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  margin: 0; /* .content video normally gets vertical margins */
  pointer-events: none; /* drags land on the piece, not the video */
}

/* cards center their text block; the extra bottom margin on the <p>
   nudges it slightly high, exactly like the paper layout */
.collage .card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 10px 10px 10px 20px;
}

.collage .card p {
  align-self: stretch;
  margin: 0 0 19px;
}

.collage .card-intro {
  left: -27px;
  top: 208px;
  width: 269px;
  height: 199px;
  background: #ffffff;
  outline: 1px solid #000000;
  z-index: 3;
}

.collage .card-side {
  left: 447px;
  top: 232px;
  width: 261px;
  height: 228px;
  background: #ffb9cd;
  z-index: 4;
}

.collage .card-work {
  left: 0;
  top: 478px;
  width: 580px;
  height: 82px;
  padding: 20px 10px 10px 20px;
  background: #000000;
  color: #ffffff;
  z-index: 3;
}

/* label above a list of facts (about page) or inline in a body */
.content .label {
  display: block;
  margin-bottom: 0.35rem;
}

.content .meta {
  margin-top: 2.75rem;
}

.content .meta dt {
  margin-top: 1.75rem;
}

.content .meta dt:first-child {
  margin-top: 0;
}

.content .meta dd {
  margin: 0.35rem 0 0;
}

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

.menu-toggle {
  display: none;
}

@media (max-width: 720px) {
  .frame {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }

  .nav {
    position: static;
    height: auto;
    /* side padding matches .content's mobile padding so the wordmark,
       hamburger and icons line up with the text below */
    padding: 2.5rem 2.0625rem 0;
    display: flex;
    flex-direction: column;
    border-right: none;
  }

  /* on mobile the social icons live inside the collapsible menu, at the
     bottom — hidden until the hamburger opens it */
  .nav .foot {
    display: none;
    order: 2;
    margin: 0.5rem 0 1.5rem;
  }

  .nav.open .foot {
    display: flex;
  }

  .nav-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
  }

  .menu-toggle {
    display: inline-flex;
    background: none;
    border: none;
    color: var(--ink);
    cursor: pointer;
    padding: 0;
  }

  .nav-body {
    margin-top: 2rem;
    display: none;
  }

  .nav.open .nav-body {
    display: block;
  }

  .content {
    padding: 1.5rem 2.0625rem 3rem;
  }

  /* about collage, mobile artboard values. the stage is a fixed 375px
     canvas that starts flush under the header (cancelling .content's
     padding) and centers itself on wider phones. */
  .collage {
    width: 375px;
    height: 1082px;
    /* -24px cancels .content's top padding; the extra -5px absorbs the
       wordmark's real rendered height (69px header vs the design's 64) so
       the stage starts exactly where the artboard says. */
    margin: -29px 0 0 calc((100% - 375px) / 2);
  }

  .collage .hello {
    left: 33px;
    top: 62px;
  }

  .collage .photo {
    left: 87px;
    top: 232px;
    width: 255px;
    height: 297px;
  }

  .collage .card-intro {
    left: 24px;
    top: 115px;
    width: 269px;
    height: 178px;
  }

  .collage .card-work {
    left: 34px;
    top: 551px;
    width: 308px;
    height: 111px;
  }

  .collage .card-side {
    left: 34px;
    top: 684px;
    width: 261px;
    height: 228px;
  }
}
