/* Dharti Group — portfolio grid + projects page
   ============================================================ */

/* ============================================================
   PORTFOLIO
   ============================================================ */
.portfolio{
  position:relative; isolation:isolate;
  background:var(--ink);
  padding:clamp(5rem,12vh,8rem) var(--gutter);
}
.portfolio .section-head{ --maxw:1160px; }
.portfolio__grid{
  max-width:1160px; margin:0 auto; display:grid; grid-template-columns:repeat(3,1fr); gap:1.2rem;
}
.pcard{ cursor:pointer; display:block; color:inherit; }
/* THE ELEVATIONS ARE SHOWN WHOLE.
   Every render in assets/projects is a full portrait elevation at its own
   ratio (0.63 to 0.86 wide for 1 tall). Cropping them to fill a landscape
   card cut the crown off one tower and the podium off another, so the frame
   is portrait and the image is CONTAINED, not covered. What is left over at
   the sides is a mount, the way a drawing is mounted on a board.

   Nothing here may go back to object-fit:cover, and nothing may scale the
   image on hover: both crop the elevation again. Hover moves the border and
   the brightness instead. */
.pcard__img{
  height:clamp(300px,32vw,400px); border-radius:3px; overflow:hidden;
  border:1px solid var(--line); background:var(--ink-2);
  transition:border-color .4s var(--ease);
}
.pcard__img picture{ display:block; height:100%; }
.pcard__img img{
  width:100%; height:100%; object-fit:contain; display:block;
  transition:filter 1.2s var(--ease);
  filter:saturate(.88) brightness(.92);
}
/* on the cream bands the mount is a tint of the ink, not the ink itself */
.sec-light .pcard__img{
  background:rgba(6,13,28,.045); border-color:rgba(6,13,28,.12);
}
.pcard:hover .pcard__img{ border-color:var(--gold); }
.sec-light .pcard:hover .pcard__img{ border-color:var(--gold-deep); }
.pcard:hover .pcard__img img{ filter:saturate(1) brightness(1); }
.pcard:focus-visible .pcard__img{ border-color:var(--gold); outline:1px solid var(--gold); outline-offset:2px; }
.pcard__body{ padding:1rem .1rem 0; }
.pcard__name{ font-weight:500; font-size:1.15rem; color:var(--bone); }
.pcard__meta{ font-size:.64rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-top:.35rem; }

@media (max-width:900px){
  .portfolio__grid{ grid-template-columns:1fr; max-width:440px; }
}

/* ============================================================
   PROJECTS PAGE
   /projects/ only. Mirrors the scale and rhythm of the story
   page so the two inner pages read as one site.
   ============================================================ */
