/* Reset */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #F5F4F0;
  background-image: radial-gradient(circle at center, #F5F4F0 0%, #E8E5DC 100%);
}

/* Faint paper grain over the desk background */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: #808080;
  filter: url(#paper-grain);
  opacity: 0.03;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Very light vignette for depth — sits above everything but is
   near-invisible at the center where the card lives */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, 0.07) 100%);
  pointer-events: none;
}

/* Suspend the full-screen blend layer while the card morphs — blending
   against a moving element forces per-frame re-rasterization */
body:has(.card.is-morphing)::before {
  opacity: 0;
}

/* Card dimensions: Paul Allen override scale */
:root {
  --card-w: 680px;
  --card-h: 380px;
}

/* Full-viewport wrapper: centers the card, provides 3D perspective */
.scene {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1100px;
}

/* The card itself — 3D transforms (rotateX/rotateY) are applied here */
.card {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  transform-style: preserve-3d;
  /* Hardware acceleration for the morph animation (transform-only) */
  will-change: transform;
  /* Initial load state: hidden, slightly lowered and scaled down */
  opacity: 0;
  transform: translateY(24px) scale(0.97);
}

/* Reveal: gentle rise into the centered resting position */
.card.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Two faces of the card, stacked for later 3D flipping */
.card-front,
.card-back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  background-color: #FFFFFA;
  /* Multi-layered shadow with negative spreads: tight contact shadow,
     mid-range umbra, wide soft falloff — reads as a real object casting
     light rather than a hard-edged rectangle */
  box-shadow:
    0 50px 100px -20px rgba(0, 0, 0, 0.14),
    0 25px 50px -12px rgba(0, 0, 0, 0.10),
    0 8px 20px -6px rgba(0, 0, 0, 0.08);
}

/* Faces sit 3px off the card plane so the card has real thickness */
.card-front {
  transform: translateZ(3px);
}

.card-back {
  transform: rotateY(180deg) translateZ(3px);
}

/* Cull face children individually — without this, positioned/composited
   children (link, glare, dots) can flash through during the flip */
.card-front > *,
.card-back > * {
  backface-visibility: hidden;
}

/* Card edges: perpendicular strips between the faces, edge-on (invisible)
   when the card is flat, facing the viewer at the ~90deg flip midpoint */
.card::before,
.card::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 6px;
  background: linear-gradient(to right, #E4E0D6, #FFFEFA 45%, #D5D1C7);
  transform: rotateY(90deg);
  pointer-events: none;
}

.card::before {
  left: -3px; /* left edge, centered on the card plane */
}

.card::after {
  right: -3px; /* right edge */
}

/* Paper-grain overlay: turbulence rendered through the SVG filter,
   multiplied over the base color at very low opacity */
