/* ==========================================================================
   Works — full portfolio archive grid (portfolio.html). A uniform grid
   (unlike the homepage teaser's asymmetric mosaic in css/portfolio.css),
   paired with the shared filter-pill component. Card interaction reuses the
   homepage's tuned visual recipe for the hover-reveal video preview + play
   button (same gradient/radius/SVG, same fixed-pixel centering that avoids
   the sub-pixel jitter bug), rebuilt here under its own .works__ namespace
   since the card/thumbnail geometry differs from the mosaic tiles.
   ========================================================================== */

.works {
  background: var(--color-bg);
  padding: var(--space-16) 0;
}

.works__filters {
  margin-bottom: var(--space-12);
}

/* align-items: start — see the identical note on .shop__grid in
   css/shop.css. Doesn't change anything visually here today (this card
   has no background of its own to reveal a stretched box), but makes the
   correct behavior explicit instead of accidental. */
.works__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
  gap: var(--space-8) var(--space-6);
}

/* Every card is a deterministic height at ANY width: a fixed-ratio 16:9
   thumbnail (below) plus a body whose tag/title/description all occupy a
   fixed number of lines (title and description are clamped to exactly two
   lines each, see below). That makes all cards in the grid identical
   height, so the vertical gap between rows is always just the grid's own
   row-gap — never inflated by a short card sitting higher than its
   neighbours. (Replaces the old fixed min-height:394px, which only matched
   the desktop card width and left uneven gaps once the cards got narrower.) */
/* Same semi-transparent box as a Shop product card / Blog post card
   (css/shop.css .shop__card) — image on top, title + short description
   below — just without a price or action button. The category tag is gone
   from the card face (it lives in the click-through modal instead). */
.works__card {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  overflow: hidden;
  cursor: pointer;
}

.works__trigger {
  display: block;
  position: relative;
  overflow: hidden;
  width: 100%;
}

.works__trigger::before {
  content: "";
  display: block;
  padding-bottom: 56.25%;
}

.works__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-base) var(--ease-standard);
}

.works__preview {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  transition: opacity 950ms var(--ease-standard);
}

.works__trigger:hover .works__preview,
.works__trigger:focus-visible .works__preview {
  opacity: 1;
}

.works__preview-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.works__shade {
  position: absolute;
  inset: 0;
  background: rgba(12, 6, 18, var(--shade-a, 0.78));
}

/* .works__play (+ its ::after glow and svg icon) is defined once in
   css/components.css, shared with the homepage's identical .portfolio__play. */

.works__body {
  padding: var(--space-4) var(--space-5) var(--space-5);
}

/* Category tag removed from the card face (per request) — it now shows in
   the click-through modal. Kept in the markup (harmless), just hidden. */
.works__tag {
  display: none;
}

/* Clamped to exactly two lines with a fixed height, so a 1-line title
   reserves the same space as a 2-line one and every card body is the same
   height. */
.works__title {
  font-size: 19px;
  line-height: 1.3;
  margin-bottom: var(--space-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  height: 2.6em;
}

.works__desc {
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--color-text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  height: 3.2em;
}

/* Column counts by width. The number of works shown per page follows this
   automatically (js/listing.js reads data-page-rows="2" on the listing and
   sets page size = 2 rows x current column count): 3 cols -> 6, 2 cols -> 4
   (2x2), 1 col -> 2 (top + bottom). Tablet is a 2x2 grid, mobile a single
   column (1x2). */
@media (max-width: 1100px) {
  .works__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Mobile: 2x2 grid of compact cards (smaller title/desc + tighter body). */
@media (max-width: 767px) {
  .works__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-5) var(--space-3);
  }
  .works__body {
    padding: var(--space-3) var(--space-3) var(--space-4);
  }
  .works__title {
    font-size: 15px;
  }
  .works__desc {
    font-size: 12px;
    -webkit-line-clamp: 2;
  }
}

/* --- Work modal: clicking a portfolio card opens this quote-modal-style
   panel (same transparent dark panel + backdrop-blur recipe as
   css/quote-modal.css) with the video on top, then the title and a short
   description. Driven by js/works-preview.js. --- */
.works-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none;
  align-items: safe center;
  justify-content: safe center;
  padding: var(--space-6);
  overflow-y: auto;
}

.works-modal:not([hidden]) {
  display: flex;
}

.works-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(2, 2, 3, 0.96);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-standard);
}

/* Column that holds the detached close button ABOVE the card, both fading +
   rising in together on open. Bounds the overall dialog height; the card
   inside scrolls if a description runs long. */
.works-modal__dialog {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 720px;
  max-height: calc(100vh - var(--space-12));
  opacity: 0;
  transform: translateY(24px) scale(0.97);
  transition: opacity var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}

.works-modal__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-6);
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.works-modal.is-visible .works-modal__backdrop {
  opacity: 1;
}

.works-modal.is-visible .works-modal__dialog {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* Square rounded button (same recipe as the header menu toggle), sitting
   as its OWN element above the card on the right — visually detached from
   the video/description panel (its own dark chip + a gap below it) rather
   than tucked inside the card's padding. */
.works-modal__close {
  align-self: flex-end;
  margin-bottom: var(--space-3);
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  background: var(--color-bg-elevated);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard);
}

.works-modal__close:hover {
  background: var(--color-bg-elevated-hover);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.works-modal__close svg {
  width: 18px;
  height: 18px;
}

.works-modal__video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #000;
}

.works-modal__video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.works-modal__title {
  margin-top: var(--space-5);
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--color-text);
}

.works-modal__desc {
  margin-top: var(--space-3);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* Mobile: smaller modal title + tighter panel padding. */
@media (max-width: 767px) {
  .works-modal__panel {
    padding: var(--space-4);
  }
  .works-modal__title {
    font-size: 17px;
  }
  .works-modal__desc {
    font-size: var(--fs-small);
  }
}

/* --- Closing CTA band (same treatment as the About page's .about-cta,
   under this page's own namespace so it stays self-contained). --- */
.works-cta {
  position: relative;
  background-color: #0a0a0d;
  padding-block: var(--space-16);
  text-align: center;
}

.works-cta__title {
  font-family: var(--font-heading);
  font-size: 26px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--color-text);
  max-width: 640px;
  margin-inline: auto;
}

.works-cta__text {
  margin: var(--space-5) auto 0;
  max-width: 520px;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--color-text-muted);
}

.works-cta__cta-wrap {
  display: inline-block;
  margin-top: var(--space-8);
}

/* Tablet/mobile: the section gets side padding so the heading/text no longer
   touch the screen edges, and the button spans the full work area (matches
   About). The wrap drops its own side padding — the section now provides it,
   so the button lines up with the padded heading instead of double-insetting. */
@media (max-width: 1024px) {
  .works-cta {
    padding-inline: var(--container-pad);
  }
  .works-cta__cta-wrap {
    display: block;
    width: 100%;
    max-width: var(--container-max);
    margin: var(--space-8) auto 0;
    padding-inline: 0;
  }
  .works-cta__cta-wrap .btn {
    width: 100%;
  }
}