.pj{ --maxw:64rem; }
.pj-sec{ padding:clamp(4.5rem,11vh,8rem) var(--gutter); }
.pj-sec .section-head{ max-width:64rem; margin-left:auto; margin-right:auto; }
.pj-sec__lede{
  /* holds a 38rem measure while starting on the same left edge as the 64rem
     column above it, rather than centring under the heading */
  max-width:38rem;
  margin:0 auto clamp(2.6rem,6vw,4rem) max(0px, calc((100% - 64rem) / 2));
  color:var(--bone-dim); font-size:.98rem; line-height:1.75;
}
.sec-light .pj-sec__lede{ color:#4a5468; }

/* ---------- page head ---------- */
.pj-head{
  padding:clamp(6.5rem,14vh,9.5rem) var(--gutter) clamp(3rem,7vh,5rem);
  /* Their own building, not stock: the heading says "buildings people live in"
     and a generic office tower would contradict it in the same eyeful. Pressidio
     rather than Phase I, which already carries the section behind the panels. */
  --bg:url("../assets/projects/dharti-pressidio-full.jpg");
  --bg:image-set(url("../assets/projects/dharti-pressidio-full.webp") type("image/webp"),
                 url("../assets/projects/dharti-pressidio-full.jpg")  type("image/jpeg"));
  --bg-pos:center 18%;
  --bg-op:.52;
}
.pj-head__inner{ max-width:64rem; margin:0 auto; }
.pj-head__title{
  font-weight:500; font-size:clamp(2.4rem,7vw,4.6rem); line-height:1.02;
  letter-spacing:-.035em; margin:1rem 0 0; color:var(--bone);
}
.pj-head__title em{ font-style:italic; color:var(--gold-2); }
.pj-head__lede{
  max-width:34rem; margin:1.8rem 0 0;
  font-size:clamp(1rem,1.7vw,1.15rem); line-height:1.7; color:var(--bone-dim);
}
.pj-meta{
  display:flex; flex-wrap:wrap; gap:.6rem 2.4rem;
  margin-top:clamp(2.4rem,5vw,3.4rem);
  padding-top:1.4rem; border-top:1px solid var(--line);
}
.pj-meta__item{ display:flex; flex-direction:column; gap:.3rem; }
.pj-meta__k{ font-size:.58rem; letter-spacing:.24em; text-transform:uppercase; color:var(--muted); }
.pj-meta__v{ font-size:.86rem; color:var(--bone); letter-spacing:.01em; }

/* ============================================================
   UNDER CONSTRUCTION — the two live sites, given room
   ============================================================ */
.pj-live{ padding-top:clamp(1rem,3vh,2rem); }
.pj-feature{
  max-width:64rem; margin:0 auto;
  display:grid; gap:clamp(2rem,5vw,4rem);
  grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  align-items:center;
}
.pj-feature + .pj-feature{ margin-top:clamp(4rem,9vh,7rem); }
.pj-feature--flip{ grid-template-columns:minmax(0,1fr) minmax(0,1.05fr); }
.pj-feature--flip .pj-feature__media{ order:2; }

.pj-feature__media{
  position:relative; border:1px solid var(--line); border-radius:3px;
  overflow:hidden; background:var(--ink-2);
  box-shadow:0 40px 90px -55px rgba(0,0,0,.9);
}
/* the stock stand-ins are landscape photographs, not elevations, so they fill
   the frame the way a photograph should */
.pj-feature__media--photo img{ object-fit:cover !important; }
/* contained, for the same reason as .pcard__img above */
.pj-feature__media img{
  display:block; width:100%; height:auto; aspect-ratio:4/5;
  object-fit:contain;
  filter:saturate(.9) brightness(.94);
  transition:filter 1.2s var(--ease);
}
.pj-feature__media:hover img{ filter:saturate(1) brightness(1); }
.pj-feature__media::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg,transparent 55%,rgba(6,13,28,.28) 78%,rgba(6,13,28,.8));
}

/* status flag, driven by the statusLabel in site.json */
.pj-flag{
  position:absolute; left:0; bottom:0; z-index:1; margin:1rem;
  font-size:.55rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-2);
  padding:.35rem .7rem; border:1px solid rgba(198,161,91,.4); border-radius:2px;
  background:rgba(6,13,28,.6); backdrop-filter:blur(3px);
}
/* STOCK PHOTOGRAPHY SAYS SO.
   Borivali and Sion have no renders yet and are carrying stock frames. Every
   one of them wears this, top right, so a placeholder is never read as the
   building. It comes off the day real imagery arrives, and not before. */
.pj-flag--note{
  left:auto; right:0; bottom:auto; top:0;
  color:var(--bone-dim); border-color:rgba(243,239,230,.24);
}

.pj-feature__where{
  display:inline-flex; align-items:center; gap:.7rem;
  font-size:.6rem; letter-spacing:.26em; text-transform:uppercase; color:var(--gold);
}
.pj-feature__where::before{ content:""; width:26px; height:1px; background:var(--gold); }
.pj-feature__name{
  font-weight:500; font-size:clamp(1.6rem,3.4vw,2.4rem); line-height:1.12;
  letter-spacing:-.025em; margin:.9rem 0 0; color:var(--bone);
}
.pj-feature__name span{ color:var(--muted); font-size:.55em; letter-spacing:0; }
.pj-feature__text{
  margin-top:1.3rem; color:var(--bone-dim); font-size:.95rem; line-height:1.78;
  max-width:30rem;
}

/* spec table */
/* stands in for .pj-open where there is no page to open yet */
.pj-feature__note{
  margin-top:1.6rem; font-size:.84rem; line-height:1.7;
  color:var(--muted); font-style:italic;
}
.pj-specs{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1.1rem 2rem; margin-top:1.9rem;
  padding-top:1.5rem; border-top:1px solid var(--line);
  max-width:30rem;
}
.pj-specs dt{
  font-size:.55rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--muted); margin-bottom:.35rem;
}
.pj-specs dd{ font-size:.9rem; color:var(--bone); letter-spacing:.01em; }

