/* ============================================================
   vilevi.ch — portfolio (v5: compact identity header, long scroll)
   Hero: name + role + badge + contacts, big photo.
   Projects grid. About surface card.
   ============================================================ */

:root {
  --bg: #fff;
  --text: #000;
  --muted: #666;
  --border: #eaeaea;
  --border-hover: #ccc;
  --surface: #f7f7f7;
  --green: #089e55;
  --green-bg: rgba(19, 213, 119, 0.1);
  --badge-bg: rgba(19, 45, 168, 0.1);   /* "Available for hire" — blue */
  --badge-text: #132da8;
  --blue: #1d6bfd;
  --link: #006fff;
  --about-bg: #132da8;              /* blue about card (both themes) */
  --about-line: rgba(255, 255, 255, 0.24);
  --list-line: #a4a7b5;             /* project-list row dividers */
  --orange: #f7601f;
  --red: #ff3534;
  --backdrop: rgba(0, 0, 0, 0.4);
  --hover-tint: rgba(0, 0, 0, 0.05);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --pad-x: 16px;
  --pad-top: 16px;
  color-scheme: light;
}

:root[data-theme="dark"] {
  --bg: #0a0a0a;
  --text: #fff;
  --muted: #999;
  --border: #262626;
  --border-hover: #444;
  --surface: #171717;
  --green: #2fd583;
  /* same hue as the #132da8 brand blue, lightened for WCAG AA on dark */
  --badge-bg: rgba(117, 139, 240, 0.16);
  --badge-text: #758bf0;
  --link: #758bf0;
  --list-line: #333;
  --backdrop: rgba(0, 0, 0, 0.6);
  --hover-tint: rgba(255, 255, 255, 0.07);
  color-scheme: dark;
}

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

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

/* visually hidden but available to screen readers / SEO */
.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;
}

body {
  font-family: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: var(--text);
  background: var(--bg);
  transition: background-color 0.3s ease, color 0.3s ease;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}

ul { list-style: none; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
  border-radius: 4px;
}

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

.page {
  max-width: 1440px;
  margin: 0 auto;
  padding: var(--pad-top) var(--pad-x) 16px;
}

.section { margin-top: 64px; }

/* ---------- Hero: identity column + photo ---------- */

.hero {
  /* full-screen, inset 16px top and bottom (sides come from .page) */
  min-height: calc(100svh - var(--pad-top) - 16px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* mobile: the side wrapper dissolves so head / photo / contacts stack
   directly (head at top, photo filling, contacts pinned to the bottom) */
.hero-side { display: contents; }
.hero-head { order: 1; }
.hero-photo { order: 2; }
.hero-contacts { order: 3; }

.hero-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.hero-id {
  display: flex;
  flex-direction: column;
  align-items: flex-start;   /* badge hugs its content instead of stretching */
  gap: 12px;
}

.hero-names {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hero-name {
  font-size: 20px;
  font-weight: 500;
  line-height: normal;
  color: var(--text);
}

.hero-role {
  font-size: 16px;
  line-height: normal;
  color: var(--muted);
}

.hero-contacts {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hero-contacts a {
  font-size: 16px;
  line-height: normal;
  color: var(--badge-text);   /* #132da8 in light, lighter blue in dark */
  transition: opacity 0.2s ease;
}

.hero-contacts a:hover { opacity: 0.65; }

/* availability badge with a live pulsing dot */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px 6px 6px;
  border-radius: 40px;
  background: var(--badge-bg);
  color: var(--badge-text);
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
}

.badge-dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin: 0 5px;   /* 6px dot centered in a 16px box, per Figma */
  border-radius: 50%;
  background: currentColor;
  animation: badge-pulse 1.6s ease-in-out infinite;
}

@keyframes badge-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.55); }
}

.hero-photo {
  position: relative;
  flex: 1;
  min-height: 40vh;
  overflow: hidden;
  border-radius: 8px;
  background: var(--surface);
}

.hero-photo img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;                   /* fallback: fills the frame, scrolls with page */
  object-fit: cover;
  object-position: 35% center;    /* nudge the subject toward the right */
}

