/*
 * Site
 *
 * The shared layer for the rebuilt pages: base styles, the nav, the
 * footer, focus states, and the motion that every page uses. Loads after
 * tokens.css. Page-specific layout lives in home.css and case-study.css.
 *
 * The older pages (About, the process pages, archived projects) still use
 * style.css + nav.css. Nothing in this file touches them.
 */

/* ---- Base ----------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: var(--nav-height);
}

body {
  margin: 0;
  font-family: var(--font-text);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.page-home {
  color: var(--white);
  background: var(--ground);
}

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

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

a {
  color: inherit;
  text-decoration: none;
}

/* Inline links in running text. */
.link {
  border-bottom: 1px solid currentColor;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.link:hover {
  color: var(--accent);
}

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

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--margin);
  top: -100px;
  z-index: 1000;
  padding: var(--sp-1) var(--sp-2);
  background: var(--ink);
  color: var(--white);
}

.skip-link:focus {
  top: var(--sp-2);
}

/* Fixed hairlines down both edges, carried over from the original site. */
body::before,
body::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(140, 140, 136, 0.4);
  pointer-events: none;
  z-index: 90;
}

body::before { left: 1.6vw; }
body::after  { right: 1.6vw; }

@media (max-width: 860px) {
  body::before { left: 3vw; }
  body::after  { right: 3vw; }
}

/* ---- Layout helpers ------------------------------------------------- */

/* Centred content column with the page margins. */
.wrap {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--margin);
}

/* 12-column grid. Children place themselves with grid-column. */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
}

/* Small secondary text: meta, captions, columns. Sentence case on
   purpose; tiny tracked capitals everywhere is a template tell (see the
   design guardrail in CLAUDE.md). */
.label {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: var(--step--1);
  line-height: var(--leading-label);
}

/* ---- Nav ------------------------------------------------------------ */

.site-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Line up with the content column, which stops growing at
     --max-width: on very wide screens the nav insets to match it. */
  padding-inline: max(var(--margin), calc((100vw - var(--max-width)) / 2 + var(--margin)));
  color: var(--white);
  background: var(--ground);
  border-bottom: 1px solid var(--rule-light);
  transition: background-color var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}

/* The bar starts clear at the top of every page and takes its ground once
   you scroll (on the homepage, once the wordmark locks in). js/site.js
   adds .is-solid. */
.site-nav:not(.is-solid) {
  background: transparent;
  border-bottom-color: transparent;
}

/* Pages that open on the light paper (About, process pages): while the bar
   is clear, its text and outline turn dark so they stay readable. */
.page-about .site-nav:not(.is-solid):not(.is-open),
.page-process .site-nav:not(.is-solid):not(.is-open) {
  color: var(--ink);
}

.page-about .site-nav:not(.is-solid):not(.is-open) .site-nav__pill,
.page-process .site-nav:not(.is-solid):not(.is-open) .site-nav__pill {
  border-color: rgba(20, 20, 20, 0.45);
}

.site-nav__logo {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-2);
  line-height: 0.86;
  letter-spacing: -0.01em;
}

/* The homepage wordmark is the logo, so the bar's own copy steps aside.
   It stays clickable under the wordmark (which lets clicks through), so
   the name always links home. */
.page-home .site-nav__logo {
  opacity: 0;
}

.site-nav__menu ul {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

.site-nav__menu a {
  font-size: var(--step-0);
  transition: color var(--dur-fast) var(--ease);
}

.site-nav__menu a:hover {
  color: var(--accent);
}

/* The current page wears the wobbly underline (Hand-drawn marks below). */

/* Contact: an outline pill. On hover the joy colour fills up from the
   bottom and the word rolls up, replaced by a fresh copy from below. */
.site-nav__pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  line-height: 1;
  padding: 0.65em 1.2em;
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 2px;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

@media (pointer: coarse) {
  .site-nav__pill {
    min-height: 44px;
  }
}

.site-nav__pill::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--pop);
  transform: translateY(101%);
  transition: transform var(--dur-base) var(--ease);
}

