/* ==========================================================================
   Sketchbook Portfolio — shared styles
   --------------------------------------------------------------------------
   The whole site is drawn on a fixed 1512 x 982 "stage" (the same frame used
   in the Figma file) and then scaled to fit the viewport with a CSS variable
   set in scripts/app.js. Every element inside the stage can therefore use the
   exact pixel coordinates from the design.
   ========================================================================== */

:root {
  /* Design frame — keep in sync with scripts/app.js */
  --frame-w: 1512px;
  --frame-h: 982px;
  --scale: 1;

  /* Sketchbook "tab" colours (from Figma) */
  --tab-about:    #ffb6ec; /* pink   */
  --tab-projects: #e2a2ff; /* purple */
  --tab-contact:  #ebff99; /* lime   */
  --tab-resume:   #a8f9ff; /* cyan   */

  --ink:      #000000;
  --ink-soft: #555555;

  --font-mono: "Intel One Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --font-sans: "Inter", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #ffffff;
  font-family: var(--font-mono);
  color: var(--ink);
  /* Keep the page from scrolling — the stage is scaled to fit instead. */
  overflow: hidden;
}

/* Load gracefully: keep the content hidden until the script signals everything
   is ready (stage scaled, tabs built, fonts + images loaded), then fade it in as
   a whole — this avoids the jagged one-by-one / scale-jump render on first paint.
   `is-ready` is added to <body> by scripts/app.js and scripts/project.js. */
.viewport, .desk { opacity: 0; }
body.is-ready .viewport,
body.is-ready .desk { opacity: 1; transition: opacity 250ms ease; }

/* --- Scaling shell ---------------------------------------------------------
   .viewport centres the stage; .stage holds everything at 1:1 design pixels
   and is scaled down (or up) by --scale.                                     */
.viewport {
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.stage {
  position: relative;
  width: var(--frame-w);
  height: var(--frame-h);
  flex: 0 0 auto;
  transform: scale(var(--scale));
  transform-origin: center center;
  background: #ffffff;
}

/* --- Background sketchbook image ------------------------------------------
   Each page drops its scanned sketchbook photo in here. Replace the files in
   /assets to swap the artwork; positioning is handled by object-fit.         */
.page-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  pointer-events: none;
  user-select: none;
}

/* ==========================================================================
   Navigation "tabs" — the coloured rectangles poking out of the book edges
   ========================================================================== */
.tab {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 42px;
  padding: 0 16px;
  font-family: var(--font-mono);
  font-size: 20px;
  line-height: 1;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  /* Paper look, matching the résumé tab: beige sheet, soft border + shadow,
     with the chapter colour showing only as an edge accent (below). */
  background: #fcfbf3;
  border: 1px solid rgba(0, 0, 0, 0.10);
  border-radius: 4px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.10);
  cursor: pointer;
  transition: transform 160ms ease, box-shadow 160ms ease;
}

/* Chapter colour as an accent stripe down the tab's OUTWARD edge (the edge that
   pokes out of the book). --tab-accent is set per-tab in scripts/app.js. */
.tab.left::before,
.tab.right::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 6px;
  background: var(--tab-accent, var(--ink-soft));
}
.tab.left::before  { left: 0;  border-radius: 4px 0 0 4px; }
.tab.right::before { right: 0; border-radius: 0 4px 4px 0; }

/* Give the label a little breathing room from the accent stripe. */
.tab.left  { padding-left: 20px; }
.tab.right { padding-right: 20px; }

/* Hinge each tab on its book-side edge (the same edge it's anchored to in
   scripts/app.js), so hover can swing it up off the page like a lifted flap. */
.tab.left  { transform-origin: right center; }
.tab.right { transform-origin: left center; }

/* On hover a link tab folds up on its hinge, peeling its outer edge toward the
   viewer. The shadow sells the lift. Flip the rotateY sign to fold it the
   other way (back into the book instead of up off it). */
a.tab.left:hover {
  transform: perspective(700px) rotateY(28deg);
  box-shadow: -6px 4px 10px rgba(0, 0, 0, 0.18);
}
a.tab.right:hover {
  transform: perspective(700px) rotateY(-28deg);
  box-shadow: 6px 4px 10px rgba(0, 0, 0, 0.18);
}

/* The active chapter's tab is not a link. It's nudged INTO the book (past its
   book-side edge) so the current tab reads as tucked under the page — the
   direction is inward, which is rightward for a left tab and leftward for a
   right tab. */
.tab.active { cursor: default; color: var(--ink); }
.tab.active.left  { transform: translateX(16px); }
.tab.active.right { transform: translateX(-16px); }

