/* ---------- Fonts ----------
   Trial webfonts used for this non-commercial portfolio, per foundry trial terms:
     - GT Alpina Trial Condensed Regular/Medium Italic (Grilli Type) — headings/labels
     - PP Neue Montreal Regular/Medium (Pangram Pangram) — body/card titles */

@font-face {
  font-family: 'GT Alpina Trial';
  src: url('../assets/fonts/GT-Alpina-Condensed-Regular-Italic-Trial.otf') format('opentype');
  font-style: italic;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'GT Alpina Trial';
  src: url('../assets/fonts/GT-Alpina-Condensed-Medium-Italic-Trial.otf') format('opentype');
  font-style: italic;
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'PP Neue Montreal';
  src: url('../assets/fonts/NeueMontreal-Regular.woff2') format('woff2');
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'PP Neue Montreal';
  src: url('../assets/fonts/NeueMontreal-Medium.woff2') format('woff2');
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

/* Same-document view-transition timing, used by the hero-nav tab router in
   js/script.js (document.startViewTransition). Hard navigations to every
   other page instead get an explicit JS fade-out (also in js/script.js) —
   cross-document `@view-transition: auto` was removed because attempting a
   native transition on top of that delayed navigation just raced it and
   aborted, with no visible effect beyond a console warning. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.45s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

:root {
  --bg: #212121;
  --bg-deep: #0f0f0f;
  --fg: #ffffff;
  --fg-dim: rgba(255, 255, 255, 0.5);
  --gap: 20px;
  --container: 1240px;
  --font-display: 'GT Alpina Trial', 'Fraunces', Georgia, serif;
  --font-body: 'PP Neue Montreal', 'General Sans', Inter, Arial, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* ---------- Custom cursors ----------
     Hotspot (the 2nd/3rd number pair) is where the pointer's "active point"
     sits within the 24x24 icon: near the tip for the default/pointer arrows,
     dead-center for the direction badges since those aren't precision
     pointers. Each has a native fallback in case the SVG fails to load. */
  --cursor-default: url('../assets/cursors/cursor-default.svg') 4 2, auto;
  --cursor-pointer: url('../assets/cursors/cursor-pointer.svg') 10 2, pointer;
  --cursor-arrow-left: url('../assets/cursors/cursor-arrow-left.svg') 12 12, w-resize;
  --cursor-arrow-right: url('../assets/cursors/cursor-arrow-right.svg') 12 12, e-resize;
  --cursor-drag: url('../assets/cursors/cursor-drag.svg') 10 10, ew-resize;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  cursor: var(--cursor-default);
}

img { display: block; max-width: 100%; }

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

a, button {
  cursor: var(--cursor-pointer);
}

/* ---------- Preloader ----------
   Only ever created (see js/script.js) when a page's images are still
   loading past a short grace period, so it starts hidden and fades in —
   fast loads that never create it skip this entirely. */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  background: var(--bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease);
}
.preloader--visible {
  opacity: 1;
  pointer-events: auto;
}
.preloader__logo {
  width: 96px;
  height: 96px;
  animation: preloader-pulse 1.4s ease-in-out infinite;
}
.preloader__percent {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  color: var(--fg-dim);
  min-width: 3ch;
  text-align: center;
}
@keyframes preloader-pulse {
  0%, 100% { opacity: 0.45; transform: scale(0.92); }
  50% { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .preloader__logo { animation: none; }
}

/* ---------- Reveal-on-scroll ----------
   Resting state only — GSAP (ScrollTrigger) animates these in; see js/script.js.
   Kept as plain CSS so content isn't briefly visible before JS runs. */
.reveal {
  opacity: 0;
}

/* ---------- Hero ---------- */
.hero {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 40px;
  padding: 40px 20px 32px;
  text-align: center;
  /* Identical hero markup on index.html and about.html — naming it lets the
     browser morph it in place across navigation instead of crossfading it
     away and back in with the rest of the page. */
  view-transition-name: site-hero;
}

.hero__logo {
  width: 220px;
}
.hero__logo img { width: 100%; height: auto; }

.hero__tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(18px, 2.4vw, 32px);
  line-height: 1.3;
  max-width: 620px;
  color: var(--fg);
}

