/* ==========================================================================
   portfolio.css — production portfolio homepage
   Scoped, additive layer on top of the Webflow identity. All new selectors
   are prefixed .pf-* and the page-level overrides are scoped to body.home so
   the shared Webflow stylesheet and the legacy pages are left untouched.
   ========================================================================== */

@font-face {
  font-family: "Graphik Home";
  src: url("../fonts/Graphik-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Graphik Home";
  src: url("../fonts/Graphik-Medium.ttf") format("truetype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* The Webflow .portv3 body is locked to height:100vh for the single-screen
   intro. The portfolio scrolls, so release the height on the home page only. */
body.portv3.home {
  height: auto;
  min-height: 100dvh;
  background: #fdfdfc;
  color: #111210;
  font-family: "Graphik Home", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.pf-skip {
  position: fixed;
  z-index: 10;
  top: 12px;
  left: 12px;
  padding: 10px 14px;
  border-radius: 7px;
  color: #fff;
  background: #111210;
  font: 500 13px/1 "Graphik Home", Arial, sans-serif;
  transform: translateY(-160%);
  transition: transform 0.2s ease;
}

.pf-skip:focus {
  transform: translateY(0);
}

/* Vesuvius Challenge cover: the supplied volcano artwork, filling the shared
   1200/630 frame. Like the Romulus card, it deliberately COVERS rather than
   letterboxes; object-position keeps the crater and lava flow in view. It takes
   the same restrained tonal-wash hover as every other card — nothing scales. */
.pf-vesuvius .pf-frame > img.pf-vesuvius-cover{
  object-fit:cover;
  object-position:50% 42%;
  background:#0a0e14;
}

/* --- Intro alignment ----------------------------------------------------- */
/* Match the intro to the work section: same 760px editorial width and left
   edge. Both are centered inside the body.portv3 horizontal padding (85px
   desktop / 24px mobile), so equal max-widths give identical left edges. The
   24px mobile gutter is inherited from that body padding and stays intact. */
body.home .container-29.pport3 {
  width: 100%;
  max-width: 760px;
  margin-top: clamp(68px, 8vw, 96px);
  box-sizing: border-box;
}

/* Defensive: Webflow constrains the avatar to width:40px but leaves height
   from the intrinsic ratio. Keep height derived from that width so responsive
   srcset source selection can never distort the rendered box. */
body.home .image-39 {
  width: 42px;
  height: auto;
  border-radius: 50%;
}

body.home .port3.header {
  max-width: 690px;
  padding-bottom: 20px;
}

body.home .port3.header > .port3-h1:not(.subhead) {
  margin-bottom: 7px;
  color: #111210;
  font-family: "Graphik Home", Arial, sans-serif;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.015em;
}

body.home .port3-h1.subhead {
  color: #71736f;
  font-family: "Graphik Home", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.52;
  letter-spacing: -0.008em;
  text-wrap: pretty;
}

.link-daylight,
body.home .link-49.cherry {
  color: #111210;
  text-decoration-color: rgba(17, 18, 16, 0.22);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

.link-daylight:hover,
.link-daylight:focus-visible,
body.home .link-49.cherry:hover,
body.home .link-49.cherry:focus-visible {
  color: #111210;
  text-decoration-color: #111210;
}

/* Intro links: one horizontal, wrap-friendly nav under the bio — same
   footer treatment (.pf-contact-links), one row at 720px, clean wrap at 390px. */
.pf-intro-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 24px;
  margin-top: 4px;
  font-family: "Graphik Home", Arial, sans-serif;
  font-size: 14px;
  line-height: 24px;
}
/* Calm contact row: subtle gray at rest, black on hover/focus. Overrides the
   webflow link-51/link-52 colors (single-class, lower specificity). */
.pf-intro-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: #9ca3af;
  transition: color 0.2s ease, opacity 0.2s ease;
}
.pf-intro-nav a:hover,
.pf-intro-nav a:focus-visible {
  color: #111;
  opacity: 1;
}
.pf-intro-nav a:focus-visible {
  outline: 2px solid #111;
  outline-offset: 4px;
  border-radius: 3px;
}

/* --- Work section shell -------------------------------------------------- */
.pf-work {
  max-width: 760px;
  margin: 0 auto;
  padding: 16px 0 128px;
  font-family: "Graphik Home", Arial, sans-serif;
  color: #111210;
}

.pf-work a {
  color: inherit;
  text-decoration: none;
}

/* Quiet editorial section label + hairline */
.pf-eyebrow {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin: 0 0 30px;
  padding-top: 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
}
.pf-eyebrow .pf-kicker {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #9ca3af;
}
.pf-eyebrow .pf-note {
  font-size: 13px;
  color: #c2c6cd;
  margin-left: auto;
}

/* --- Media frame --------------------------------------------------------- */
.pf-frame {
  /* Single-cell grid: media and the optional logo overlay share one "stack"
     cell, so the logo is centered by the grid — no transform math to drift. */
  display: grid;
  grid-template-areas: "stack";
  width: 100%;
  /* Every card shares one 1200/630 frame; artwork is contained, never cropped,
     so mixed sources (1200x630, 2400x1260, RatMap 1280x720) all show in full. */
  aspect-ratio: 1200 / 630;
  overflow: hidden;
  border-radius: 13px;
  border: 1px solid rgba(17, 18, 16, 0.08);
  background: #f6f6f5;
  box-shadow: 0 1px 0 rgba(17, 18, 16, 0.02);
  transition: border-color 0.25s ease, box-shadow 0.3s ease;
}
.pf-frame > img:not(.pf-logo-overlay),
.pf-frame > video {
  grid-area: stack;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border: none;
  border-radius: 0;
  /* Only the tonal-wash hover transitions; never geometry. */
  transition: filter 0.3s ease;
}
/* Lead media: motion video by default, static poster under reduced motion.
   Pure CSS swap, no JS — the reduced-motion rule lives near the bottom.
   Specificity matches the cover rule above (0,2,1) and wins on source order. */
.pf-frame > img.pf-lead-still {
  display: none;
}
/* Romulus feature: the market loop deliberately FILLS its 1200/630 card
   (object-fit: cover), unlike the contained artwork on every other card, so
   the 3:2 source reads as a designed cover rather than a letterboxed still.
   Motion video by default, static still under reduced motion — a pure CSS
   swap handled below. These rules follow the base .pf-frame media rules so the
   cover fill and the still's hidden default win on equal specificity by source
   order; only the Romulus card is affected, never WaitLayer/other cover art. */
.pf-frame > video.pf-romulus-video {
  object-fit: cover;
}
.pf-frame > img.pf-romulus-still {
  display: none;
  object-fit: cover;
}
/* Daylight wordmark: centered by the grid cell (place-self), never by a
   transform, so hover and the reduced-motion video/still swap can never
   shift it. Explicit stacking above the media, intrinsic-safe size cap. */
.pf-logo-overlay {
  grid-area: stack;
  place-self: center;
  z-index: 2;
  width: 32%;
  max-width: 384px;
  height: auto;
  border: none;
  border-radius: 0;
  pointer-events: none;
  transform: none;
  transition: none;
}

/* --- Caption block ------------------------------------------------------- */
.pf-cap {
  display: block;
  margin-top: 16px;
}
.pf-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px 9px;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.35;
  color: #111210;
  letter-spacing: -0.005em;
}
.pf-title-text {
  display: inline-block;
}
.pf-tags {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
}
.pf-title .work-tag,
.pf-title .work-tag + .work-tag {
  margin-left: 0;
}
.pf-desc {
  display: block;
  margin-top: 5px;
  font-size: 14.5px;
  line-height: 1.5;
  color: #6b7280;
  max-width: 46ch;
  text-wrap: pretty;
}
.pf-year {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: #b8bcc4;
}

/* --- Lead flagship (Daylight) ------------------------------------------- */
.pf-lead {
  display: block;
  margin-bottom: 60px;
}
.pf-lead .pf-cap {
  margin-top: 20px;
}
.pf-lead .pf-title {
  font-size: 20px;
  font-weight: 500;
}
.pf-lead .pf-desc {
  font-size: 15.5px;
  max-width: 52ch;
}

/* --- Secondary feature (WaitLayer) -------------------------------------- */
.pf-feature {
  display: block;
  margin-bottom: 52px;
}
.pf-feature .pf-title {
  font-size: 18px;
}
.pf-feature .pf-desc {
  font-size: 15px;
}

/* --- Grid of recent solo builds ----------------------------------------- */
.pf-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px 28px;
  margin-bottom: 8px;
}
.pf-tile {
  display: block;
}
.pf-tile .pf-frame {
  border-radius: 10px;
}
.pf-tile .pf-cap {
  margin-top: 13px;
}

/* --- Earlier work: heading + a couple of tiles, then compact archive ---- */
.pf-earlier {
  margin-top: 64px;
}

/* --- Compact archive rows ----------------------------------------------- */
.pf-archive {
  margin-top: 8px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
}
/* A designed ledger: four aligned columns — title | tags | description | year.
   Separate spans (not tags nested in the title) so every column lines up. */
.pf-row {
  display: grid;
  grid-template-columns: 188px 128px 1fr auto;
  align-items: baseline;
  column-gap: 20px;
  min-height: 46px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.07);
  transition: opacity 0.25s ease;
}
.pf-row-title {
  font-size: 15px;
  font-weight: 500;
  color: #111;
}
.pf-row-tags {
  display: inline-flex;
  align-items: center;
}
/* Tag sits in its own column, so drop the leading margin it carries inline. */
.pf-row-tags .work-tag {
  margin-left: 0;
}
.pf-row-desc {
  font-size: 14px;
  line-height: 1.45;
  color: #9ca3af;
  transition: color 0.2s ease;
}
.pf-row-year {
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: #c2c6cd;
  text-align: right;
  white-space: nowrap;
  transition: color 0.2s ease;
}

