/*
 * Releases hub-and-spoke styles — standalone plain CSS (no build step).
 * Hub body class: .post-type-archive-release  |  Spoke body class: .single-release
 *
 * This is a hand-written plain-CSS port of assets/scss/pages/_releases.scss.
 * SCSS variables/mixins are resolved to real values:
 *   $primary-base-color   -> var(--wp--preset--color--primary-base)
 *   $secondary-base-color -> var(--wp--preset--color--secondary-base)
 *   $neutral-dark-color   -> var(--wp--preset--color--neutral-dark)
 *   $neutral-white-color  -> var(--wp--preset--color--neutral-white)
 *   $timing-function      -> 0.4s ease-in-out
 *   $border-radius-50     -> 50px
 *   $box-shadow-medium    -> 0 4px 16px rgb(0 0 0 / 8%)
 *   media-custom-min(900px) -> @media (min-width: 900px)
 *   media-custom-max(900px) -> @media (max-width: 899.98px)
 *
 * The TOC JS gates its sticky/scroll-spy behaviour on matchMedia('(min-width: 900px)'),
 * so the desktop TOC layout below uses the same 900px breakpoint to stay consistent.
 */

/* ---------------------------------------------------------------------------
 * Spoke: two-column body layout (TOC rail + long-form content)
 * Req 9.2 (desktop 220px rail), 9.3 (mobile stack), 13.2 (single column mobile)
 * ------------------------------------------------------------------------- */

/* Constrain the two-column body to the site's wide container width and center
   it, so it aligns with the article head / rest of the page instead of going
   full-bleed (which pushed the TOC to the far-left screen edge). */
.single-release .gg-release-body {
  max-width: var(--wp--style--global--wide-size, 1112px);
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
  box-sizing: border-box;
}

/* Desktop: fixed-width TOC rail beside a flexible content column.
   The body stretches its columns to full row height (align-items: stretch)
   so the TOC column is as tall as the content column — this gives the sticky
   nav inside it room to travel as the page scrolls. */
@media (min-width: 900px) {
  .single-release .gg-release-body {
    display: flex;
    align-items: stretch;
    gap: 2.4rem;
    overflow: visible;
  }

  .single-release .gg-release-body .gg-release-toc-col {
    flex: 0 0 220px;
    width: 220px;
    max-width: 220px;
  }

  .single-release .gg-release-body .gg-release-content-col {
    flex: 1 1 auto;
    min-width: 0; /* allow long content/code to shrink instead of overflow */
    overflow: visible;
  }
}

/* Mobile: stack to a single column, TOC first/above the content, full width. */
@media (max-width: 899.98px) {
  .single-release .gg-release-body {
    display: block;
  }

  .single-release .gg-release-body .gg-release-toc-col,
  .single-release .gg-release-body .gg-release-content-col {
    width: 100%;
    max-width: 100%;
  }

  .single-release .gg-release-body .gg-release-toc-col {
    margin-bottom: 1.6rem;
  }
}

/* Suppressed-TOC state (JS adds this + removes the toc column when < 2 H2s).
   Req 9.5, 14.5 — content spans full width, no empty rail. */
.single-release .gg-release-body.gg-release-body--no-toc {
  display: block;
}

.single-release .gg-release-body.gg-release-body--no-toc .gg-release-toc-col {
  display: none;
}

.single-release .gg-release-body.gg-release-body--no-toc .gg-release-content-col {
  width: 100%;
  max-width: 100%;
  flex-basis: 100%;
}

/* ---------------------------------------------------------------------------
 * TOC list — a real vertical nav (list-style none, spacing).
 * Req 15.6 (screen-reader operable list), 9.6/13.4 (sticky desktop / static mobile)
 * ------------------------------------------------------------------------- */

/* Boxed panel styling (applies at all sizes) so the TOC reads as a distinct
   panel rather than a bare list. */