.hero__nav {
  display: flex;
  gap: 2px;
  padding: 8px;
}

.hero__nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  opacity: 0.5;
}
.hero__nav-item.is-active {
  opacity: 1;
}
.hero__nav-item span {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  white-space: nowrap;
}

/* ---------- Sections ---------- */
.section {
  max-width: var(--container);
  margin: 0 auto;
  padding: 100px 20px 60px;
}

#work { padding-top: 56px; }

.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 40px;
}

.section__head h2 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 3vw, 32px);
  margin: 0;
}

.work-nav {
  display: none;
  gap: 32px;
}
/* Touch devices keep native swipe-scroll on the row; the arrows are a
   desktop-with-a-mouse affordance only. */
@media (hover: hover) and (pointer: fine) {
  .work-nav { display: flex; }
}
.work-nav__btn {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 40px;
  line-height: 1;
  color: var(--fg);
  background: none;
  border: none;
  padding: 0;
  transition: color 0.3s var(--ease);
}
.work-nav__btn.is-inactive {
  color: var(--fg-dim);
  cursor: var(--cursor-default);
  pointer-events: none;
}

/* ---------- Card component (Selected Work + Playground) ----------
   Shadow/lift live on .card (unclipped, so box-shadow stays rounded and
   doesn't show a seam on transform); rounding + clipping of the actual
   artwork live on the .card__clip child. Splitting these across two
   elements avoids the classic border-radius+overflow+transform bug where
   the browser's shadow and clip paths drift apart mid-transition. */
.card {
  position: relative;
  display: block;
  border-radius: 21px;
  aspect-ratio: var(--card-w) / var(--card-h);
  --shadow-o: 0;
  box-shadow: 0 24px 48px rgba(0, 0, 0, var(--shadow-o));
}

.card__clip {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  background: var(--card-bg, #111);
}

.card__visual {
  position: absolute;
  inset: 0;
}

.card__layer {
  position: absolute;
  left: var(--l, 0);
  top: var(--t, 0);
  width: var(--w, 100%);
  height: var(--h, 100%);
  object-fit: cover;
}
.card__layer--centered {
  left: 50%;
  top: 50%;
  width: auto;
  height: 100%;
  transform: translate(-50%, -50%);
}
.card__mask {
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-position: 0 0;
  mask-position: 0 0;
}

.card__fade {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(15, 15, 15, 0) 45%, rgba(15, 15, 15, 0.92) 100%);
  opacity: 0;
}

.card__text {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 16px;
  opacity: 0;
  transform: translateY(10px);
}

/* Selected Work: caption + fade are always shown, not hover-only */
.work-grid .card__fade,
.work-grid .card__text {
  opacity: 1;
  transform: translateY(0);
}

.card__title {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.25;
  margin: 0 0 10px;
}
.card__title-dim { color: var(--fg-dim); font-weight: 400; }

.card__client {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 18px;
  color: var(--fg-dim);
  margin: 0;
}

/* ---------- Selected Work: single horizontal row ----------
   Scrolls natively (trackpad/touch drag) and via the two header arrows.
   The scrollport bleeds to both viewport edges, while its left padding puts
   the first card back on the section's content line in the initial state.
   Once scrolled, cards can therefore travel all the way to the viewport edge
   instead of being clipped at the section boundary. */
.work-grid {
  --work-grid-gutter: calc((100vw - 100%) / 2);
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  gap: var(--gap);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin-right: calc(-1 * var(--work-grid-gutter));
  /* overflow-x:auto forces overflow-y to act as auto too (per spec, an axis
     can't stay "visible" while the other isn't), which would otherwise clip
     the hover box-shadow at the row's top/bottom edges. The left gutter also
     gives the first card's shadow room in the initial state. */
  padding: 24px 0 90px var(--work-grid-gutter);
  margin-top: -24px;
  margin-bottom: -90px;
  margin-left: calc(-1 * var(--work-grid-gutter));
}
.work-grid img { -webkit-user-drag: none; user-drag: none; }
.work-grid::-webkit-scrollbar { display: none; }
.work-grid .card {
  flex: 0 0 auto;
  width: calc(var(--card-w) * 1px);
}