/* --- Contact ending ------------------------------------------------------ */
.pf-contact {
  margin-top: 72px;
  padding-top: 24px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
}
.pf-contact-line {
  font-size: 15px;
  line-height: 1.55;
  color: #6b7280;
}
.pf-contact-line a {
  color: #111;
  transition: opacity 0.25s ease;
}
.pf-contact-links {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  font-size: 14px;
}
.pf-contact-links a {
  color: #9ca3af;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  transition: opacity 0.25s ease;
}

/* --- Hover / focus (pointers + keyboard) -------------------------------- */
/* One restrained, transform-free treatment shared by every primary thumbnail
   (pf-lead, pf-feature, pf-tile). The hairline darkens, the drop shadow deepens
   a touch, and a whisper-soft tonal wash lifts the artwork — like light catching
   the glass of a museum frame. Nothing scales, translates, or moves; the arrow
   below carries the directional cue. Hover is gated to fine pointers so it never
   sticks on touch, and keyboard focus mirrors the same wash. */
@media (hover: hover) and (pointer: fine) {
  .pf-lead:hover .pf-frame,
  .pf-feature:hover .pf-frame,
  .pf-tile:hover .pf-frame {
    border-color: rgba(17, 18, 16, 0.17);
    box-shadow: 0 12px 32px rgba(17, 18, 16, 0.06);
  }
  .pf-lead:hover .pf-frame > img:not(.pf-logo-overlay),
  .pf-lead:hover .pf-frame > video,
  .pf-feature:hover .pf-frame > img,
  .pf-feature:hover .pf-frame > video,
  .pf-tile:hover .pf-frame > img {
    filter: brightness(1.03) saturate(1.04);
  }
}
.pf-lead:focus-visible .pf-frame,
.pf-feature:focus-visible .pf-frame,
.pf-tile:focus-visible .pf-frame {
  border-color: rgba(17, 18, 16, 0.17);
  box-shadow: 0 12px 32px rgba(17, 18, 16, 0.06);
}
.pf-lead:focus-visible .pf-frame > img:not(.pf-logo-overlay),
.pf-lead:focus-visible .pf-frame > video,
.pf-feature:focus-visible .pf-frame > img,
.pf-feature:focus-visible .pf-frame > video,
.pf-tile:focus-visible .pf-frame > img {
  filter: brightness(1.03) saturate(1.04);
}
/* Safeguard: no hover/focus state may transform or move the Daylight overlay
   or the media. The logo stays grid-centered with transform:none at all times. */
