/* Cardonal — practice areas grid
   §0by: the card no longer flips. The image is scaled up at rest and zooms
   out to its true size on hover, and the description fades up as it settles.
   Below 768px there is no hover, so everything is shown outright. */
.c-pgrid--ruled { border-top: 1px solid var(--c-line-hairline); }
.c-pgrid__inner {
  display: flex; flex-direction: column; gap: var(--c-space-48);
  padding-left: var(--c-margin); padding-right: var(--c-margin);
}
.c-pgrid__eyebrow {
  margin: 0; font-family: var(--c-font-heading); font-size: var(--c-size-label-lg);
  font-weight: var(--c-weight-label); line-height: var(--c-lh-label);
  letter-spacing: var(--c-ls-label-lg); text-transform: uppercase;
  color: var(--surface-muted);
}
.c-pgrid__grid { display: grid; gap: var(--c-space-32); }
.c-pgrid__grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.c-pgrid__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* --- The card ------------------------------------------------------------
   §0by — zoom-out reveal. At rest the image is scaled up and cropped, the
   wash is light, and the card shows its numeral and title. On hover the
   image settles back to 1 — reading as a zoom OUT — the wash deepens, and
   the description fades up underneath the title.

   Why scale-down-to-1 rather than scale-up-on-hover: zooming out is what was
   asked for, and it also means the resting state is the only one that
   crops the photograph. The image never renders below its natural size, so
   it cannot go soft.

   `transform-origin: center` plus the frame's `overflow: hidden` keeps the
   crop centred through the whole movement. */
.c-pgrid__card {
  display: block;
  height: var(--pgrid-h);
  text-decoration: none;
}

.c-pgrid__frame {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: var(--c-surface-deep);
}

.c-pgrid__img {
  position: absolute; inset: 0; display: block;
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.14);
  transform-origin: center center;
  transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
}
.c-pgrid__card:hover .c-pgrid__img,
.c-pgrid__card:focus-visible .c-pgrid__img { transform: scale(1); }

.c-pgrid__note {
  position: absolute; inset: 0; display: flex; align-items: flex-start;
  justify-content: center; padding: var(--c-space-16) var(--c-space-24);
  background-color: var(--c-surface-placeholder);
  border: 1px dashed var(--c-line-hairline-strong);
  font-family: var(--c-font-body); font-size: var(--c-size-caption);
  line-height: var(--c-lh-caption); text-align: center; color: var(--c-text-muted);
}

/* The wash is the design's own opacity value at rest; it deepens on hover so
   the description, which lands over a busier part of the crop once the image
   settles, stays readable. */
.c-pgrid__wash {
  position: absolute; inset: 0;
  background-color: var(--c-surface-deep); opacity: 0.68;
  transition: opacity 620ms cubic-bezier(0.22, 1, 0.36, 1);
}
.c-pgrid__card:hover .c-pgrid__wash,
.c-pgrid__card:focus-visible .c-pgrid__wash { opacity: 0.82; }

/* §0cb — NO FLEX `gap` HERE, DELIBERATELY. The collapsing description has to
   be able to cost literally nothing at rest, and a flex `gap` is charged
   whether or not the item between has any height — a zero-height wrapper
   still left 24px between the title and READ instead of 12px. The spacing is
   therefore explicit margins on the items that always have height. */
.c-pgrid__content {
  position: absolute; right: var(--c-space-32); bottom: var(--c-space-32); left: var(--c-space-32);
  display: flex; flex-direction: column;
}
.c-pgrid__title { margin-top: var(--c-space-12); }
.c-pgrid__read { margin-top: var(--c-space-12); }
.c-pgrid__numeral, .c-pgrid__read {
  font-family: var(--c-font-heading); font-size: var(--c-size-label-sm);
  font-weight: var(--c-weight-label); line-height: var(--c-lh-label);
  letter-spacing: var(--c-ls-label-sm); text-transform: uppercase;
}
.c-pgrid__numeral { color: var(--c-accent-gold-light); }
.c-pgrid__read { color: var(--c-text-on-deep); }
.c-pgrid__title {
  font-family: var(--c-font-heading); font-size: var(--c-size-h3);
  font-weight: var(--c-weight-h3); line-height: var(--c-lh-h3);
  color: var(--c-text-on-deep);
}

/* §0cb — THE DESCRIPTION TAKES NO SPACE UNTIL IT IS SHOWN.
   Client: "default ye content ka space nahi rahega, jaise pehle tha waisa
   rahega, aur hover me wo text aayega."

   The first pass hid it with `opacity: 0` alone, which leaves the element in
   the layout — so the card reserved three lines of empty space between the
   title and READ and looked broken at rest. It now collapses to zero height
   and grows on hover.

/* The collapse is `max-height` on a clipper, NOT the `grid-template-rows:
   0fr -> 1fr` trick. That trick is the tidier one and it was tried first —
   it collapsed correctly but never reopened: measured on the live page, the
   `1fr` track resolved to `0px`, because this grid sits inside an
   absolutely-positioned, content-sized column where the free space an `fr`
   resolves against is indefinite. `max-height` has no such dependency.

   The cost of `max-height` is the magic number: it must be comfortably
   larger than the tallest description (the longest here measures 204px at
   desktop width, and more on a narrow card), and the ease runs against that
   number rather than the real height, so the growth finishes slightly before
   the transition does. The opacity fade covers that, and a card that opens a
   little early beats one that never opens at all.

   If a description is ever long enough to be cut off, raise this value — it
   is the only thing holding the height. */
.c-pgrid__desc-wrap { display: block; }

