/* ============================================================================
   portfolio.css — the categorised portfolio, laid out like the reference
   (devanshprakash.com/portfolio): a sticky category rail on the left, and a
   right-hand column of per-service-line sections, each with its own heading,
   description and grid of project cards.

   Built in the Blizznex design language rather than copying the reference's
   dark theme, so the page belongs to the rest of the site: white surfaces,
   --ink text, --blue accent, the same radii and easing curves as style.css.

   Scoped under .pf and loaded after style.css. The card component (.pf-card)
   is deliberately shared with the homepage preview, at a lower density, so
   both read as one system instead of two unrelated card designs.
   ========================================================================= */

.pf{
  --pf-line:#e4e6ef;
  --pf-soft:#f4f5f9;
  --pf-muted:#5b5f78;
  --pf-surface:#fff;
  --pf-radius:16px;
  --pf-thumb-radius:12px;
  --pf-shadow:0 4px 20px rgba(11,11,16,.06);
  --pf-shadow-hover:0 14px 38px rgba(11,11,16,.14);
  /* the fixed site header overlays the page; sections and the sticky rail
     both need to clear it. Measured at runtime by portfolio.js. */
  --pf-headroom:100px;
}

/* ------------------------------------------------------------- structure -- */
/* .section supplies the site's standard gutters; .pf-wrap supplies its own so
   the rail and the grid share one measurement. Zero the section's horizontal
   padding or the two stack and the page sits inset twice as far as the header. */
.pf.section{padding-left:0;padding-right:0}
.pf-wrap{padding:0 var(--pad-x,40px) 6vh}

/* The work page leads straight into the categorised layout, so the intro
   doesn't need the near-full-screen height it gets elsewhere — that reads as
   a blank screen between the headline and the first project. */
body[data-page="projects"] #about-intro{min-height:auto;padding-top:calc(16vh);padding-bottom:2vh}
.pf-layout{
  display:grid;
  grid-template-columns:236px minmax(0,1fr);
  gap:clamp(28px,4vw,72px);
  align-items:start;
}

/* ============================================================== SIDEBAR ====
   Sticky category rail. Top-level entries are the service lines; a service
   line with sub-groups gets a collapsible list beneath it, exactly like the
   reference's Graphic Design / Video Projects tree.
   ========================================================================= */
.pf-rail{position:sticky;top:calc(var(--pf-headroom) + 24px)}
.pf-rail-label{
  font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--pf-muted);margin-bottom:14px;
}
.pf-nav{display:flex;flex-direction:column;gap:2px}
.pf-nav-group + .pf-nav-group{
  margin-top:6px;padding-top:6px;border-top:1px solid var(--pf-line);
}
.pf-nav-top{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;padding:9px 0;
  font-size:15px;font-weight:600;line-height:1.3;color:var(--ink);
  background:none;border:none;text-align:left;cursor:pointer;
  transition:color .22s var(--bez);
}
.pf-nav-top:hover{color:var(--blue)}
.pf-nav-top.is-current{color:var(--blue)}
/* the active marker is a bar rather than a colour change alone, so the
   current section is still obvious to anyone who can't distinguish the blue */
.pf-nav-top.is-current::before{
  content:"";position:absolute;left:calc(var(--pf-bar-offset,-14px));
  width:3px;height:1.1em;border-radius:2px;background:var(--blue);
}
.pf-nav-top{position:relative}
.pf-nav-count{
  font-size:11px;font-weight:600;color:var(--pf-muted);
  background:var(--pf-soft);border-radius:20px;padding:2px 8px;flex:none;
}
.pf-nav-caret{
  width:14px;height:14px;flex:none;color:var(--pf-muted);
  transition:transform .25s var(--bez);
}
.pf-nav-group.is-open .pf-nav-caret{transform:rotate(180deg)}
.pf-nav-subs{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .3s var(--bez);
}
.pf-nav-group.is-open .pf-nav-subs{grid-template-rows:1fr}
.pf-nav-subs-inner{overflow:hidden;display:flex;flex-direction:column}
.pf-nav-sub{
  padding:6px 0 6px 14px;font-size:14px;color:var(--pf-muted);
  border-left:1px solid var(--pf-line);margin-left:2px;
  transition:color .2s var(--bez),border-color .2s var(--bez);
}
.pf-nav-sub:hover,.pf-nav-sub.is-current{color:var(--blue);border-color:var(--blue)}