.pf-lead:hover .pf-logo-overlay,
.pf-lead:focus-within .pf-logo-overlay,
.pf-lead:focus-visible .pf-logo-overlay {
  transform: none;
  place-self: center;
}
/* Hard guarantee that the wash never becomes motion: thumbnail media is pinned
   to transform:none on every hover/focus state, so nothing can scale or shift. */
.pf-lead:hover .pf-frame > img:not(.pf-logo-overlay),
.pf-lead:hover .pf-frame > video,
.pf-feature:hover .pf-frame > img,
.pf-feature:hover .pf-frame > video,
.pf-tile:hover .pf-frame > img,
.pf-lead:focus-visible .pf-frame > img:not(.pf-logo-overlay),
.pf-lead:focus-visible .pf-frame > video,
.pf-feature:focus-visible .pf-frame > img,
.pf-feature:focus-visible .pf-frame > video,
.pf-tile:focus-visible .pf-frame > img {
  transform: none;
}
/* Hover/focus strengthens legibility: modestly darken the description and year
   instead of fading the whole row. The row does not move or resize. */
.pf-row:hover .pf-row-desc,
.pf-row:focus-visible .pf-row-desc,
.pf-row:focus-within .pf-row-desc {
  color: #6b7280;
}
.pf-row:hover .pf-row-year,
.pf-row:focus-visible .pf-row-year,
.pf-row:focus-within .pf-row-year {
  color: #9ca3af;
}
.pf-contact-line a:hover,
.pf-contact-links a:hover {
  opacity: 0.5;
}