/* ============================================================
   COMPLETED — cream band, four cards
   ============================================================ */
.pj-grid{
  max-width:64rem; margin:0 auto;
  display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(1.4rem,3vw,2.2rem);
}
.pj-grid .pcard__img{ height:clamp(320px,36vw,440px); }
.pcard--static{ cursor:default; }
.pcard__status{
  margin-top:.55rem; display:inline-block;
  font-size:.55rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-2);
  padding:.3rem .6rem; border:1px solid rgba(198,161,91,.4); border-radius:2px;
}

/* the cards were written for the navy homepage; on the cream band they need
   their own ink, borders and hover, or they vanish into the background */
.sec-light .pcard__img{ border-color:rgba(6,13,28,.14); }
.sec-light .pcard__name{ color:var(--ink); }
.sec-light .pcard__meta{ color:#5a6478; }
.sec-light .pcard__status{ color:var(--gold-deep); border-color:rgba(138,106,47,.4); }
.sec-light .pcard--static:hover .pcard__img{ border-color:rgba(6,13,28,.14); }
.sec-light .pcard--static:hover .pcard__img img{ transform:scale(1.02); filter:saturate(.88) brightness(.92); }

.pj-note{
  max-width:64rem; margin:clamp(2.2rem,4vw,3rem) auto 0;
  font-size:.62rem; letter-spacing:.06em; color:#8a93a3; font-style:italic;
}

/* ============================================================
   CLOSE
   ============================================================ */
.pj-close__inner{ max-width:64rem; margin:0 auto; }
.pj-close__title{
  font-weight:500; font-size:clamp(1.6rem,3.4vw,2.4rem); line-height:1.16;
  letter-spacing:-.025em; margin:.9rem 0 0; color:var(--bone); max-width:22ch;
}
.pj-close__text{
  margin-top:1.1rem; max-width:32rem;
  color:var(--bone-dim); font-size:.95rem; line-height:1.75;
}
.pj-close__actions{ display:flex; flex-wrap:wrap; gap:.8rem; margin-top:2rem; }
.pj-disclaimer{
  max-width:64rem; margin:clamp(3.5rem,8vh,5.5rem) auto 0;
  padding-top:1.4rem; border-top:1px solid var(--line);
  font-size:.62rem; line-height:1.7; color:var(--muted);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width:900px){
  .pj-feature,
  .pj-feature--flip{ grid-template-columns:1fr; gap:1.8rem; }
  .pj-feature--flip .pj-feature__media{ order:0; }
  .pj-grid{ grid-template-columns:1fr; max-width:440px; }
}
@media (max-width:520px){
  .pj-specs{ gap:1rem 1.2rem; }
}

/* ============================================================
   TABS — Completed / Ongoing / Upcoming
   The tablist ships hidden and js/projects.js reveals it, so with JS off
   every panel stays visible and the page reads straight down.
   ============================================================ */
.pj-tabs-wrap{ padding:0 var(--gutter); }
.pj-tabs{
  max-width:64rem; margin:0 auto; display:flex; flex-wrap:wrap; gap:.4rem;
  padding-bottom:.9rem; border-bottom:1px solid var(--line);
}
.pj-tabs[hidden]{ display:none; }
.pj-tab{
  appearance:none; cursor:pointer;
  background:transparent; border:1px solid transparent; border-radius:2px;
  color:var(--muted); font-family:inherit;
  font-size:.68rem; letter-spacing:.2em; text-transform:uppercase;
  padding:.7rem 1.1rem;
  transition:color .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease);
}
.pj-tab:hover{ color:var(--bone-dim); }
.pj-tab[aria-selected="true"]{
  color:var(--gold-2); border-color:rgba(198,161,91,.45); background:rgba(198,161,91,.08);
}
.pj-tab:focus-visible{ outline:1px solid var(--gold); outline-offset:2px; }
.pj-panel[hidden]{ display:none; }
.pj-panel:focus{ outline:none; }
/* the tablist sits directly above the panel, so the panel's own top padding
   would double the gap */
.pj-panel{ padding-top:clamp(2.4rem,6vh,4rem); }

/* ============================================================
   ONGOING — cards now open a page of their own
   ============================================================ */