@media (max-width: 560px) {
  .work-grid .card { width: calc(var(--card-w) * 0.72px); }
}

/* Extra scrollable room past the "View all" card, sized in JS only when
   the right arrow's target would otherwise exceed the row's natural
   scroll range (happens on wide screens, where bleed already shows past
   the arrow's own position) — keeps the right-arrow click always able to
   reach its target instead of clamping short partway through a card. */
.work-grid__spacer {
  flex: 0 0 auto;
  width: 0;
}

.card--viewall {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  background: #2c2c2c;
}
.card--viewall__circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: #3a3a3a;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 40px;
  color: var(--fg);
}
.card--viewall__label {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 32px;
  color: var(--fg);
  white-space: nowrap;
}

/* ---------- Playground (masonry via columns) ---------- */
.playground-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
  align-items: start;
}

.playground-col {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

@media (max-width: 900px) {
  .playground-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .playground-grid { grid-template-columns: 1fr; }
}

/* ---------- Footer links ---------- */
.links {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: var(--bg);
}
.links a,
.links button {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  border: none;
  border-bottom: 1px dashed var(--fg);
  padding: 0 0 2px;
  background: none;
  color: inherit;
  cursor: var(--cursor-pointer);
}

/* CV: a footer link with an RU/EN choice instead of a single href. The menu
   opens upward (it sits in the footer, at the bottom of the page) as a
   filled chip matching the site's other popover-style surfaces. */
.cv-picker {
  position: relative;
  display: inline-flex;
}
.cv-picker__menu {
  position: absolute;
  bottom: calc(100% + 14px);
  left: 50%;
  display: flex;
  gap: 4px;
  padding: 6px;
  border-radius: 14px;
  background: #2c2c2c;
  opacity: 0;
  transform: translate(-50%, 6px);
  pointer-events: none;
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}
.cv-picker.is-open .cv-picker__menu {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.cv-picker__option {
  font-family: var(--font-body) !important;
  font-style: normal !important;
  font-weight: 500;
  font-size: 14px;
  border-bottom: none !important;
  padding: 8px 16px !important;
  border-radius: 10px;
  color: var(--fg);
  white-space: nowrap;
  transition: background 0.2s var(--ease);
}
.cv-picker__option:hover {
  background: rgba(255, 255, 255, 0.12);
}

@media (max-width: 480px) {
  .hero { gap: 28px; }
  .hero__nav {
    flex-wrap: nowrap;
    justify-content: center;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .hero__nav::-webkit-scrollbar { display: none; }
  .hero__nav-item { padding: 8px 14px; flex-shrink: 0; }
  .hero__nav-item span { font-size: 14px; }
}

/* ================= Case study pages ================= */

/* Fixed so the back button stays reachable while scrolling a case study.
   .case-nav itself spans the full viewport width (left/right: 0) with the
   same max-width/margin auto/padding as the non-fixed layout used, so its
   horizontal alignment with the rest of the page's content is unaffected —
   only .case-back paints, so pointer-events are re-enabled on it alone. */
.case-nav {
  position: fixed;
  top: 24px;
  left: 0;
  right: 0;
  z-index: 50;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 20px;
  pointer-events: none;
}
.case-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 20px;
  border-radius: 20px;
  background: #2c2c2c;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  color: var(--fg);
  pointer-events: auto;
  transition: background 0.3s var(--ease);
}
.case-back:hover {
  background: #3a3a3a;
}
.case-back img { width: 15px; height: 15px; filter: invert(1); }

.case {
  max-width: var(--container);
  margin: 0 auto;
  padding: 100px 20px 100px;
  display: flex;
  flex-direction: column;
  gap: 90px;
}

.case-hero img,
.case-feature-row img,
.case-feature-grid img,
.case-compare img {
  width: 100%;
  display: block;
  border-radius: 20px;
}

/* Text blocks sit in the right half of the content column, matching the source layout */
.case-text {
  margin-left: auto;
  width: 622px;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 40px;
}
.case-text__group h3,
.case-text__label {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 16px;
  color: var(--fg-dim);
  margin: 0 0 14px;
}
.case-text__group p {
  font-size: 20px;
  line-height: 1.45;
  margin: 0;
}

/* The intro block (tags/description/badges) uses a tighter 16px gap in
   Figma than the other text blocks' 40px group spacing. */
.case-text--intro {
  gap: 16px;
}

.case-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 14px;
  color: var(--fg-dim);
}
.case-tags span:not(:last-child)::after {
  content: '•';
  margin-left: 8px;
}
.case-desc {
  font-size: 22px;
  line-height: 1.4;
  margin: 0;
}
.case-badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px 12px 12px;
  border-radius: 20px;
  background: #2c2c2c;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  color: #fff;
}
.case-badge img { width: 12px; height: auto; }