/* Visible, consistent focus ring for keyboard users */
.pf-work a:focus-visible {
  outline: 2px solid #111;
  outline-offset: 4px;
  border-radius: 4px;
}
.pf-work a:focus:not(:focus-visible) {
  outline: none;
}

/* --- Responsive: designed for 390px, not merely collapsed --------------- */
@media screen and (max-width: 767px) {
  body.home .container-29.pport3 {
    margin-top: 48px;
  }
  body.home .port3.header > .port3-h1:not(.subhead) {
    font-size: 16px;
  }
  body.home .port3-h1.subhead {
    font-size: 16px;
    line-height: 1.5;
  }
  .pf-work {
    max-width: none;
    padding-bottom: 88px;
  }
  .pf-eyebrow .pf-note {
    display: none;
  }
  .pf-lead {
    margin-bottom: 44px;
  }
  .pf-lead .pf-title {
    font-size: 18px;
  }
  .pf-title {
    gap: 6px 8px;
  }
  .pf-feature .pf-title {
    font-size: 17px;
  }
  .pf-grid {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  .pf-earlier {
    margin-top: 52px;
  }
  /* Compact mobile ledger: title + year share the first line, tag(s) hold a
     stable second row, description spans the full width on a third row. */
  .pf-row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "title year"
      "tags  tags"
      "desc  desc";
    column-gap: 12px;
    row-gap: 5px;
    padding: 15px 0;
    align-items: baseline;
  }
  .pf-row-title {
    grid-area: title;
  }
  .pf-row-tags {
    grid-area: tags;
  }
  .pf-row-desc {
    grid-area: desc;
  }
  .pf-row-year {
    grid-area: year;
    text-align: right;
  }
}

