/* ============================================================
   Projects page. Grid transcribed from the projects.html mockup
   (1440px reference); the expanding detail panel is an addition
   for the real portfolio content.
   ============================================================ */

/* Title row - h1 sizing comes from .page-hero h1 in common.css */
.projects-head{display:flex;justify-content:space-between;align-items:flex-end;gap:44px}
.projects-meta{flex:none;font:400 15px/1.55 var(--font);color:var(--ink-2);text-align:right;animation:sm-rise .8s ease .28s both}

/* Filter chips */
.filters{display:flex;flex-wrap:wrap;gap:8px;margin-top:26px;animation:sm-rise .8s ease .34s both}
.filter{background:#fff;border:1px solid var(--border);border-radius:var(--r-pill);padding:10px 20px;font:500 13.5px var(--font);color:var(--ink-2);cursor:pointer;transition:background .25s,border-color .25s,color .25s}
.filter:hover{border-color:var(--indigo);color:var(--indigo)}
.filter.is-active{background:var(--indigo);border-color:var(--indigo);color:#fff;font-weight:600}
/* Long category names get a shorter chip label on narrow screens; see the
   .filter-short swap in the 760px block. */
.filter-short{display:none}

/* Grid of uniform tiles - keeps whole rows so the detail panel can be
   anchored to the end of a row without leaving holes. */
.projects-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;padding:32px max(56px,calc((100% - var(--content-w))/2)) 0;animation:sm-rise .85s ease .46s both}
.project-tile{position:relative;display:block;border-radius:var(--r-card);overflow:hidden;height:300px;box-shadow:var(--shadow-card);transition:box-shadow .3s}
.project-tile[hidden]{display:none}
.project-tile img{width:100%;height:100%;object-fit:cover;transition:transform .5s}
.project-tile:hover img{transform:scale(1.06)}
.project-tile-info{position:absolute;left:12px;right:12px;bottom:12px;display:flex;justify-content:space-between;align-items:center;gap:14px;background:rgba(255,255,255,.92);backdrop-filter:blur(6px);border-radius:12px;padding:12px 14px 12px 16px;pointer-events:none}
.project-tile-info strong{display:block;font:700 14.5px var(--font);color:var(--ink)}
.project-tile-info em{display:block;font:500 12px var(--font);font-style:normal;color:var(--orange);margin-top:2px}
.project-tile-chevron{flex:none;width:32px;height:32px;border-radius:50%;background:var(--indigo);color:#fff;display:grid;place-items:center;transition:transform .3s,background .25s}
.project-tile-chevron svg{width:16px;height:16px}
/* Full-tile hit area; the chevron is the visible affordance */
.project-open{position:absolute;inset:0;width:100%;background:none;border:0;padding:0;cursor:pointer}
.project-open:focus-visible{outline:3px solid var(--orange);outline-offset:-3px;border-radius:var(--r-card)}
.project-tile.is-open{box-shadow:0 0 0 3px var(--orange),var(--shadow-card)}
.project-tile.is-open .project-tile-chevron{transform:rotate(180deg);background:var(--orange)}
.projects-empty{grid-column:1/-1;padding:48px 0;text-align:center;font:400 15px var(--font);color:var(--ink-2)}

/* Detail panel. Parked in #projectPanels and moved into the grid by JS. */
.js .project-panel{display:none}
.project-panel{grid-column:1/-1;overflow:hidden;transition:height .45s ease}
.panel-inner{position:relative;display:grid;grid-template-columns:1.15fr .85fr;gap:32px;background:#fff;border:1px solid var(--border);border-radius:var(--r-card-lg);padding:26px}
/* contain, not cover: the source photos mix portrait, landscape and panorama,
   and cropping a tall building to a 16:10 box loses most of the subject.
   A blurred copy of the same image fills the letterbox. */
.panel-stage{position:relative;border-radius:14px;overflow:hidden;background:var(--bg-alt);aspect-ratio:16/10}
.panel-stage img{position:absolute;inset:0;width:100%;height:100%}
.panel-stage-bg{object-fit:cover;filter:blur(26px) saturate(1.15);transform:scale(1.18);opacity:.6}
.panel-stage-img{object-fit:contain}
.panel-thumbs{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}
.panel-thumb{width:88px;height:62px;padding:0;border:2px solid transparent;border-radius:10px;overflow:hidden;background:none;cursor:pointer;opacity:.7;transition:opacity .25s,border-color .25s}
.panel-thumb img{width:100%;height:100%;object-fit:cover}
.panel-thumb:hover{opacity:1}
.panel-thumb.is-active{opacity:1;border-color:var(--orange)}
.panel-info h2{margin:10px 0 0;font:700 26px/1.2 var(--font);letter-spacing:-.02em}
.panel-summary{margin-top:12px;font:400 14.5px/1.7 var(--font);color:var(--ink-2)}
.panel-specs{margin:22px 0 0}
.panel-specs>div{display:grid;grid-template-columns:112px 1fr;gap:16px;padding:10px 0;border-top:1px solid var(--border)}
.panel-specs dt{font:600 12.5px var(--font);color:var(--ink-3)}
.panel-specs dd{margin:0;font:500 13.5px/1.5 var(--font);color:var(--ink)}
.status-pill{display:inline-block;border-radius:var(--r-pill);padding:4px 12px;font:600 12px var(--font)}
.status-pill.is-done{background:var(--indigo-tint);color:var(--indigo)}
.status-pill.is-wip{background:#fdeeda;color:#b96a05}
.panel-cta{display:inline-block;margin-top:22px;font:600 13.5px var(--font);color:var(--orange);transition:color .25s}
.panel-cta:hover{color:var(--indigo)}
.panel-close{position:absolute;right:16px;top:16px;width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--border);border-radius:50%;background:#fff;color:var(--ink-2);cursor:pointer;transition:background .25s,color .25s,border-color .25s}
.panel-close svg{width:16px;height:16px}
.panel-close:hover{background:var(--indigo);border-color:var(--indigo);color:#fff}

/* No-JS fallback: the panels read as a plain list below the grid */
.project-panels{padding:0 max(56px,calc((100% - var(--content-w))/2))}
.project-panels .panel-inner{margin-bottom:20px}
.js .project-panels{padding:0}

/* Pagination */
.load-more-row{display:flex;justify-content:center;padding:32px max(56px,calc((100% - var(--content-w))/2)) 56px}
.load-more{background:none;border:1px solid #d8d6e6;border-radius:var(--r-pill);padding:13px 28px;font:600 14px var(--font);color:var(--indigo);cursor:pointer;transition:border-color .25s}
.load-more:hover{border-color:var(--indigo)}
.load-more[hidden]{display:none}

/* ---------- Responsive ---------- */
@media (max-width:1240px){
  .projects-grid{padding:28px 32px 0}
  .load-more-row{padding:28px 32px 40px}
  .panel-inner{gap:24px;padding:22px}
}
@media (max-width:1100px){
  .projects-grid{grid-template-columns:repeat(2,1fr)}
  /* Single column: the close button would land on the photo, so the panel gets
     a header strip of its own for it - and a 44px tap target with it. */
  .panel-inner{grid-template-columns:1fr;padding-top:64px}
  .panel-info h2{margin-top:0}
  .panel-close{right:14px;top:14px;width:44px;height:44px}
}
@media (max-width:760px){
  .projects-head{flex-direction:column;align-items:flex-start;gap:10px}
  .projects-meta{text-align:left}
  .projects-meta br{display:none}

  /* Chips become one edge-to-edge scrolling row instead of five stacked
     rows that push the first tile below the fold. */
  .filters{flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;
           -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity;
           margin:22px -20px 0;padding:0 20px 6px;scrollbar-width:none}
  .filters::-webkit-scrollbar{display:none}
  /* snap-align:center, not start: the script centres the chip it has just
     activated, so the snap points have to sit where the script scrolls to -
     with start alignment the proximity snap dragged the picked chip back
     against the right edge of the row. */
  .filter{flex:none;white-space:nowrap;padding:12px 18px;scroll-snap-align:center}
  .filter-full{display:none}
  .filter-short{display:inline}

  .projects-grid{grid-template-columns:1fr;padding:28px 20px 0}
  /* Tiles scale with the viewport instead of staying a fixed 260px that looks
     letterboxed at 320; the cap keeps them from becoming half-screen slabs just
     under the breakpoint. width:100% is required - an aspect-ratio box with a
     max-height otherwise shrinks its own width to keep the ratio. */
  .project-tile{width:100%;height:auto;aspect-ratio:4/3;max-height:300px}
  .panel-inner{padding:58px 18px 20px}
  .panel-close{right:12px;top:12px}
  /* Portrait and square sources waste most of a 16:10 box once the stage is
     only ~300px wide, so the box gets taller on a phone. */
  .panel-stage{aspect-ratio:4/3}
  /* Fixed-width thumbs wrapped into a ragged 3+1 block; a four-column grid
     always fills exactly one row. */
  .panel-thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;flex-wrap:nowrap;margin-top:10px}
  .panel-thumb{width:auto;height:auto;aspect-ratio:7/5}
  .panel-info h2{margin-top:14px}
  .panel-specs{margin-top:18px}
  .panel-specs>div{grid-template-columns:1fr;gap:3px;padding:12px 0}
  /* The panel's only call to action - as a plain link it was an 18px target */
  .panel-cta{display:block;margin-top:22px;padding:14px 20px;border:1px solid var(--border);
             border-radius:var(--r-pill);color:var(--indigo);text-align:center;font-size:14px}
  .load-more-row{padding:28px 20px 36px}
  .load-more{padding:15px 28px}
}
@media (max-width:560px){
  .panel-info h2{font-size:22px}
  .project-tile-info{left:10px;right:10px;bottom:10px;padding:11px 12px}
}