.case-feature-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
}
.case-feature-grid {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.case-compare {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  aspect-ratio: 1240 / 666;
  cursor: var(--cursor-drag);
  user-select: none;
  /* Matches the block's own radial gradient fill in Figma — the before/
     after shots don't quite reach the container edges, so this shows in
     the margins instead of a jarring black bar. */
  background: radial-gradient(circle at 50% 50%, #ffffff 0%, #fff7cb 25%, #ffee96 50%, #ffe662 75%, #ffe147 87.5%, #ffdd2d 100%);
}
/* Both shots are full-bleed and identically sized/positioned (the whole
   container) — that's what lets the drag reveal more/less of either side
   with no gap. Sizing each to only its own small Figma "window" meant the
   reveal ran out of image past that window's edge. */
.case-compare img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  border-radius: 0;
  pointer-events: none;
  /* The full mockup at "contain" size reads small against this wide
     letterboxed block — scale it up so it reads closer to Figma's size,
     letting the container's overflow:hidden crop the excess. */
  transform: scale(1.4);
}
/* The reveal clip must be a percentage of the whole container, not of the
   "after" image's own (already-offset, already-narrower) box — clipping
   the image directly clipped it relative to itself, which is why the
   drag looked broken. Wrap it in a full-size layer and clip that instead. */
.case-compare__after-clip {
  position: absolute;
  inset: 0;
  clip-path: inset(0 0 0 50%);
}
.case-compare__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 6px;
  background: #ffdd2d;
  border-radius: 8px;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 2;
}
.case-compare__grip {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 48px;
  height: 108px;
  border-radius: 11px;
  background: #ffdd2d;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  pointer-events: none;
  z-index: 3;
}
.case-compare__grip span {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  color: #9a8104;
}
.case-compare__label {
  position: absolute;
  top: 3%;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  color: #212121;
  z-index: 2;
}
.case-compare__label--before { left: 1.6%; }
.case-compare__label--after { right: 1.6%; }

.case-animation {
  aspect-ratio: 1240 / 860;
  border-radius: 20px;
  background: #161616;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.case-animation span {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 28px;
  color: var(--fg-dim);
}
.case-animation video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.case-results ul {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.case-results li {
  font-size: 20px;
  padding-left: 22px;
  position: relative;
}
.case-hypotheses,
.case-plain-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.case-hypotheses li {
  font-size: 18px;
  line-height: 1.5;
  padding-left: 22px;
  position: relative;
}
.case-hypotheses li::before {
  content: '•';
  position: absolute;
  left: 0;
  color: var(--fg-dim);
}
.case-plain-list { gap: 10px; margin-top: 6px; }
.case-plain-list li { font-size: 20px; }

.case-results li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--fg-dim);
}

@media (max-width: 900px) {
  .case-feature-row { grid-template-columns: repeat(2, 1fr); }
  .case-text { width: 100%; }
}
@media (max-width: 560px) {
  .case-feature-row { grid-template-columns: 1fr; }
  .case { gap: 60px; }
}

/* ================= About page ================= */