a.pj-feature__media{ display:block; }
.pj-feature__name a{ transition:color .3s var(--ease); }
.pj-feature__name a:hover{ color:var(--gold-2); }
.pj-feature__name a:focus-visible{ outline:1px solid var(--gold); outline-offset:3px; }
.pj-feature__media:focus-visible{ outline:1px solid var(--gold); outline-offset:3px; }
.pj-open{
  display:inline-flex; align-items:center; gap:.55rem; margin-top:1.7rem;
  font-size:.66rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-2);
  transition:color .3s var(--ease);
}
.pj-open span{ transition:transform .4s var(--ease); }
.pj-open:hover{ color:var(--gold); }
.pj-open:hover span{ transform:translateX(5px); }

/* ============================================================
   UPCOMING — one unnamed entry. No spec block belongs here.
   ============================================================ */
.pj-next__card{
  max-width:64rem; margin:0 auto;
  display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4rem); align-items:center;
}
.pj-next__media{
  position:relative; isolation:isolate; display:block;
  border:1px solid var(--line); border-radius:3px; overflow:hidden;
  background:var(--ink-2);
}
/* the only render we hold is low resolution, so it stays atmosphere rather
   than a product shot: softened, darkened, never sharp */
.pj-next__media img{
  display:block; width:100%; height:auto; aspect-ratio:1/1;
  object-fit:cover; filter:saturate(.6) brightness(.72) blur(2px); transform:scale(1.06);
}
.pj-next__veil{
  position:absolute; inset:0;
  background:
    radial-gradient(120% 90% at 50% 60%, rgba(6,13,28,0) 0%, rgba(6,13,28,.7) 72%, rgba(6,13,28,.93) 100%),
    linear-gradient(180deg, rgba(6,13,28,.5), rgba(6,13,28,.2) 45%, rgba(6,13,28,.86));
}
.pj-next__media:focus-visible{ outline:1px solid var(--gold); outline-offset:3px; }
/* A STOCK FRAME IS NOT THAT RENDER.
   The blur above exists because the one render we held was low resolution and
   had to stay atmosphere. A stock photograph is sharp and is labelled as
   stock, so it is shown, with only enough veil for the type to sit on. */
.pj-next__media--photo img{
  filter:saturate(.82) brightness(.92); transform:none;
}
.pj-next__media--photo .pj-next__veil{
  background:
    radial-gradient(120% 90% at 50% 55%, rgba(6,13,28,0) 0%, rgba(6,13,28,.34) 74%, rgba(6,13,28,.64) 100%),
    linear-gradient(180deg, rgba(6,13,28,.28), rgba(6,13,28,.06) 45%, rgba(6,13,28,.55));
}
.pj-next__label{
  font-weight:500; font-size:clamp(1.4rem,2.8vw,2rem); line-height:1.18;
  letter-spacing:-.022em; margin:.9rem 0 0; color:var(--gold-2); max-width:18ch;
}
.pj-next__label a{ transition:color .3s var(--ease); }
.pj-next__label a:hover{ color:var(--gold); }
.pj-next__label a:focus-visible{ outline:1px solid var(--gold); outline-offset:3px; }
.pj-next__text{
  margin-top:1.1rem; max-width:30rem;
  color:var(--bone-dim); font-size:.95rem; line-height:1.78;
}
/* the status reads as a flag on the media, the way every other card on this
   page carries one. As a loose chip in the body it shared a line with the CTA
   and read as a second, dead button sitting next to the live one. */
.pj-next__cta{ display:inline-flex; margin-top:1.8rem; }

@media (max-width:900px){
  .pj-next__card{ grid-template-columns:1fr; gap:1.8rem; }
  .pj-next__media img{ aspect-ratio:4/3; }
}
@media (max-width:520px){
  .pj-tabs{ gap:.2rem; }
  .pj-tab{ padding:.65rem .8rem; font-size:.62rem; letter-spacing:.16em; }
}

/* the panel itself carries a short entrance so the swap has a beat of its
   own; js/projects.js staggers the contents on top of it */
.pj-panel--enter{ animation:pjPanelIn .34s var(--ease) both; }
@keyframes pjPanelIn{
  from{ opacity:0; transform:translateY(8px); }
  to  { opacity:1; transform:none; }
}
@media (prefers-reduced-motion:reduce){
  .pj-panel--enter{ animation:none; }
}
