/* ===================================================================
   closing.css — side projects and the footer.

   The two sections these replace were the weakest on the page: a
   text-only grid, and a "More work" heading whose entire content was
   one link to Dribbble. Both now carry their own weight.
   =================================================================== */

/* ---- side projects ---- */

.side {
  border-top: 1px solid var(--line);
  padding: clamp(4rem, 10vh, 7rem) 0;
}

.side__head {
  max-width: var(--wide-max);
  margin: 0 auto clamp(2rem, 5vw, 3.5rem);
  padding: 0 var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.side__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.4vw, 2.5rem);
  letter-spacing: -.03em;
  line-height: 1.1;
  color: var(--fg-1);
}

.side__note {
  margin: 0;
  max-width: 34ch;
  font-size: .875rem;
  line-height: 1.6;
  color: var(--fg-2);
}

.side__grid {
  max-width: var(--wide-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.side__item {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.side__item:hover {
  transform: translateY(-4px);
  box-shadow: 0 2px 4px rgba(17,17,17,.05), 0 30px 64px -22px rgba(17,17,17,.24);
}

.side__media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--bg-sunken);
}
.side__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .8s var(--ease);
}
.side__item:hover .side__media img { transform: scale(1.04); }

.side__body { padding: 1.25rem 1.35rem 1.5rem; }
.side__name {
  display: block;
  font-family: var(--font-display);
  font-size: 1.25rem;
  letter-spacing: -.02em;
  color: var(--fg-1);
  margin-bottom: .35rem;
}
.side__desc {
  display: block;
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--fg-2);
  margin-bottom: .9rem;
}
.side__tag {
  font-family: var(--font-mono);
  font-size: .625rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-3);
}

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

.foot {
  padding: clamp(4rem, 10vh, 7rem) 0 clamp(2rem, 4vh, 3rem);
}

.foot__inner {
  max-width: var(--wide-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.foot__cta {
  display: inline-block;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 7vw, 5rem);
  line-height: 1.02;
  letter-spacing: -.035em;
  color: var(--fg-1);
  text-decoration: none;
  position: relative;
}
.foot__cta::after {
  content: "";
  position: absolute;
  left: 0; bottom: .06em;
  width: 100%;
  height: 2px;
  background: var(--fg-1);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .6s var(--ease);
}
.foot__cta:hover::after { transform: scaleX(1); }

.foot__grid {
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}

.foot__col h4 {
  margin: 0 0 .9rem;
  font-family: var(--font-mono);
  font-size: .625rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-3);
  font-weight: 400;
}
.foot__col a,
.foot__col p {
  display: block;
  margin: 0 0 .5rem;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--fg-2);
  text-decoration: none;
  transition: color .25s;
  width: fit-content;
}
.foot__col a:hover { color: var(--fg); }

/* The colophon is not filler: this site argues that its typography is
   deliberate, so it names the faces and holds itself to that claim. */
.foot__colophon {
  margin-top: clamp(2rem, 5vw, 3rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 2rem;
  font-family: var(--font-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-3);
}

/* A 21-character address set at 2.2rem is wider than a 390px screen, so
   below that the CTA drops to a size that fits and the underline follows
   each line rather than spanning the block. */
@media (max-width: 560px) {
  .foot__cta {
    font-size: clamp(1.05rem, 6.4vw, 1.6rem);
    letter-spacing: -.02em;
    word-break: break-word;
  }
  .foot__cta::after { bottom: -.12em; }
  /* The three link columns stack on a phone and cost 456px of a 714px footer,
     which is most of a screen spent on links, so the columns stay gone: every
     one of the six cases is already linked from the body above.
     LinkedIn and GitHub are the exception, and only because they live nowhere
     else on the page — the panel follows both, verifying what shipped and
     cross-referencing the profile. They come back as one quiet mono line in
     the colophon's register: no heading, no rule of its own, no Dribbble. */
  .foot__grid {
    display: block;
    margin-top: clamp(1.5rem, 5vw, 2rem);
    padding-top: 0;
    border-top: none;
  }
  .foot__col { display: none; }
  .foot__col:first-child { display: flex; gap: 1.5rem; }
  .foot__col:first-child h4 { display: none; }
  .foot__col:first-child a {
    margin: 0;
    font-family: var(--font-mono);
    font-size: .625rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--fg-3);
  }
  /* Set this small on purpose, so the hit area is bought with a pseudo-element
     rather than with padding: 44px to the thumb, 15px on the page, and the
     line does not grow by a pixel. The 24px gap keeps the two from touching. */
  .foot__col:first-child a { position: relative; }
  .foot__col:first-child a::after {
    content: "";
    position: absolute;
    inset: -14px -10px;
  }
  .foot__col:first-child a[href*="dribbble"] { display: none; }
  .foot__colophon { margin-top: clamp(1.5rem, 5vw, 2rem); }
}