.single-release .gg-release-toc {
  background-color: var(--wp--preset--color--neutral-very-light, #f5f6fb);
  padding: 1.6rem;
  border-radius: 8px;
}

/* Sticky on desktop only. The nav sits at the top of a full-height (stretched)
   column, so it sticks and travels as the content column scrolls. Sticky also
   needs a non-clipping ancestor chain: overflow: visible on the body and
   content column (set above) keeps position: sticky from being disabled. */
@media (min-width: 900px) {
  .single-release .gg-release-toc {
    position: sticky;
    top: 100px; /* clears the fixed header while scrolling */
    /* Long TOCs scroll internally so the panel never exceeds the viewport. */
    max-height: calc(100vh - 120px);
    overflow-y: auto;
  }
}

/* Static (non-sticky) on mobile. */
@media (max-width: 899.98px) {
  .single-release .gg-release-toc {
    position: static;
    top: auto;
  }
}

.single-release .gg-release-toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.single-release .gg-release-toc li {
  margin: 0;
  padding: 0;
}

.single-release .gg-release-toc a {
  display: block;
  padding: 0.7rem 1rem;
  font-size: 15px !important;
  color: var(--wp--preset--color--neutral-dark);
  text-decoration: none;
  /* Non-color active affordance baseline: a transparent left border that
     becomes visible on the active entry (see .is-active below). */
  border-left: 3px solid transparent;
  transition: color 0.4s ease-in-out, border-color 0.4s ease-in-out;
}

.single-release .gg-release-toc a:hover {
  color: var(--wp--preset--color--primary-base);
}

/* Active entry — MUST NOT rely on colour alone (Req 15):
   combine a colour change WITH a visible left border and heavier weight. */
.single-release .gg-release-toc a.is-active,
.single-release .gg-release-toc a[aria-current='location'] {
  color: var(--wp--preset--color--primary-base);
  font-weight: 700;
  border-left-color: var(--wp--preset--color--primary-base);
}

/* Visible focus indicator, >= 3:1 contrast (Req 15.3). */
.single-release .gg-release-toc a:focus-visible {
  outline: 2px solid var(--wp--preset--color--primary-base);
  outline-offset: 2px;
}

/* Mobile touch targets >= 44px (Req 13.6, 15). */
@media (max-width: 899.98px) {
  .single-release .gg-release-toc a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

/* ---------------------------------------------------------------------------
 * Back-to-top control (shown by the TOC JS on 10+ H2 sections).
 * Scoped to the spoke. Req 9.10/9.11, 15.3 (focus), 13.6 (touch target).
 * ------------------------------------------------------------------------- */
.single-release .gg-back-to-top {
  position: fixed;
  right: 1.6rem;
  bottom: 1.6rem;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  color: var(--wp--preset--color--neutral-white);
  background-color: var(--wp--preset--color--secondary-base);
  border: 0;
  border-radius: 50px;
  box-shadow: 0 4px 16px rgb(0 0 0 / 8%);
  cursor: pointer;
  /* Hidden until JS toggles .active after scrolling past the first H2. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s ease-in-out, visibility 0.4s ease-in-out;
}

.single-release .gg-back-to-top.active {
  opacity: 1;
  visibility: visible;
}

.single-release .gg-back-to-top:focus-visible {
  outline: 2px solid var(--wp--preset--color--neutral-white);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Read-time label wrapper (shortcode output).
 * ------------------------------------------------------------------------- */
.gg-release-read-time,
.gg-post-banner__read-time {
  display: inline-block;
  color: var(--wp--preset--color--neutral-dark);
}

/* ---------------------------------------------------------------------------
 * Center the single-page article head (date + byline) to match the centered
 * title. The post title is already center-aligned, but the meta/byline row
 * defaults to flex-start (left), which looks inconsistent. Scoped to the spoke.
 * ------------------------------------------------------------------------- */
.single-release .gg-post-banner__meta {
  justify-content: center;
  text-align: center;
}

.single-release .gg-post-banner__author-data {
  justify-content: center;
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * Mobile: reduce section vertical padding 48px -> 20px, scoped to release
 * hub + spoke so other templates are unaffected. Desktop keeps theme default.
 * Req 13.5
 * ------------------------------------------------------------------------- */
@media (max-width: 899.98px) {
  .post-type-archive-release .wp-block-group.has-section-padding,
  .post-type-archive-release .wp-block-cover.has-section-padding,
  .single-release .wp-block-group.has-section-padding,
  .single-release .wp-block-cover.has-section-padding {
    padding-top: 20px;
    padding-bottom: 20px;
  }
}

/* ---------------------------------------------------------------------------
 * Mobile touch targets >= 44px for card + CTA links (Req 13.6, 15).
 * ------------------------------------------------------------------------- */
@media (max-width: 899.98px) {
  .post-type-archive-release .gravity-block-dynamic-boxes a,
  .post-type-archive-release .wp-block-button__link {
    min-height: 44px;
  }
}

/* ---------------------------------------------------------------------------
 * Brand-tinted fallback for missing featured images (Req 6.10, 8.4, 14.4).
 * Defensive: acf/dynamic-boxes may already render a fallback; this ensures any
 * empty image wrapper shows a solid brand tint rather than a blank area.
 * ------------------------------------------------------------------------- */
.post-type-archive-release .gravity-block-dynamic-boxes__feature-image:not(:has(img)),
.single-release .gravity-block-dynamic-boxes__feature-image:not(:has(img)) {
  background-color: var(--wp--preset--color--secondary-base);
  aspect-ratio: 16 / 9;
}

/* On the spoke, an empty featured image should collapse (no tinted band).
   The article-head featured image lives in the share row; when absent it must
   not reserve space. */
.single-release .wp-block-post-featured-image:not(:has(img)) {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Reduced-motion: disable CSS transitions on interactive TOC + back-to-top.
 * (JS also honours prefers-reduced-motion for scroll behaviour.)
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .single-release .gg-release-toc a,
  .single-release .gg-back-to-top {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * Releases hub hero — eyebrow pill + accent-italic headline + cream bg.
 * Matches the Studio Designer "What's New" mockup. Fonts already loaded on the
 * site: Montserrat (headline) + Playfair Display italic (the "New" accent).
 * ------------------------------------------------------------------------- */

/* Eyebrow pill */
.post-type-archive-release .gg-release-eyebrow {
  display: inline-block;
  margin: 0 auto 24px;
  padding: 7px 16px;
  background-color: #fbd9ce;
  color: #ff5c39;
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  line-height: 1;
}

/* Make the eyebrow center as an inline-block pill (it's a centered paragraph) */
.post-type-archive-release .gg-hero-logo {
  text-align: center;
}

/* The cursive accent word ("New") in the H1 */
.post-type-archive-release .gg-release-hero-title .gg-release-accent {
  font-family: 'Playfair Display', serif;
  font-style: italic;
  font-weight: 500;
  color: #ff5c39;
}

/* Hub grid cards — center the date, title, and read-more within each card.
   The card + content wrapper are flex columns; align-items: center centers the
   child boxes horizontally, and text-align/justify-content center their text. */
.post-type-archive-release .gravity-block-dynamic-boxes__box,
.post-type-archive-release .gravity-block-dynamic-boxes__group-wrapper,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__box,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__group-wrapper {
  align-items: center;
  text-align: center;
}

.post-type-archive-release .gravity-block-dynamic-boxes__date,
.post-type-archive-release .gravity-block-dynamic-boxes__title,
.post-type-archive-release .gravity-block-dynamic-boxes__read-more,
.post-type-archive-release .gravity-block-dynamic-boxes__date .date,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__date,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__title,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__read-more,
.single-release .gg-latest-from-sd .gravity-block-dynamic-boxes__date .date {
  text-align: center;
  justify-content: center;
  width: 100%;
}

/* ---------------------------------------------------------------------------
 * Hub hero paragraph/heading — the gg-text-max-width-632 class constrains the
 * width but doesn't auto-center the block. Auto margins center it in the hero.
 * ------------------------------------------------------------------------- */
.post-type-archive-release .gg-hero-logo .gg-text-max-width-632 {
  margin-left: auto;
  margin-right: auto;
}

/* ---------------------------------------------------------------------------
 * Article-head share row: if the article-head featured image is empty/absent,
 * don't let it reserve space and create a gap next to the share icons.
 * ------------------------------------------------------------------------- */
.single-release .gg-post-banner__author-and-share .wp-block-post-featured-image:not(:has(img)) {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Related "More Releases" grid: go 2-up on tablet, 1-up on phones so cards
 * are never cropped. The grid container is a CSS grid; override its columns.
 * ------------------------------------------------------------------------- */
@media (max-width: 1024px) {
  .single-release .gg-latest-from-sd .gravity-block-dynamic-boxes--grid-view.gravity-block-grid-3-col {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 680px) {
  .single-release .gg-latest-from-sd .gravity-block-dynamic-boxes--grid-view.gravity-block-grid-3-col {
    grid-template-columns: 1fr;
  }
}

/* Flexbox fallback: the grid may be implemented with flexbox rather than CSS
   grid. Override the card boxes' flex-basis to cover both implementations. */
@media (max-width: 1024px) {
  .single-release .gg-latest-from-sd .gravity-block-grid-3-col .gravity-block-dynamic-boxes__box {
    flex: 0 0 calc(50% - 1rem);
    max-width: calc(50% - 1rem);
  }
}

@media (max-width: 680px) {
  .single-release .gg-latest-from-sd .gravity-block-grid-3-col .gravity-block-dynamic-boxes__box {
    flex: 0 0 100%;
    max-width: 100%;
  }
}