/* --- Motion / no-JS safety ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* Keep the tonal-wash hover, but apply it instantly rather than easing it. */
  .pf-frame > img:not(.pf-logo-overlay),
  .pf-frame > video {
    transition: none;
  }
  /* Swap the autoplaying lead loop for its still poster frame.
     Specificity 0,2,1 to override the cover/base rules above. */
  .pf-frame > video.pf-lead-video {
    display: none;
  }
  .pf-frame > img.pf-lead-still {
    display: block;
  }
  /* Same swap for the Romulus feature loop: hide the video, reveal its still. */
  .pf-frame > video.pf-romulus-video {
    display: none;
  }
  .pf-frame > img.pf-romulus-still {
    display: block;
  }
  /* The intro relies on a Webflow load animation; guarantee it is legible
     when motion is reduced. */
  .home [data-w-id] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* If JavaScript never runs, Webflow can't reveal the intro — show it. */
html:not(.w-mod-js) .home [data-w-id] {
  opacity: 1 !important;
  transform: none !important;
}

/* ==========================================================================
   Status / provenance tags — preserved verbatim from work.html so the
   taxonomy and its honest labels stay identical across the site.
   ========================================================================== */
.work-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  vertical-align: 2px;
  margin-left: 8px;
  padding: 3px 9px;
  border: 1px solid #e5e7eb;
  border-radius: 100px;
  font-family: "Graphik Home", Arial, sans-serif;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #6b7280;
  background: #fff;
  white-space: nowrap;
}
.work-tag + .work-tag { margin-left: 5px; }
.work-tag i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #22c55e;
  animation: tagPulse 2.6s ease-out infinite;
}
@keyframes tagPulse {
  0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.35); }
  60% { box-shadow: 0 0 0 5px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}
.work-tag.beta i { background: #f59e0b; animation: betaBreathe 2.8s ease-in-out infinite; }
.work-tag.ongoing {
  color: #b93420;
  border-color: #f0d2cc;
  background: #fff8f6;
}
.work-tag.ongoing i {
  width: 9px;
  height: 2px;
  border-radius: 2px;
  background: #e34025;
  animation: none;
}
.work-tag.research {
  color: #5f625d;
  border-color: #e2e3df;
  background: #f7f7f4;
}
.work-tag.acq b {
  color: #8b5cf6;
  font-weight: 400;
  font-size: 10px;
  line-height: 1;
  display: inline-block;
  animation: acqGlow 4.8s ease-in-out infinite;
}
@keyframes acqGlow {
  0%, 100% { opacity: 0.5; text-shadow: none; }
  50% { opacity: 1; text-shadow: 0 0 7px rgba(139, 92, 246, 0.45); }
}
@keyframes betaBreathe {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(0.72); opacity: 0.55; }
}
.work-tag.fill { background: #f4f4f5; border-color: #f4f4f5; }
.work-tag.solo {
  color: #15803d;
  border-color: #dcfce7;
  background: linear-gradient(110deg, #f0fdf4 40%, #fafffc 50%, #f0fdf4 60%);
  background-size: 260% 100%;
  background-position: -35% 0;
  animation: soloSheen 4.5s linear infinite;
}
.work-tag.solo.amber {
  color: #b45309;
  border-color: #fef3c7;
  background: linear-gradient(110deg, #fffbeb 40%, #fffdf6 50%, #fffbeb 60%);
  background-size: 260% 100%;
  background-position: -35% 0;
}
@keyframes soloSheen {
  0% { background-position: 135% 0; }
  45% { background-position: -35% 0; }
  100% { background-position: -35% 0; }
}
.work-tag.muted { color: #a8adb5; border-color: #ededef; }
.work-tag.dashed { border-style: dashed; }
@media (prefers-reduced-motion: reduce) {
  .work-tag i, .work-tag.solo, .work-tag.acq b { animation: none; }
}