.site-nav__pill span {
  position: relative;
  display: block;
  transition: transform var(--dur-base) var(--ease);
}

.site-nav__pill span::after {
  content: attr(data-label);
  position: absolute;
  left: 0;
  top: 100%;
  padding-top: 0.65em;
}

.site-nav__menu .site-nav__pill:hover {
  color: var(--ink);
  border-color: var(--pop);
}

.site-nav__menu .site-nav__pill:hover::before {
  transform: none;
}

@media (prefers-reduced-motion: no-preference) {
  .site-nav__menu .site-nav__pill:hover span {
    transform: translateY(calc(-100% - 0.65em));
  }
}

.site-nav__burger {
  display: none;
  position: relative;
  /* 44px tap target; the negative margin keeps the lines where they were. */
  width: 44px;
  height: 44px;
  margin: -4px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.site-nav__burger span:not(.sr-only) {
  position: absolute;
  left: 8px;
  right: 8px;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-base) var(--ease), top var(--dur-base) var(--ease);
}

.site-nav__burger span:nth-child(1) { top: 17px; }
.site-nav__burger span:nth-child(2) { top: 26px; }

.site-nav.is-open .site-nav__burger span:nth-child(1) { top: 21px; transform: rotate(45deg); }
.site-nav.is-open .site-nav__burger span:nth-child(2) { top: 21px; transform: rotate(-45deg); }

@media (max-width: 860px) {

  .site-nav__burger {
    display: block;
    z-index: 2;
  }

  .site-nav__menu {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: flex-start;
    padding: calc(var(--nav-height) + var(--sp-6)) var(--margin) var(--sp-6);
    background: var(--ground);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-base) var(--ease), visibility 0s linear var(--dur-base);
  }

  .site-nav.is-open .site-nav__menu {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--dur-base) var(--ease);
  }

  .site-nav__menu ul {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-3);
  }

  .site-nav__menu a {
    font-family: var(--font-display);
    font-weight: 200;
    font-size: var(--step-3);
    line-height: var(--leading-tight);
  }

  .site-nav__pill {
    padding: 0;
    color: inherit;
    border: 0;
    border-radius: 0;
  }

  .site-nav__pill::before,
  .site-nav__pill span::after {
    display: none;
  }

  /* Keep the logo above the open panel, including on the homepage where
     it is otherwise hidden behind the hero wordmark. */
  .site-nav.is-open .site-nav__logo {
    visibility: visible;
    position: relative;
    z-index: 2;
  }

  body.menu-open {
    overflow: hidden;
  }
}

/* ---- Footer --------------------------------------------------------- */

.site-footer {
  color: var(--white);
  background: var(--ground);
  padding-top: var(--module-gap);
  overflow: hidden;
}

/* The footer's column is a size container, so the giant wordmark below can
   be sized to exactly fill it with cqw units. */
.site-footer .wrap {
  container-type: inline-size;
}

.site-footer__top {
  row-gap: var(--sp-5);
  align-items: start;
}

.site-footer__contact {
  grid-column: 1 / span 8;
}

.site-footer__contact .label {
  color: var(--white);
  margin-bottom: var(--sp-2);
}

/* The sign-off line above the email. */
.site-footer__hello {
  margin-bottom: var(--sp-6);
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-3);
  line-height: 1.05;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.site-footer__hello em {
  font-style: italic;
}

.site-footer__email-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-4);
}


/* Big outline button, shared by About (Resume) and the footer (Email me).
   Oversized, and it fills on hover. */
.big-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.7em 1.3em;
  font-size: var(--step-2);
  line-height: 1;
  letter-spacing: -0.01em;
  border: 1px solid var(--ink);
  border-radius: 2px;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.big-button:hover {
  color: var(--paper);
  background: var(--ink);
}

/* On the charcoal: white outline, fills with the joy colour. */
.big-button--light {
  border-color: rgba(255, 255, 255, 0.7);
}