/* pinned scroll: the image is held to the viewport by a scroll-driven
   animation (composited, so it stays smooth on mobile) while the frame
   scrolls over it and crops it vertically. --pin-distance (= max scroll)
   is set in JS so translateY tracks the scroll position 1:1. */
@keyframes hero-pin {
  from { transform: translateY(calc(-1 * var(--frame-top, 0px))); }
  to { transform: translateY(calc(var(--pin-distance, 0px) - var(--frame-top, 0px))); }
}

@supports (animation-timeline: scroll()) {
  .hero-photo img {
    height: 100vh;
    animation: hero-pin linear both;
    animation-timeline: scroll(root block);
    will-change: transform;
  }
}

/* ---------- Theme toggle ---------- */

.hero-toggles {
  display: flex;
  align-items: flex-start;
  gap: 2px;
  flex: 0 0 auto;
}

.theme-toggle {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: var(--text);
  transition: background-color 0.2s ease;
}

.theme-toggle:hover { background: var(--hover-tint); }

.theme-toggle .icon-sun { display: none; }

:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }

/* ---------- Projects: name / description / year list ---------- */

.project-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--list-line);
}

/* mobile: stacked block per row */
.project-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  padding: 16px 0;
  border-bottom: 1px solid var(--list-line);
  text-align: left;
  color: var(--text);
}

.pr-name {
  font-size: 16px;
  font-weight: 500;
  line-height: normal;
  color: var(--text);
}

.pr-desc {
  font-size: 14px;
  line-height: 20px;
  color: var(--muted);
}

.pr-year {
  font-size: 14px;
  line-height: normal;
  color: var(--muted);
}

/* "Coming Soon" rows are dimmed and non-interactive */
.project-row.is-soon,
.project-row.is-soon .pr-name { color: var(--muted); }
.project-row.is-soon .pr-year { opacity: 0.7; }

/* floating thumbnail that follows the cursor on desktop hover */
.project-thumb {
  position: fixed;
  top: 0;
  left: 0;
  width: 320px;
  height: 228px;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  opacity: 0;
  z-index: 90;
  transform: translate(-50%, -50%) scale(0.96);
  transition: opacity 0.2s ease, transform 0.25s var(--ease-out);
  will-change: transform, top, left;
}

.project-thumb.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* mobile: first tap "peeks" a row — a full-width blue block fades in and
   the thumbnail scales open; a second tap opens the case study */
.project-row { position: relative; isolation: isolate; }

.pr-name,
.pr-desc,
.pr-year { transition: color 0.3s ease; }

/* full-bleed blue background behind the row, fades in when peeked */
.project-row::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--pad-x));
  right: calc(-1 * var(--pad-x));
  z-index: -1;
  background: var(--about-bg);
  opacity: 0;
  transition: opacity 0.35s var(--ease-out);
}

.project-row.is-peek::before { opacity: 1; }

.project-row.is-peek .pr-name,
.project-row.is-peek .pr-desc,
.project-row.is-peek .pr-year { color: #fff; }

/* inline thumbnail — collapsed by default, expands + scales in on peek */
.pr-thumb {
  display: grid;
  grid-template-rows: 0fr;
  margin-top: 0;
  opacity: 0;
  transition:
    grid-template-rows 0.45s var(--ease-out),
    margin-top 0.45s var(--ease-out),
    opacity 0.35s var(--ease-out);
}

.pr-thumb-inner {
  overflow: hidden;
  min-height: 0;
}

.pr-thumb img {
  display: block;
  width: 100%;
  border-radius: 8px;
  transform: scale(0.92);
  transition: transform 0.6s var(--ease-out);
}

.project-row.is-peek .pr-thumb {
  grid-template-rows: 1fr;
  margin-top: 12px;
  opacity: 1;
}

.project-row.is-peek .pr-thumb img { transform: scale(1); }

/* hide only the two dividers that touch the expanded row */
.project-row.is-peek { border-bottom-color: transparent; }        /* divider below it */
.project-row:has(+ .is-peek) { border-bottom-color: transparent; } /* divider above it */
.project-list:has(.is-peek:first-child) { border-top-color: transparent; } /* first row: list top edge */

/* ---------- Slides (detail overlay) ---------- */

.slide {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--surface);
  border-radius: 8px;
  overflow: hidden;
}

.slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* consecutive slides sit 16px apart (36px content gap - 20px) */
.slide + .slide { margin-top: -20px; }

/* ---------- About: blue card — bio + experience + skills ---------- */

.about-card {
  background: var(--about-bg);
  color: #fff;
  border-radius: 8px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  /* reveal: the blue block expands open... */
  opacity: 0;
  transform: scaleY(0.66);
  transform-origin: center;
  transition:
    opacity 0.5s var(--ease-out),
    transform 0.75s var(--ease-out);
  will-change: transform, opacity;
}

.about-card.in {
  opacity: 1;
  transform: scaleY(1);
}

/* ...then its content swoops in one by one (delays set in JS) */
.about-card .bio,
.about-card .xp-row,
.about-card .skills-list li {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.6s var(--ease-out),
    transform 0.7s var(--ease-out);
}

.about-card.in .bio,
.about-card.in .xp-row,
.about-card.in .skills-list li {
  opacity: 1;
  transform: none;
}

.about-left {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.bio {
  max-width: 674px;
  font-size: 24px;
  line-height: 1.25;
  color: #fff;
}

.xp-list {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 674px;
}

.xp-row {
  padding: 12px 0;
  border-bottom: 1px solid var(--about-line);
}

.xp-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.xp-company {
  font-size: 16px;
  line-height: 20px;
  color: #fff;
}

.xp-years {
  font-size: 12px;
  line-height: 16px;
  color: rgba(255, 255, 255, 0.7);
  white-space: nowrap;
}

.xp-role {
  font-size: 14px;
  line-height: 20px;
  color: rgba(255, 255, 255, 0.7);
}

.skills-list {
  display: flex;
  flex-direction: column;
  align-self: start;
  width: 100%;
}

.skills-list li {
  padding: 8px 0;
  border-bottom: 1px solid var(--about-line);
  font-size: 14px;
  line-height: 20px;
  color: #fff;
}

/* ---------- Job logos (detail headers) ---------- */

.job-logo {
  position: relative;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  overflow: hidden;
}

.job-logo img { width: 100%; height: 100%; object-fit: cover; }

.job-logo-opswat,
.job-logo-ubiquiti {
  display: grid;
  place-items: center;
  background: #006fff;
}

.job-logo-opswat img { width: 23px; height: 23px; }
.job-logo-ubiquiti img { width: 19px; height: 19px; }

.job-logo-inspired { background: var(--red); }

.job-logo-inspired img {
  position: absolute;
  top: 0;
  left: -240%;
  width: 340%;
  height: 100%;
  max-width: none;
  object-fit: contain;
}

/* ---------- Scroll-in animation ---------- */

[data-animate] {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.7s var(--ease-out) var(--d, 0s),
    transform 0.7s var(--ease-out) var(--d, 0s);
}

[data-animate].in {
  opacity: 1;
  transform: none;
}

/* ---------- Detail overlay ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
}

.overlay[hidden] { display: none; }

.overlay-backdrop {
  position: absolute;
  inset: 0;
  background: var(--backdrop);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.overlay-panel:focus,
.overlay-panel:focus-visible { outline: none; }

.overlay-panel {
  position: absolute;
  inset: 0;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.4s var(--ease-out),
    transform 0.4s var(--ease-out);
}

.overlay.open .overlay-backdrop { opacity: 1; }
.overlay.open .overlay-panel { opacity: 1; transform: none; }

.overlay-scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.overlay-inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 24px 16px;
}

/* back link at the top of the detail view */
.overlay-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 36px;
  font-size: 16px;
  line-height: normal;
  color: var(--muted);
  transition: color 0.2s ease;
}

.overlay-back:hover { color: var(--text); }