/* Underline just the label text of link tabs (not the arrow), matching Figma. */
.tab .u { text-decoration: underline; }

/* Resume "tab" — styled as a sheet of paper tucked behind the book. It sits at
   z-index -1 (behind .page-bg, which is a transparent PNG), so only the strip
   above the book's top edge shows. The cyan cap marks where to grab it; hover
   slides the sheet up, as if pulling it out from behind the page. */
.tab.resume {
  width: 370px;
  height: 200px;
  padding: 16px 16px 0;
  align-items: flex-start;
  justify-content: center;
  font-size: 18px;
  color: var(--ink-soft);
  background: #fcfbf3;
  border: 1px solid rgba(0, 0, 0, 0.10);
  border-radius: 3px 3px 8px 8px;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.10);
  transform: rotate(-1.5deg);
  transition: transform 180ms ease;
  z-index: -1;
}
.tab.resume::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 6px;
  background: var(--tab-resume);
  border-radius: 3px 3px 0 0;
}
.tab.resume:hover { transform: rotate(-1.5deg) translateY(-10px); }

/* ==========================================================================
   Page-specific overlay content (text that sits on top of the sketchbook)
   ========================================================================== */

/* Landing — clickable sketchbook cover on the right side of the frame. */
.cover-link {
  position: absolute;
  left: 699px;
  top: 74px;
  width: 589px;
  height: 908px;
  display: block;
  overflow: hidden;
  cursor: pointer;
}
.cover-link img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}
.cover-hint {
  position: absolute;
  left: 1040px;
  top: 760px;
  font-size: 16px;
  color: var(--ink-soft);
  opacity: 0.7;
}

/* About — intro paragraph on the left page. */
.about-intro {
  position: absolute;
  left: 268px;
  top: 406px;
  width: 427px;
  font-size: 16px;
  line-height: 1.35;
  color: var(--ink);
}
.about-intro p { margin: 0 0 1em; }
.about-intro em { font-style: italic; }

/* Projects — clickable "sticker" entries into each case study. Position each
   sticker with left/top inline; every sticker renders at the same width here so
   they stay uniform regardless of the source PNG's dimensions. */
.project-sticker {
  position: absolute;
  display: block;
  text-decoration: none;
  cursor: pointer;
}
.project-sticker img {
  display: block;
  /* Default size; override per sticker by setting --sticker-w inline on the
     <a>, e.g. style="…; --sticker-w: 160px;" */
  width: var(--sticker-w, 120px);
  height: auto;
  /* drop-shadow (not box-shadow) follows the PNG's cut-out shape, so irregular
     stickers cast a realistic shadow instead of a rectangle. */
  filter: drop-shadow(2px 3px 2px rgba(0, 0, 0, 0.22));
  transition: transform 120ms ease, filter 120ms ease;
}
/* Peel up on hover: keep the tilt, and grow the shadow to sell the lift. */
.project-sticker:hover img {
  transform: scale(1.04) rotate(-2deg);
  filter: drop-shadow(4px 7px 5px rgba(0, 0, 0, 0.28));
}

/* Project title tooltip — follows the cursor while a sticker is hovered
   (positioned in JS; see initStickerTooltips in scripts/app.js). */
.sticker-tooltip {
  position: fixed;
  z-index: 100;
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--ink);
  white-space: nowrap;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 4px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
}
.sticker-tooltip.is-visible { opacity: 1; }

/* Contact — details on the sticky note over the left page. */
.contact-info {
  position: absolute;
  left: 406px;
  top: 249px;
  width: 350px;
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 1.35;
  color: var(--ink);
}
.contact-info p { margin: 0 0 0.35em; }
.contact-info .lead { font-style: italic; margin-bottom: 1em; }
.contact-info a { color: inherit; text-decoration: none; }
.contact-info a:hover { text-decoration: underline; }

/* ==========================================================================
   Resume page — the résumé shown like a printed sheet laid on a graph-paper
   desk, with a download sticker taped beside it.
   ========================================================================== */

/* Faint graph paper, echoing the sketchbook's ruled pages. Applied to the whole
   window (not the scaled .stage) so it fills any display; the stage is made
   transparent so the desk shows through behind the résumé sheet. */
body[data-page="resume"] {
  background:
    repeating-linear-gradient(rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 32px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 32px),
    #f6f3ea;
}
body[data-page="resume"] .stage { background: transparent; }

.resume-title {
  position: absolute;
  left: 452px;
  top: 34px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 30px;
  font-weight: 400;
  color: var(--ink);
}