.big-button--light:hover {
  color: var(--ink);
  background: var(--pop);
  border-color: var(--pop);
}

@media (max-width: 860px) {
  .big-button {
    font-size: var(--step-1);
  }
}


/* The hand-drawn icons sit in a row on the right, top aligned with the
   sign-off line, with the location under them. */
.site-footer__links {
  grid-column: 10 / -1;
  display: flex;
  flex-wrap: wrap;
  align-content: start;
  gap: var(--sp-2);
  padding-top: 0.4em;
  font-size: var(--step-0);
  color: var(--white);
}

.site-footer__place {
  flex-basis: 100%;
}

.site-footer__links a {
  color: var(--white);
  transition: color var(--dur-fast) var(--ease);
}

.site-footer__links a:hover {
  color: var(--accent);
}

/* "Zoey Russomano" measures 6.24em wide set as separate letter spans
   (they lose the font's kerning), so 100cqw / 6.3 runs edge to edge with
   a hair to spare. */
.site-footer__wordmark {
  margin-top: var(--sp-8);
  font-family: var(--font-display);
  font-weight: 200;
  font-size: calc(100cqw / 6.3);
  line-height: 0.86;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--white);
  user-select: none;
}

/* Each letter of the wordmark is a span. They rise in one after another
   when the footer scrolls into view, and hop when hovered. */
.site-footer__wordmark .ch {
  display: inline-block;
  transition: transform var(--dur-base) var(--ease), color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .site-footer__wordmark .ch:hover {
    color: var(--pop);
    transform: translateY(-0.08em) rotate(-4deg);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .js .site-footer__wordmark .ch {
    opacity: 0;
    transform: translateY(40%);
    transition: transform 700ms var(--ease), opacity 500ms var(--ease), color var(--dur-fast) var(--ease);
    transition-delay: calc(var(--i) * 55ms);
  }

  .js .site-footer__wordmark.is-in .ch {
    opacity: 1;
    transform: none;
  }

  .js .site-footer__wordmark.is-in .ch:hover {
    transform: translateY(-0.08em) rotate(-4deg);
    transition-delay: 0ms;
  }
}

.site-footer__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding-block: var(--sp-3);
  border-top: 1px solid var(--rule-light);
  color: var(--white);
}

.site-footer__row a {
  color: var(--white);
  transition: color var(--dur-fast) var(--ease);
}

/* Back to top: an invisible 44px tall tap area, so the row keeps its look
   (::after is the wobbly underline). */
.site-footer__row a::before {
  content: "";
  position: absolute;
  inset: -14px 0;
}

.site-footer__row a:hover {
  color: var(--accent);
}

@media (max-width: 860px) {
  .site-footer__contact,
  .site-footer__links {
    grid-column: 1 / -1;
    justify-items: start;
  }

  .site-footer__links {
    padding-top: 0;
  }

  .site-footer__wordmark {
    margin-top: var(--sp-6);
  }
}

/* ---- Motion --------------------------------------------------------- */
/* Everything below is opt-in for people who have not asked for reduced
   motion. Without JS, or with reduced motion, content simply shows. */

@media (prefers-reduced-motion: no-preference) {

  /* Modules fade and rise into place as they enter the viewport.
     js/site.js adds .js to <html>, then .is-in to each [data-reveal]. */
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
    transition-delay: var(--reveal-delay, 0ms);
  }

  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  /* Page transition: a short fade out on internal navigation, fade in on
     arrival. */
  .js body {
    animation: page-in 240ms var(--ease) both;
  }

  .js body.is-leaving {
    opacity: 0;
    transition: opacity 180ms var(--ease);
  }

  @keyframes page-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}

/* ---- Touch targets -------------------------------------------------- */
/* Small links and buttons get a bigger invisible hit area on touch
   screens, without changing how they look. */
@media (pointer: coarse) {
  .site-nav__burger::after {
    content: "";
    position: absolute;
    inset: -4px;
  }

  .site-footer__row a {
    display: inline-block;
    padding-block: 14px;
    margin-block: -14px;
  }
}