.overlay-back svg { flex: 0 0 auto; }

.overlay-content {
  display: flex;
  flex-direction: column;
  gap: 36px;
}

/* ---------- Detail content ---------- */

/* eyebrow (category) above the title */
.detail-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.detail-eyebrow {
  font-size: 14px;
  line-height: normal;
  color: var(--muted);
}

.detail-title {
  font-size: 28px;
  font-weight: 500;
  line-height: 1.15;
  color: var(--text);
}

/* text columns are narrower (635px) than the full-width slides */
.detail-intro,
.detail-text {
  max-width: 635px;
  font-size: 16px;
  line-height: 24px;
  color: var(--text);
}

.detail-body {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.detail-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.detail-subhead {
  font-size: 16px;
  font-weight: 500;
  line-height: normal;
  color: var(--text);
}

.detail-clients { color: var(--muted); }

/* ============================================================
   Last section (about card) — its own breakpoints:
   stacked on phones, half/half on tablets, fixed skills rail on full web
   ============================================================ */

/* tablets (incl. iPad portrait): row, equal 50/50 columns */
@media (min-width: 700px) {
  .about-card {
    flex-direction: row;
    align-items: stretch;
    gap: 20px;
    min-height: 688px;
  }

  .about-left {
    justify-content: space-between;
    gap: 40px;
    flex: 1;
    min-width: 0;
  }

  .skills-list {
    flex: 1;
    min-width: 0;
  }

  .bio { font-size: 32px; }
}

/* full web: left column grows, skills is a fixed 436px rail */
@media (min-width: 1200px) {
  .skills-list { flex: 0 0 436px; }
}

/* ============================================================
   Web (>= 900px) — phones and portrait tablets get the stacked layout
   ============================================================ */

@media (min-width: 900px) {
  .section { margin-top: 96px; }

  /* desktop: identity column (left) beside the photo (right) */
  .hero { flex-direction: row; gap: 16px; }

  .hero-side {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 0 0 460px;
    max-width: 460px;
  }

  .hero-photo { flex: 1; }

  /* projects — name and description equal, year a fixed narrower column.
     The year track must be a fixed width (not max-content): each row is its
     own grid, so a content-sized year column would be wider on "Coming Soon"
     rows than "2022" rows and knock the name/description columns out of
     alignment between rows. */
  .project-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 112px;
    gap: 20px;
    align-items: baseline;
    padding: 32px 16px;
  }

  /* inline peek thumbnail is mobile-only; desktop uses the floating one */
  .pr-thumb { display: none; }

  .pr-name,
  .pr-desc,
  .pr-year { font-size: 16px; line-height: normal; }

  .pr-desc { color: var(--text); }
  .pr-year { text-align: right; }

  .project-row.is-soon .pr-desc { color: var(--muted); }

  /* hover: blue row, white text (available projects only) */
  .project-row:not(.is-soon) { cursor: pointer; }

  .project-row:not(.is-soon):hover {
    background: var(--about-bg);
    border-bottom-color: transparent;
  }

  .project-row:not(.is-soon):hover .pr-name,
  .project-row:not(.is-soon):hover .pr-desc,
  .project-row:not(.is-soon):hover .pr-year { color: #fff; }

  .overlay-inner { padding: 40px; }

  .overlay-back { margin-bottom: 36px; }

  .detail-title { font-size: 32px; }
}

/* ============================================================
   Reduced motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  [data-animate],
  .overlay-backdrop,
  .overlay-panel,
  .slide img,
  .about-card,
  .about-card .bio,
  .about-card .xp-row,
  .about-card .skills-list li {
    transition: none !important;
  }

  [data-animate],
  .about-card,
  .about-card .bio,
  .about-card .xp-row,
  .about-card .skills-list li {
    opacity: 1;
    transform: none;
  }

  /* no pinned-scroll effect when reduced motion is preferred */
  .hero-photo img { height: 100%; animation: none; transform: none; }

  .badge-dot { animation: none; }
}

/* body scroll lock while overlay is open */
body.no-scroll { overflow: hidden; }