.c-pgrid__desc-clip {
  display: block;
  max-height: 0;
  overflow: hidden;
  transition: max-height 520ms cubic-bezier(0.4, 0, 0.2, 1);
}
.c-pgrid__card:hover .c-pgrid__desc-clip,
.c-pgrid__card:focus-visible .c-pgrid__desc-clip { max-height: 18rem; }

/* The 12px of space above the text lives INSIDE the clipper, so it appears
   with the text and vanishes with it. It cannot be a margin on the wrapper
   or a `gap` on `.c-pgrid__content` — either would be charged at rest, which
   is the gap the client asked to remove. */
/* §0cc — THE CEILING AND THE CURVE ARE WHAT MAKE THIS READ AS MOTION.
   Client: "vo abhi bina animation ke aa raha hai … thoda smooth ho jaye."

   The transition was already declared and shipping correctly — the problem
   was the numbers. `max-height` eases towards the CEILING, not towards the
   content's real height, so with a 26rem (416px) ceiling and a ~204px
   description the visible growth was over in the first third of the
   duration. A strong ease-out (`cubic-bezier(0.22, 1, 0.36, 1)`) made that
   worse by front-loading almost all the distance into the first 150ms — so
   it read as a snap, exactly as reported.

   Two changes, and they only work together:
   - the ceiling drops to 18rem (288px), close enough to the real height that
     most of the range is distance the eye actually sees;
   - the curve becomes a symmetrical ease (`cubic-bezier(0.4, 0, 0.2, 1)`),
     which spreads that distance evenly across the 520ms instead of spending
     it immediately.

   18rem is the safety margin: if a description ever renders taller than
   288px it will be clipped, and this value is the only thing holding it.
   The longest here measures 204px at desktop width.

   The text also rises 6px as it fades, and its fade now runs WITH the growth
   rather than 100ms behind it — a delay on top of an already-fast opening
   was the other half of why it felt abrupt. */
.c-pgrid__desc {
  display: block;
  padding-top: var(--c-space-12);
  font-family: var(--c-font-body); font-size: var(--c-size-small);
  line-height: var(--c-lh-small); color: var(--c-text-on-deep);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 460ms cubic-bezier(0.4, 0, 0.2, 1),
              transform 460ms cubic-bezier(0.4, 0, 0.2, 1);
}
.c-pgrid__card:hover .c-pgrid__desc,
.c-pgrid__card:focus-visible .c-pgrid__desc { opacity: 1; transform: none; }

@media (max-width: 1023px) {
  .c-pgrid__grid--3, .c-pgrid__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* --- Phone: no flip, everything visible -----------------------------------
   Below 768px there is no hover, so the flip is disabled and the back face
   (the one carrying the description) is shown outright in normal flow.

   THE BUG THIS FIXES (§0bi): `.c-pgrid__content` was set to
   `position: static` here while `.c-pgrid__img` and `.c-pgrid__wash` stayed
   `position: absolute`. In CSS painting order a positioned sibling with
   `z-index: auto` paints ABOVE non-positioned in-flow content, so the text
   was being rendered and then buried under the photograph and its tint —
   the cards read as image-only. On desktop the same markup works because
   the content is absolute there too and comes later in the DOM.

   The content is therefore `position: relative; z-index: 1` rather than
   static: still in flow (so it gives the card its height, which is the
   point of the mobile treatment), but painted above the image. */
/* --- Phone: no hover, so everything is shown -----------------------------
   A touch screen has no hover state, so the description is simply visible
   and the image sits at its true size. The card grows to fit its content
   instead of holding the desktop's fixed height.

   THE BUG THIS STILL GUARDS AGAINST (§0bi): `.c-pgrid__content` was once
   `position: static` here while the image and wash stayed absolute. A
   positioned sibling with `z-index: auto` paints ABOVE non-positioned
   in-flow content, so the text rendered and was then buried under the
   photograph — the cards read as image-only. Hence `relative` + `z-index: 1`
   rather than static: still in flow, so it gives the card its height, but
   painted above the image. And `inset: auto` is essential, not tidiness —
   the desktop rule's `right/bottom/left: 32px` offsets are still in effect,
   and on a RELATIVE box an offset SHIFTS the element rather than anchoring
   it, which pushed the content 32px up and 32px right. */
@media (max-width: 767px) {
  .c-pgrid__grid--3, .c-pgrid__grid--2 { grid-template-columns: minmax(0, 1fr); }
  .c-pgrid__card { height: auto; }
  .c-pgrid__frame {
    height: auto;
    min-height: 320px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }
  .c-pgrid__img { transform: none; transition: none; }
  /* Deepened from the design's 0.68: at phone size the type sits over a
     smaller, busier crop and 0.68 left the lighter passages competing with
     the copy. */
  .c-pgrid__wash { z-index: 0; opacity: 0.82; transition: none; }
  .c-pgrid__content {
    position: relative; z-index: 1;
    inset: auto;
    padding: var(--c-space-32);
  }
  /* No hover on a touch screen, so the description is simply open: the row
     is at its natural height and nothing transitions. */
  .c-pgrid__desc-clip { max-height: none; transition: none; }
  .c-pgrid__desc { opacity: 1; transform: none; transition: none; }
}
/* Respect a reduced-motion preference: the reveal still happens on hover,
   it just happens instantly and without the zoom. */
@media (prefers-reduced-motion: reduce) {
  .c-pgrid__img { transform: none; transition: none; }
  .c-pgrid__wash, .c-pgrid__desc, .c-pgrid__desc-clip { transition: none; }
}