.about-photos {
  display: flex;
  gap: var(--gap);
  align-items: flex-start;
  margin-bottom: 96px;
}
.about-photos__left {
  display: flex;
  flex-direction: column;
  gap: 74px;
  flex: 822 1 0%;
  min-width: 0;
}
.about-photos__row {
  display: flex;
  align-items: flex-start;
  gap: var(--gap);
  width: 100%;
}
.about-photos__row .about-photo { flex: 1; }
.about-photo {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
}
.about-photo--tall {
  flex: 401 1 0%;
}
.about-photo__img {
  position: absolute;
  left: var(--l, 0);
  top: var(--t, 0);
  width: var(--w, 100%);
  height: var(--h, 100%);
  object-fit: cover;
}
.about-photo__img--plain {
  position: static;
  width: 100%;
  height: 100%;
}

.about-bio {
  width: 685px;
  max-width: 100%;
  font-family: var(--font-body);
  font-size: 24px;
  line-height: 1.2;
  margin: 0;
}

.about-strengths h3 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 3vw, 32px);
  margin: 0 0 48px;
}
.about-strengths__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: 84px;
  row-gap: 48px;
}
.about-strength {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.about-strength__badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 12px 16px;
  border-radius: 20px;
  background: #2c2c2c;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  color: #fff;
}
.about-strength p {
  font-family: var(--font-body);
  font-size: 24px;
  line-height: 1.4;
  margin: 0;
}

@media (max-width: 900px) {
  .about-photos { flex-direction: column; }
  .about-photos__left { flex: none; width: 100%; }
  .about-photo--tall { flex: none; width: 100%; }
  .about-strengths__grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .about-photos__row { flex-direction: column; }
}

/* ================= Experience page ================= */

.exp-list {
  margin-left: auto;
  width: 622px;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 80px;
}
.exp-entry {
  display: flex;
  flex-direction: column;
  gap: 48px;
}
.exp-entry__text {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.exp-entry__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  width: 100%;
}
.exp-entry__icon {
  width: 48px;
  height: 48px;
  border-radius: 6px;
  overflow: hidden;
  flex-shrink: 0;
}
.exp-entry__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.exp-entry__badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 12px 16px;
  border-radius: 20px;
  background: #2c2c2c;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  color: #fff;
  white-space: nowrap;
}
.exp-entry__title {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.exp-entry__company {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 24px;
  color: var(--fg);
  margin: 0;
}
.exp-entry__role {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  color: var(--fg);
  margin: 0;
}
.exp-entry__desc {
  font-family: var(--font-body);
  font-size: 24px;
  line-height: 1.4;
  color: var(--fg-dim);
  margin: 0;
}
.exp-entry__cards {
  display: flex;
  gap: 10px;
  width: 100%;
}
.exp-entry__cards .exp-card {
  flex: 1;
  min-width: 0;
}
.exp-entry__cards--fixed .exp-card--fixed {
  flex: none;
  width: 200px;
}
.exp-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.exp-card__img {
  width: 100%;
  height: 223px;
  border-radius: 20px;
  object-fit: cover;
  display: block;
}
.exp-card__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 16px;
  color: var(--fg);
  margin: 0;
}

@media (max-width: 700px) {
  .exp-entry__cards { flex-wrap: wrap; }
  .exp-entry__cards .exp-card { flex: 1 1 45%; }
}

/* ================= All Projects page ================= */

.project-entry {
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.project-entry__field {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.project-entry__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.project-entry__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 32px;
  color: var(--fg);
  margin: 0;
}
.project-entry__title-dim {
  color: var(--fg-dim);
}
.project-entry__badges {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-shrink: 0;
}
.project-entry__subtitle {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 20px;
  color: var(--fg);
  margin: 0;
}
.project-entry__stack {
  display: flex;
  gap: 64px;
  flex-wrap: wrap;
}
.project-entry__stack-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.project-entry__stack-label {
  font-family: Inter, Arial, sans-serif;
  font-size: 20px;
  color: var(--fg-dim);
  margin: 0;
}
.project-entry__stack-value {
  font-family: Inter, Arial, sans-serif;
  font-size: 20px;
  color: var(--fg);
  margin: 0;
}
.project-entry__title-link,
.project-entry__visual-link {
  display: block;
}
.project-entry__visual {
  aspect-ratio: 1239 / 738;
  border-radius: 20px;
  overflow: hidden;
  background: #2c2c2c;
}
.project-entry__visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media (max-width: 700px) {
  .project-entry__head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .project-entry__stack { gap: 32px; }
}