/* ============================================================== SECTIONS === */
.pf-sections{min-width:0}
.pf-section{scroll-margin-top:calc(var(--pf-headroom) + 28px)}
.pf-section + .pf-section{margin-top:clamp(56px,7vw,104px)}
.pf-section-head{margin-bottom:clamp(24px,3vw,38px)}
.pf-section-title{
  font-size:clamp(30px,4.4vw,58px);font-weight:500;line-height:1.05;
  letter-spacing:-.02em;margin:0 0 .35em;
}
.pf-section-desc{
  font-size:clamp(15px,1.15vw,18px);line-height:1.6;color:var(--pf-muted);
  max-width:62ch;margin:0;
}
.pf-sub{margin-top:clamp(32px,4vw,52px)}
.pf-sub:first-of-type{margin-top:0}
.pf-sub-title{
  display:flex;align-items:center;gap:12px;
  font-size:clamp(17px,1.5vw,22px);font-weight:600;letter-spacing:-.01em;
  margin:0 0 18px;
}
.pf-sub-title::after{
  content:"";flex:1;height:1px;background:var(--pf-line);
}

/* ================================================================= GRID ==== */
.pf-grid{display:grid;gap:clamp(16px,1.6vw,24px);grid-template-columns:repeat(3,minmax(0,1fr))}
/* The homepage preview runs the same card at a lower density. At half the page
   width the 16:11 thumbnail becomes very tall, so the two-up variant uses a
   wider crop — same component, proportion tuned to the space it sits in. */
.pf-grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.pf-grid-2 .pf-thumb{aspect-ratio:16/9}
/* the homepage grid sits under the section heading; .project-list used to
   supply this gap with its own margin-top */
#work > .pf{margin-top:clamp(36px,8vh,90px)}

/* ================================================================= CARD ====
   Order follows the reference: year, title, thumbnail, client-type label,
   then the action row.
   ========================================================================= */
.pf-card{
  display:flex;flex-direction:column;
  background:var(--pf-surface);
  border:1px solid var(--pf-line);
  border-radius:var(--pf-radius);
  padding:16px;
  transition:box-shadow .35s var(--bez),transform .35s var(--bez),border-color .35s var(--bez);
}
.pf-card:hover{
  box-shadow:var(--pf-shadow-hover);
  border-color:transparent;
  transform:translateY(-3px);
}
.pf-card-year{font-size:12px;font-weight:500;color:var(--pf-muted);line-height:1}
.pf-card-title{
  font-size:clamp(17px,1.3vw,20px);font-weight:600;letter-spacing:-.01em;
  line-height:1.25;margin:8px 0 14px;
  transition:color .25s var(--bez);
}
.pf-card:hover .pf-card-title{color:var(--blue)}

/* Thumbnail. A real screenshot fills it; with no image the gradient set on
   the element itself shows through, so every card is a designed block rather
   than an empty frame. Ratio-locked and cropped so screenshots of any shape
   sit on the same grid line. */
