/* =====================================================================
   Ruben Stom — portfolio
   ===================================================================== */

:root {
  --font: "Crimson Pro", Georgia, "Times New Roman", serif;
  --fs: 15px;
  --lh: 1.6;

  /* light pages */
  --light-bg: #fff;
  --light-text: #555;
  --light-name: #000;
  --label: #a1a1a1;

  /* dark page */
  --dark-bg: #000;
  --dark-text: #c7c7c7;
  --dark-title: #a0a0a0;
  --dark-nav: #fff;
  --dark-rule: #454545;

  /* form */
  --field-border: #454545;
  --field-border-focus: #c7c7c7;
  --field-text: #c7c7c7;
  --field-placeholder: #9d9c9a;
  --button-bg: #dbdbdb;
  --status: #999896;

  --gutter: 20px;
  --ease: cubic-bezier(0.77, 0, 0.175, 1);
  --slide: 0.8s;
  --fade: 0.45s;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
html { overflow: hidden; }
body {
  font-family: var(--font);
  font-size: var(--fs);
  font-weight: 400;
  line-height: var(--lh);
  color: var(--light-text);
  background: var(--light-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
}
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img { display: block; }
em, i { font-style: italic; }

/* ---------- layers ---------- */
.layer {
  position: fixed;
  inset: 0;
  overflow: hidden;
  transform: translate3d(0, 0, 0);
  transition: transform var(--slide) var(--ease), visibility 0s linear 0s;
}
.layer-home { background: var(--light-bg); z-index: 1; }
.layer-info {
  background: var(--dark-bg);
  color: var(--dark-text);
  z-index: 2;
  box-shadow: 0 -2px 0 0 var(--dark-bg); /* covers the hairline seam while sliding */
  transform: translate3d(0, 100%, 0);
  visibility: hidden;
  transition: transform var(--slide) var(--ease), visibility 0s linear var(--slide);
}
html.info-open .layer-home { transform: translate3d(0, -100%, 0); }
html.info-open .layer-info {
  transform: translate3d(0, 0, 0);
  visibility: visible;
  transition: transform var(--slide) var(--ease), visibility 0s linear 0s;
}
html.no-transition .layer,
html.no-transition .projects,
html.no-transition .intro-text,
html.no-transition .project-view { transition: none !important; }

/* scrolling views: no visible scrollbar (wheel, trackpad and touch still scroll) */
.home-view, .project-view, .info-view {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.home-view::-webkit-scrollbar,
.project-view::-webkit-scrollbar,
.info-view::-webkit-scrollbar { display: none; }

/* ---------- nav ---------- */
.nav {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 0;
  z-index: 20;
}
.nav a {
  position: absolute;
  top: var(--gutter);
  line-height: 1.3;
  transition: opacity 0.3s ease;
}
.nav a:hover { opacity: 0.6; }
.nav-left { left: var(--gutter); }
.nav-right { right: var(--gutter); }
.nav-light a { color: var(--light-text); }
.nav-dark a { color: var(--dark-nav); }

/* ---------- home view ---------- */
.home-view {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
}
.hero {
  flex: 1 0 auto;
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.intro-text {
  font-size: 16px;
  line-height: 22px;
  transition: opacity var(--fade) ease;
}
.intro-text .name {
  color: var(--light-name);
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
  margin: 0;
}
/* visually hidden but available to screen readers and search engines */
.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;
}
.intro-text .tagline { font-style: italic; color: var(--light-text); }

.projects-wrap {
  flex: 0 0 auto;
  overflow: hidden; /* clips the slide so it never adds scrollable overflow */
}
.projects {
  background: var(--dark-bg);
  padding: var(--gutter);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--gutter);
  transition: transform var(--slide) var(--ease);
  will-change: transform;
}
.thumb {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: #111;
}
.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
/* dark overlay + title: hidden by default, revealed on hover. The photo is
   darkened only, never blurred, so it stays sharp under the title. */
.thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.thumb-title {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 15px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  text-indent: 0.2em; /* offsets the trailing letter-space so the word sits optically centred */
  opacity: 0;
  transition: opacity 0.4s ease;
}
@media (hover: hover) {
  .thumb:hover::after,
  .thumb:focus-visible::after,
  .thumb:hover .thumb-title,
  .thumb:focus-visible .thumb-title { opacity: 1; }
  /* subtle zoom of the photo inside its frame */
  .thumb:hover img,
  .thumb:focus-visible img { transform: scale(1.01); }
}
/* touch devices have no hover: keep the glass + title visible so projects stay labelled,
   and fade them out while a thumbnail is pressed so only the photo shows */
@media (hover: none) {
  .thumb::after,
  .thumb-title { opacity: 1; }
  .thumb:active::after,
  .thumb:active .thumb-title { opacity: 0; }
  .thumb { -webkit-tap-highlight-color: transparent; }
}

/* ---------- project view ---------- */
.project-view {
  position: absolute;
  inset: 0;
  cursor: default;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  display: flex;
  padding: 60px var(--gutter) 32px;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
.project-box {
  margin: auto;
  width: 352px; /* overwritten by JS */
}
.project-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  color: var(--label);
  margin-bottom: 10px;
  line-height: 1.3;
}
.project-close { color: var(--label); transition: opacity 0.3s ease; }
.project-close:hover { opacity: 0.6; }
.project-media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: #eee;
}
.project-media img { width: 100%; height: 100%; object-fit: cover; }
.project-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.project-media video.is-playing { opacity: 1; }
.project-text {
  margin-top: 18px;
  color: var(--light-text);
}

html.project-open .projects { transform: translate3d(0, 100%, 0); }
html.project-open .intro-text { opacity: 0; }
html.project-open .home-view { pointer-events: none; }
html.project-open .project-view {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.6s ease 0.25s, visibility 0s linear 0s;
}

/* ---------- info view ---------- */
.info-view {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}
.info-content {
  position: relative;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 120px var(--gutter) 32px;
}
.cols {
  display: flex;
  align-items: flex-start;
  gap: 120px;
}
.col { flex: 0 0 auto; }
.col-about { width: 324px; }
.col-elsewhere { width: 250px; }

.label {
  font-size: var(--fs);
  font-weight: 400;
  color: var(--dark-title);
  margin: 0 0 6px;
}
.block p + p { margin-top: 22px; }
.divider + .block { margin-top: 46px; }
.divider {
  display: none;
  border: 0;
  border-top: 1px solid var(--dark-rule);
  margin: 0;
}

.entry {
  display: block;
  margin-top: 14px;
  transition: opacity 0.3s ease;
}
.entry:first-of-type { margin-top: 0; }
.entry:hover { opacity: 0.65; }
.entry-title { display: block; color: var(--dark-text); }
.entry-desc { display: block; font-style: italic; color: var(--dark-text); }
.arrow {
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 6px;
  vertical-align: -0.25px;
}

/* newsletter form */
.newsletter { margin-top: 16px; }
.newsletter-row { display: flex; width: 308px; max-width: 100%; }
.newsletter input {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  padding: 0 12px;
  font: inherit;
  color: var(--field-text);
  background: none;
  border: 1px solid var(--field-border);
  border-right: 0;
  border-radius: 0;
  outline: none;
  transition: border-color 0.2s ease;
  -webkit-appearance: none;
}
.newsletter input::placeholder { color: var(--field-placeholder); opacity: 1; }
.newsletter input:focus { border-color: var(--field-border-focus); }
.newsletter button {
  flex: 0 0 auto;
  height: 34px;
  padding: 0 24px;
  color: #000;
  background: var(--button-bg);
  transition: opacity 0.2s ease;
}
.newsletter button:hover { opacity: 0.82; }
.newsletter button:disabled { opacity: 0.6; cursor: default; }
.form-status {
  color: var(--status);
  margin-top: 10px;
  min-height: 1.6em;
}
.form-status:empty { display: none; }

/* info image (desktop: right-anchored, from 230px below top to 32px above bottom) */
.info-image {
  position: absolute;
  right: var(--gutter);
  top: 230px;
  bottom: 32px;
  margin: 0;
  width: min(calc((100vh - 262px) * 0.75), calc(100vw - 756px));
  overflow: hidden;
}
.info-image img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- tablet (768–1023): columns side by side, image flows below ---------- */
@media (max-width: 1023px) {
  .info-content { padding-top: 100px; }
  .cols { gap: 60px; }
  .info-image {
    margin-top: 48px;
    position: static;
    width: 100%;
    aspect-ratio: 3 / 4;
    height: auto;
  }
}

/* ---------- mobile (< 768) ---------- */
@media (max-width: 767px) {
  /* nav becomes a solid bar so scrolled content doesn't run under the links */
  .nav {
    height: 56px;
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
  }
  .nav-light { background: rgba(255, 255, 255, 0.72); }
  .nav-dark { background: rgba(0, 0, 0, 0.6); }

  .hero { min-height: 55vh; }
  .projects { grid-template-columns: minmax(0, 1fr); }

  /* narrow layout: glass + title shown by default on every input type,
     and fade out on mouse hover (or touch press) to reveal the photo */
  .thumb::after,
  .thumb-title { opacity: 1; }
  .thumb:hover::after,
  .thumb:active::after,
  .thumb:hover .thumb-title,
  .thumb:active .thumb-title { opacity: 0; }

  /* thumbnails: flat 40% black overlay, title always visible */
  .thumb::after {
    background: rgba(0, 0, 0, 0.4);
    opacity: 1;
  }
  .thumb-title { opacity: 1; }

  .project-view { padding: 60px var(--gutter) 32px; }

  .info-content { padding: 40vh var(--gutter) var(--gutter); }
  .cols { flex-direction: column; align-items: stretch; gap: 0; }
  .col { width: auto; }
  .divider { display: block; margin: 40px 0; }
  .divider + .block { margin-top: 0; }
  .info-image {
    position: static;
    width: 100%;
    aspect-ratio: 3 / 4;
    height: auto;
    margin-top: 28px;
  }
}

/* ---------- loading animation (first visit per session) ---------- */
@keyframes introFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes introSlideUp { from { transform: translate3d(0, 100%, 0); } to { transform: translate3d(0, 0, 0); } }
@keyframes introThumb {
  from { opacity: 0; transform: translate3d(0, 20px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
html.intro .intro-text { animation: introFade 0.9s ease 0.15s both; }
html.intro .nav-light a { animation: introFade 0.7s ease 1.0s both; }
html.intro .projects { animation: introSlideUp 0.9s var(--ease) 1.1s both; }
html.intro .thumb { animation: introThumb 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; }
html.intro .thumb:nth-child(1) { animation-delay: 1.75s; }
html.intro .thumb:nth-child(2) { animation-delay: 1.87s; }
html.intro .thumb:nth-child(3) { animation-delay: 1.99s; }
html.intro .thumb:nth-child(4) { animation-delay: 2.11s; }
html.intro .thumb:nth-child(5) { animation-delay: 2.23s; }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  :root { --slide: 0.01s; --fade: 0.01s; }
  html.intro .intro-text,
  html.intro .nav-light a,
  html.intro .projects,
  html.intro .thumb { animation-duration: 0.01s; animation-delay: 0s; }
  .thumb::after, .thumb-title, .thumb img, .entry, .nav a { transition: none; }
  .thumb:hover img, .thumb:focus-visible img { transform: none; }
}