/* The résumé itself — a white sheet with a soft drop shadow, slightly askew. */
.resume-doc {
  position: absolute;
  left: 452px;
  top: 92px;
  width: 600px;
  height: 848px;              /* ~A4 portrait ratio */
  background: #ffffff;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);
  transform: rotate(-1deg);
  overflow: hidden;
}
.resume-doc img,
.resume-doc embed {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background: #ffffff;
}

/* Download prompt, taped to the right-hand page. */
.resume-aside {
  position: absolute;
  left: 1130px;
  top: 320px;
  width: 300px;
  font-family: var(--font-mono);
  font-size: 18px;
  color: var(--ink);
}
.resume-note { margin: 0 0 14px; font-style: italic; color: var(--ink-soft); }

.resume-download {
  display: inline-block;
  padding: 12px 22px;
  font-size: 18px;
  color: var(--ink);
  text-decoration: none;
  background: var(--tab-resume);
  border-radius: 4px;
  box-shadow: 2px 3px 0 rgba(0, 0, 0, 0.18);
  transform: rotate(-2deg);
  transition: transform 140ms ease, box-shadow 140ms ease;
}
.resume-download:hover {
  transform: rotate(-2deg) translateY(-2px);
  box-shadow: 2px 6px 0 rgba(0, 0, 0, 0.20);
}

/* Back link — reuses the .tab.left fold-on-hover, just recoloured. */
.back-tab {
  background: #efece1;
  color: var(--ink-soft);
}

/* ==========================================================================
   Project case-study pages — a SCROLLABLE sketchbook "page" on the desk.
   Unlike the fixed 1512x982 spreads, these grow to fit however much content a
   project needs. One project.html renders every project from the data in
   scripts/projects-data.js (via scripts/project.js). Building blocks:
     .case-title    — project title
     .case-blurb    — quick blurb
     .case-question — the intriguing question (highlighter swipe)
     .case-figure / .case-figures — taped-down photos (single or row)
     .case-section  — blocks of body text, with optional <h2>
   ========================================================================== */

/* The scrolling desk fills the window at any size; content scrolls within it
   (the global `overflow: hidden` on body stays; .desk owns the scroll). */
.desk {
  height: 100vh;
  overflow-y: auto;
  background:
    repeating-linear-gradient(rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 32px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 32px),
    #f6f3ea;
}

/* Centred column that reads like a page torn from the sketchbook. Sizes here are
   tuned to match the résumé page's *rendered* scale (its content is shrunk by
   --scale inside .stage; this page isn't, so its type is smaller on purpose). */
.case {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 40px 100px;
  color: var(--ink);
}

/* The résumé-style back tab, pinned to the top-left corner so it stays reachable
   as the case study scrolls. Sized down to match how the tab renders on the
   scaled résumé page. */
body[data-page="project"] .back-tab {
  position: fixed;
  left: 24px;
  top: 24px;
  z-index: 10;
  height: 30px;
  padding: 0 14px 0 18px;
  font-size: 14px;
}

.case-title {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 30px;
  font-weight: 400;
  line-height: 1.1;
}

.case-blurb {
  margin: 0 0 30px;
  max-width: 540px;
  font-family: var(--font-sans);
  font-style: italic;
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* The intriguing question — a marker-highlighted line that anchors the page. */
.case-question {
  margin: 0 0 40px;
  font-family: var(--font-mono);
  font-size: 21px;
  line-height: 1.55;
}
.case-question span {
  /* Highlighter swipe sitting behind the words (uneven-looking band). */
  background: linear-gradient(var(--tab-projects), var(--tab-projects));
  background-repeat: no-repeat;
  background-size: 100% 46%;
  background-position: 0 78%;
  padding: 0 4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* A taped-down photo. Slight rotation for the scrapbook feel. */
.case-figure {
  margin: 0 0 36px;
  padding: 10px 10px 0;
  background: #fff;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14);
  transform: rotate(-1.2deg);
}
.case-figure img { display: block; width: 100%; height: auto; }
.case-figure figcaption {
  padding: 8px 4px 12px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-soft);
}

/* A row of photos that wraps on narrow windows; alternating tilt. */
.case-figures {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  margin: 0 0 36px;
}
.case-figures .case-figure { flex: 1 1 260px; margin: 0; }
.case-figures .case-figure:nth-child(even) { transform: rotate(1.2deg); }

/* A block of body text, with an optional small section heading. */
.case-section { margin: 0 0 32px; max-width: 540px; }
.case-section h2 {
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 400;
}
.case-section p {
  margin: 0 0 1em;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
}