/* ---- Hand-drawn marks ----------------------------------------------- */
/* A scribble in the joy colour drawn over finished type, as if by hand.
   Wrap a word in .scribble with data-draw and the SVG mark below; it
   draws itself the first time it scrolls into view (js/site.js).
   .scribble = a loop round the word; add .scribble--under for a double
   squiggle under it instead. Without JS or with reduced motion the mark
   is simply there. */
.scribble {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}

.scribble__mark {
  position: absolute;
  left: -7%;
  top: -24%;
  width: 114%;
  height: 148%;
  overflow: visible;
  fill: none;
  stroke: var(--pop);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.scribble--under .scribble__mark {
  top: auto;
  bottom: -0.32em;
  left: -3%;
  width: 106%;
  height: 0.45em;
}

.js .scribble__mark path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1100ms cubic-bezier(0.6, 0.05, 0.3, 1) 200ms;
}

.js .scribble.is-drawn .scribble__mark path {
  stroke-dashoffset: 0;
}

@media (prefers-reduced-motion: reduce) {
  .js .scribble__mark path {
    transition: none;
  }
}

/* Wobbly underline that draws in from the left on hover, on text links:
   the nav and the footer's last row. The current
   page in the nav keeps it on. */
.site-nav__menu a:not(.site-nav__pill),
.site-footer__row a {
  position: relative;
}

.site-nav__menu a:not(.site-nav__pill)::after,
.site-footer__row a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.32em;
  height: 0.38em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8'%3E%3Cpath d='M0 5c4-4 8-4 11-1s6 4 10 1 7-4 10-1 6 3 9 0' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x 0 50% / 2.2em 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 8'%3E%3Cpath d='M0 5c4-4 8-4 11-1s6 4 10 1 7-4 10-1 6 3 9 0' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x 0 50% / 2.2em 100%;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 420ms var(--ease);
  pointer-events: none;
}

.site-nav__menu a:not(.site-nav__pill):hover::after,
.site-nav__menu a[aria-current="page"]::after,
.site-footer__row a:hover::after {
  clip-path: inset(0 0 0 0);
}

/* ---- Hand-drawn icons ----------------------------------------------- */
/* Wobbly, hand-drawn line icons, stroked in the current colour. Each one
   does its own small thing when you touch it: the Instagram camera tips
   back, its swirl lens spins and the flash blinks in the joy colour; the
   LinkedIn "i" pops its dot. Redraw them any time: they are plain SVG
   paths in the footer markup. */
.site-footer__social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
}

.hand-icon {
  width: 3.25em;
  height: 3.25em;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: color var(--dur-fast) var(--ease), transform var(--dur-base) var(--ease);
}

.hand-icon path {
  transform-box: fill-box;
  transform-origin: center;
}

.site-footer__social:hover .hand-icon,
.site-footer__social:focus-visible .hand-icon {
  color: var(--pop);
}

.hand-icon__flash {
  transition: fill var(--dur-fast) var(--ease);
}

.site-footer__social:hover .hand-icon__flash {
  fill: currentColor;
}

@media (prefers-reduced-motion: no-preference) {
  .site-footer__social:hover .hand-icon {
    animation: hand-wiggle 520ms ease-in-out;
  }

  .site-footer__social:hover .hand-icon__lens {
    animation: lens-spin 900ms cubic-bezier(0.3, 1.4, 0.5, 1);
  }

  .site-footer__social:hover .hand-icon__dot {
    animation: dot-pop 600ms cubic-bezier(0.3, 1.6, 0.5, 1);
  }
}

@keyframes hand-wiggle {
  25% { rotate: -10deg; scale: 1.08; }
  60% { rotate: 6deg; }
  100% { rotate: 0deg; scale: 1; }
}

@keyframes lens-spin {
  to { rotate: 360deg; }
}

@keyframes dot-pop {
  40% { translate: 0 -5px; scale: 1.6; }
  100% { translate: 0 0; scale: 1; }
}