/* ===================================================================
   .strip — shipped solo, without a case study.

   Three products of very unequal visual strength: one pale and
   document-like, one dark with a poster in it, one an illustration. Full
   bleed crops made them compete and cut the TruequeGo headline in half.
   Each screen is inset on a shared surface instead, so they read as three
   objects of the same weight rather than three photographs.
   =================================================================== */

.strip { border-top: 1px solid var(--line); padding: clamp(4rem, 10vh, 7rem) 0; }

.strip__head {
  max-width: var(--wide-max); margin: 0 auto clamp(2rem, 5vw, 3rem);
  padding: 0 var(--gutter); display: grid; gap: .75rem;
}
.strip__head h2 {
  margin: 0; font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.6rem, 3.4vw, 2.5rem); letter-spacing: -.03em;
  line-height: 1.1; color: var(--fg-1);
}
.strip__head p { margin: 0; max-width: 52ch; font-size: .875rem; line-height: 1.6; color: var(--fg-2); }

.strip__grid {
  max-width: var(--wide-max); margin: 0 auto; padding: 0 var(--gutter);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.strip__item {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--radius-card);
  background: var(--bg-raised); overflow: hidden;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.strip__item:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); }

/* The screen sits inside the card, never bleeding to its edges. */
/* One frame, one crop, anchored to the top. Contain left each screenshot at
   its own scale because their aspect ratios differ, which is the thing that
   made the row look assembled from three unrelated pictures. */
.strip__media {
  background: var(--bg-sunken); border-bottom: 1px solid var(--line);
  padding: 1.15rem 1.15rem 0; overflow: hidden;
}
.strip__media img {
  /* The frame is wider than the widest source (TruequeGo at 1.78), so cover
     always scales by width and crops only the bottom. Anything narrower loses
     the sides, which is what was cutting the TruequeGo headline in half. */
  display: block; width: 100%; aspect-ratio: 1.9 / 1;
  object-fit: cover; object-position: top center;
  border-radius: 8px 8px 0 0; border: 1px solid var(--line); border-bottom: none;
  background: #fff; box-shadow: 0 14px 30px -14px rgba(17,17,17,.22);
}


/* Flex, not grid: the links row rides on margin-top:auto so it sits on
   the floor of every card, and a description one line longer than its
   neighbours no longer drags the row down with it. */
.strip__body { padding: 1.15rem 1.35rem 1.35rem; display: flex; flex-direction: column; gap: .45rem; flex: 1; }
.strip__kicker {
  font-family: var(--font-mono); font-size: var(--t-meta);
  letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--fg-3);
}
.strip__name { font-family: var(--font-display); font-weight: 500;
               font-size: 1.1875rem; letter-spacing: -.02em; color: var(--fg-1); }
.strip__desc { margin: 0; font-size: .875rem; line-height: 1.55; color: var(--fg-2); }

/* Two links of visibly different jobs. "Case study" is the card's own action
   and stretches over the whole card, so the click target is the card and the
   label only names it. The live link is the off-site one, and it carries the
   real domain because the domain is the evidence: it can be typed into a
   browser and checked. The two used to be equal-weight mono labels side by
   side, which read as a pair of tags rather than as two destinations. */
.strip__item { position: relative; }
.strip__links {
  margin-top: auto; padding-top: 1rem;
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}
.strip__links a {
  font-size: .8125rem; color: var(--fg-2); text-decoration: none;
  display: inline-flex; align-items: center; gap: .4rem;
  transition: color .2s;
}
.strip__case {
  color: var(--fg-1) !important; font-weight: 500;
}
.strip__case::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius-card);
}
.strip__case span { transition: transform .3s var(--ease); }
.strip__item:hover .strip__case span { transform: translateX(3px); }

/* Above the stretched overlay, or it would never be clickable. */
.strip__live {
  position: relative; z-index: 1;
  font-family: var(--font-mono); font-size: var(--t-meta);
  letter-spacing: var(--track-meta);
  border-bottom: 1px solid transparent; transition: color .2s, border-color .2s;
}
.strip__live:hover { color: var(--fg); border-bottom-color: var(--line-strong); }
.strip__item:focus-within { box-shadow: var(--shadow-card); }
.strip__links a:focus-visible { outline: 2px solid var(--fg-1); outline-offset: 3px; border-radius: 2px; }