.pf-thumb{
  position:relative;display:block;width:100%;
  aspect-ratio:16/11;overflow:hidden;
  border-radius:var(--pf-thumb-radius);
  background:var(--pf-soft);
}
.pf-thumb img{
  position:relative;z-index:1;
  width:100%;height:100%;object-fit:cover;object-position:top center;
  display:block;transition:transform 1s var(--bez-soft);
}
.pf-card:hover .pf-thumb img{transform:scale(1.05)}
/* gradient stand-in — same treatment the cards used before any screenshots
   existed, kept as the fallback so nothing renders blank. It has to sit
   BEHIND the <img> (z-index:0 vs. the img's z-index:1 above) — without an
   explicit z-index here, this absolutely-positioned span painted on top of
   the plain, statically-positioned <img> regardless of DOM order, which is
   how a real screenshot could be correctly uploaded, correctly returned by
   the CRM API, and still never actually be visible on the card: it was
   rendering underneath this gradient the whole time. */
.pf-thumb-fallback{position:absolute;inset:0;z-index:0;transition:transform 1s var(--bez-soft)}
.pf-card:hover .pf-thumb-fallback{transform:scale(1.05)}
.pf-thumb-fallback::after{
  content:attr(data-initials);
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:clamp(28px,3vw,44px);font-weight:600;letter-spacing:-.02em;
  color:rgba(255,255,255,.5);
}
.pf img.is-broken{display:none}

.pf-card-type{
  font-size:12px;font-weight:500;color:var(--pf-muted);
  text-align:center;margin:12px 0 0;
}
.pf-card-foot{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:12px;padding-top:12px;border-top:1px solid var(--pf-line);
}
.pf-card-action{
  display:inline-flex;align-items:center;gap:7px;
  font-size:13px;font-weight:600;color:var(--blue);
}
.pf-card-icon{
  width:26px;height:26px;flex:none;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--pf-muted);background:var(--pf-soft);
  transition:background .25s var(--bez),color .25s var(--bez),transform .25s var(--bez);
}
.pf-card:hover .pf-card-icon{background:var(--blue);color:#fff;transform:translate(2px,-2px)}
.pf-card-icon svg{width:14px;height:14px}

/* ---- empty state -------------------------------------------------------- */
.pf-empty{
  border:1px dashed var(--pf-line);border-radius:var(--pf-radius);
  padding:44px 28px;text-align:center;color:var(--pf-muted);
}

/* ---- mobile category selector ------------------------------------------- */
.pf-mobile-nav{display:none}

/* ============================================================== RESPONSIVE = */
@media (max-width:1100px){
  .pf-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media (max-width:900px){
  /* The rail stops being a rail: the category tree would eat a third of a
     tablet screen for navigation the visitor can also get by scrolling. It
     becomes a horizontal chip strip pinned under the header instead. */
  .pf-layout{grid-template-columns:minmax(0,1fr);gap:0}
  .pf-rail{display:none}
  .pf-mobile-nav{
    display:block;position:sticky;top:var(--pf-headroom);z-index:40;
    background:var(--off-white);
    margin:0 calc(var(--pad-x,40px) * -1) 26px;
    padding:12px var(--pad-x,40px);
    border-bottom:1px solid var(--pf-line);
  }
  .pf-mobile-track{
    display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch;
  }
  .pf-mobile-track::-webkit-scrollbar{display:none}
  .pf-chip{
    flex:none;padding:8px 15px;border-radius:20px;
    background:var(--pf-soft);border:1px solid transparent;
    font-size:13px;font-weight:600;white-space:nowrap;color:var(--ink);
    transition:background .2s var(--bez),color .2s var(--bez);
  }
  .pf-chip.is-current{background:var(--blue);color:#fff}
}

@media (max-width:640px){
  .pf-grid,.pf-grid-2{grid-template-columns:minmax(0,1fr)}
  .pf-card{padding:14px}
  .pf-section + .pf-section{margin-top:52px}
  .pf-card-title{font-size:17px}
}

/* ---- reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .pf-card,.pf-thumb img,.pf-thumb-fallback,.pf-card-icon,.pf-nav-caret,.pf-nav-subs{
    transition:none;
  }
  .pf-card:hover{transform:none}
  .pf-card:hover .pf-thumb img,.pf-card:hover .pf-thumb-fallback{transform:none}
}