.card-front::before,
.card-back::before {
  content: "";
  position: absolute;
  inset: 0;
  background: #808080;
  filter: url(#paper-grain);
  opacity: 0.06;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Front-face layout: Paul Allen balance — name/title dead center,
   two-line footer anchored to the bottom edge */
.card-front {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 0 60px 40px;
}

/* Deep-engraving letterpress, applied to all card text */
.card-front,
.card-back {
  color: rgba(30, 30, 30, 0.85);
}

/* Name: Copperplate Gothic (macOS system font), uppercase, wide tracking */
.card-name {
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 34px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

/* Title: directly below the name, smaller */
.card-title {
  margin-top: 16px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 14px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

/* Footer: two balanced lines, engraved */
.card-footer {
  position: absolute;
  left: 60px;
  right: 60px;
  bottom: 36px;
  text-align: center;
}

.footer-line {
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  line-height: 1.9;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

/* Footer links: same engraving, no underline — only a hover fade */
.footer-line a {
  color: inherit;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.footer-line a:hover {
  opacity: 0.55;
}

/* Location, top-left corner — mirrors the [ CV ] corner detail */
.card-location {
  position: absolute;
  top: 26px;
  left: 30px;
  padding: 4px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

/* ============================================================
   CV / resume typography (expanded state) — LaTeX-style scale
   Base classes only; real content comes later.
   ============================================================ */
.cv {
  font-family: "Computer Modern Serif", "Latin Modern Roman", Georgia, serif;
  font-weight: 400;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: #1A1A1A;
  text-align: justify;
  hyphens: auto;
}

/* Document title: more presence, weight contrast against the meta line */
.cv-heading {
  font-size: 24px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.02em;
  margin: 0 0 2px;
  text-align: left;
}

/* Section heading: widely spaced small-caps feel, short hairline rule
   instead of a full-width divider */
.cv-section {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 22px 0 8px;
  text-align: left;
}

.cv-section::after {
  content: "";
  display: block;
  width: 34px;
  margin-top: 5px;
  border-bottom: 0.5px solid rgba(30, 30, 30, 0.55);
}

/* Entry subheading (role / degree line) */
.cv-subheading {
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.01em;
  text-align: left;
}

/* Meta line (dates, locations) — italic, right-flush friendly */
.cv-meta {
  font-size: 11px;
  font-style: italic;
  line-height: 1.5;
  text-align: left;
}

/* Body text */
.cv-body {
  margin: 4px 0;
}

/* Compact list for CV entries */
.cv-list {
  margin: 4px 0 4px 18px;
}

.cv-list li {
  margin-bottom: 2px;
}

/* CV links: inherit the print aesthetic, quiet underline */
.cv a {
  color: inherit;
  text-decoration: none;
  border-bottom: 0.5px solid rgba(30, 30, 30, 0.4);
}

/* Breathing room between experience entries — consistent 12px rhythm */
.cv-meta + .cv-subheading,
.cv-body + .cv-subheading {
  margin-top: 12px;
}

/* Glare layer: moving sheen above the paper grain, clipped to the face.
   No z-index (DOM order already places it on top) — a composited layer
   would escape the face's backface culling and flash mid-flip. */
.card-glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
  background: linear-gradient(
    105deg,
    transparent 40%,
    rgba(255, 255, 255, 0.35) 50%,
    transparent 60%
  );
  background-size: 250% 250%;
}

/* ============================================================
   Back face: portfolio micro-slider
   ============================================================ */
.card-back {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Extra bottom padding lifts the project block, balancing the
     dots/arrow row anchored along the bottom edge */
  padding: 0 64px 48px;
}

/* Project text block — cross-fades on project switch */
.project-view {
  transition: opacity 0.25s ease;
}

.project-view.is-fading {
  opacity: 0;
}

/* Project stack tag line, top of the entry */
.project-stack {
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

.project-name {
  display: inline-block;
  margin-top: 12px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 26px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(30, 30, 30, 0.85);
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
  transition: opacity 0.2s ease;
}

.project-name:hover {
  opacity: 0.6;
}

/* [ Details ] expand trigger — same convention as [ CV ] */
.project-expand {
  display: inline-block;
  margin: 16px 0 0;
  border: none;
  background: none;
  padding: 4px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.3s ease;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

.project-expand:hover {
  opacity: 1;
}

/* Next-project arrow, bottom-right (aligned with the dots' baseline) */
.project-next {
  position: absolute;
  right: 56px;
  bottom: 30px;
  border: none;
  background: none;
  padding: 4px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-size: 18px;
  color: rgba(30, 30, 30, 0.85);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.2s ease;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

.project-next:hover {
  opacity: 1;
}

/* Pagination dots, bottom-left */
.project-dots {
  position: absolute;
  left: 64px;
  bottom: 40px;
  display: flex;
  gap: 10px;
}

.pagination-dot {
  width: 6px;
  height: 6px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(30, 30, 30, 0.85);
  opacity: 0.25;
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.pagination-dot:hover {
  opacity: 0.5;
}

.pagination-dot.is-active {
  opacity: 1;
  transform: scale(1.3);
}

/* ============================================================
   Card -> CV expanded state
   ============================================================ */

/* Deepened shadow animates with the resize (paper lifted toward viewer) */
.card-front,
.card-back {
  transition: box-shadow 0.7s ease;
  will-change: box-shadow;
}

.card.is-expanded {
  width: min(800px, 92vw);
  height: 90vh;
}

.card.is-expanded .card-front,
.card.is-expanded .card-back {
  box-shadow:
    0 90px 160px -30px rgba(0, 0, 0, 0.22),
    0 40px 80px -20px rgba(0, 0, 0, 0.16),
    0 12px 28px -8px rgba(0, 0, 0, 0.10);
}

/* During the morph: drop the SVG-filter grain and shadow animation.
   Filtered + blend-mode layers force software rasterization of the whole
   scaling subtree every frame — that is the 15fps stutter. The grain
   returns the instant the card settles, so rest state is unchanged. */
.card.is-morphing .card-front::before,
.card.is-morphing .card-back::before {
  opacity: 0;
}

.card.is-morphing .card-front,
.card.is-morphing .card-back {
  transition: none;
}

/* [ CV ] trigger, top-right corner — styled like the corner details
   on the movie card */
.cv-button {
  position: absolute;
  top: 26px;
  right: 30px;
  border: none;
  background: none;
  padding: 4px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(30, 30, 30, 0.85);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.3s ease;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

.cv-button:hover {
  opacity: 1;
}

/* Front intro + footer + location fade out while expanding */
.front-intro,
.card-footer,
.card-location {
  transition: opacity 0.3s ease;
}

.card.is-expanded .front-intro,
.card.is-expanded .card-footer,
.card.is-expanded .card-location,
.card.is-expanded .cv-button {
  opacity: 0;
  pointer-events: none;
}

/* CV / project panel: absolute over the face, revealed only after resize
   (opacity + visibility so it never intercepts clicks while hidden) */
.cv-panel,
.project-panel {
  position: absolute;
  inset: 48px 56px;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.4s ease, visibility 0.4s ease;
}

.cv-panel.is-open,
.project-panel.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Back-face controls fade out while a project detail is expanded */
.project-dots {
  transition: opacity 0.3s ease;
}

.card.is-expanded .project-view,
.card.is-expanded .project-next,
.card.is-expanded .project-dots {
  opacity: 0;
  pointer-events: none;
}

/* Close icon, top-right of the expanded card (lifted in Z above the faces) */
.card-close {
  position: absolute;
  top: 14px;
  right: 16px;
  z-index: 10;
  transform: translateZ(20px);
  backface-visibility: hidden;
  border: none;
  background: none;
  padding: 4px;
  font-family: "Inter", sans-serif;
  font-size: 14px;
  color: #1A1A1A;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.card.is-expanded .card-close {
  opacity: 0.55;
  pointer-events: auto;
}

/* The back-face copy already inherits the face's 3D offset */
.card-back .card-close {
  transform: none;
}

.card-close:hover {
  opacity: 1;
}

/* Download PDF action, top-right of the front face (near ✕, no overlap).
   Lives on .card-front (not inside .cv-panel) because the panel's
   overflow-y: auto would clip it at its negative offset. */
.cv-download {
  position: absolute;
  top: 18px;
  right: 64px;
  padding: 4px;
  font-family: "Copperplate Gothic Light", "Copperplate", "Copperplate Gothic", serif;
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(30, 30, 30, 0.85);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, 1),
               -1px -1px 1px rgba(0, 0, 0, 0.12);
}

.card.is-cv-open .cv-download {
  opacity: 0.55;
  pointer-events: auto;
}

.cv-download:hover {
  opacity: 1;
}

/* Non-CV UI text: prevent accidental selection on rapid clicks */
.front-intro,
.card-footer,
.card-back,
.cv-button,
.cv-download,
.card-close {
  user-select: none;
  -webkit-user-select: none;
}

/* Clean page breaks when the CV is rendered to PDF */
.cv-section,
.cv-subheading,
.cv-meta,
.cv-list li {
  page-break-inside: avoid;
  break-inside: avoid;
}
