/*
 * blog.css — the public blog's index and article pages.
 *
 * Shared by templates/blog/list.html and templates/blog/detail.html, which
 * both render components/blog_card.html; keeping the card rules in one file
 * avoids two near-identical <style> blocks drifting apart.
 *
 * Sizes are in px, not rem: the theme sets `html { font-size: 10px }`
 * (CLAUDE.md), so rem values render at 62.5% of what a mockup intends.
 */

/* ---------------------------------------------------------------------
   Category badges
   ---------------------------------------------------------------------
   BlogCategory.COLOR_CLASS_CHOICES offers seven badge colours. Bootstrap 5
   ships five of them; `purple` and `orange` are not Bootstrap palette
   entries, so without these two rules a category set to either renders as
   an unstyled, invisible badge.
*/
.text-bg-purple {
    color: #fff;
    background-color: #6f42c1;
}

.text-bg-orange {
    color: #fff;
    background-color: #fd7e14;
}

/* ---------------------------------------------------------------------
   Category filter chips (index page)
   ---------------------------------------------------------------------
   The theme ships `.rbt-badge-2` as a static pill with no interactive
   states, so hover and the current selection are defined here.
*/
.blog-filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.blog-filter-chips .rbt-badge-2 {
    padding: 10px 20px;
    border-radius: 100px;
    font-size: 14px;
    line-height: 1.4;
    transition: all 0.3s ease-in-out;
}

.blog-filter-chips .rbt-badge-2:hover,
.blog-filter-chips .rbt-badge-2.is-active {
    background: var(--color-primary);
    color: var(--color-white);
    box-shadow: var(--shadow-1);
}

.blog-filter-chips .blog-filter-count {
    margin-left: 6px;
    opacity: 0.75;
}

.blog-active-tag {
    font-size: 14px;
}

/* While `blog_filters.js` is fetching a new list. Dimming rather than
   replacing with a spinner: the swap is one small request, and a skeleton
   that flashes for 80ms reads as a glitch. `pointer-events: none` stops a
   second click landing on links that are about to be replaced. */
#blog-results {
    transition: opacity 0.15s ease-in-out;
}

#blog-results.is-loading {
    opacity: 0.45;
    pointer-events: none;
}

/* ---------------------------------------------------------------------
   Card meta (date + reading time), on both pages
   --------------------------------------------------------------------- */
.rbt-card .rbt-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
    font-size: 13px;
    color: var(--color-body);
}

.rbt-card .rbt-meta li i {
    margin-right: 6px;
}

/* The compact horizontal card is short by design, so its meta row has to
   take less space than the grid card's. */
.rbt-card.card-list .rbt-meta {
    font-size: 12px;
    gap: 12px;
}

/* ---------------------------------------------------------------------
   Horizontal card height
   ---------------------------------------------------------------------
   The theme pins `.rbt-card.card-list` to `max-height: 150px`, sized for
   the mockup's content: a one-line title and a link, nothing else. Our
   card also carries a category badge and a meta row, so a title that wraps
   to three lines overflows the box — the text spills out and the next card
   (which sits `mt--30` below) lands on top of it.

   Letting the card grow is the fix rather than truncating the title: a
   headline is the one thing on a blog card that must never be cut. The
   `min-height` keeps a short-titled card from looking squashed next to a
   tall one, which is also what makes the column read as a little bigger.

   Scoped to `.blog-card` so nothing else that uses the theme's card-list
   shape is affected.
*/
.rbt-card.blog-card.card-list {
    max-height: none;
    min-height: 200px;
    /* The theme pairs its 150px cap with `height: 100%`, which only stayed
       sane because the cap clamped it. With the cap gone, `100%` resolves
       against the stretched column and every card claims the column's full
       height — three cards, each as tall as all three. It has to go back to
       content height. */
    height: auto;
}

/* The image is `height: 100%` in the theme, so it follows the taller card
   on its own; it only needs a floor so a short card keeps a sane crop. */
.rbt-card.blog-card.card-list .rbt-card-img a img {
    min-height: 200px;
}

/* 30px of padding on a now-taller card wastes the width the title needs. */
.rbt-card.blog-card.card-list .rbt-card-body {
    padding: 24px 26px;
}

/* Long headlines: wrap cleanly instead of pushing a long unbroken word
   past the card edge. */
.rbt-card.blog-card .rbt-card-title {
    overflow-wrap: break-word;
}

/* ---------------------------------------------------------------------
   Feature block: balance the two columns
   ---------------------------------------------------------------------
   The first row of the index is one feature card (left) beside three
   stacked list cards (right). Their heights are decided by completely
   different things — the left by one image plus a short body, the right by
   3 x 200px plus two 30px gaps — so the right column runs several hundred
   pixels taller and the row looks broken.

   The taller column wins, and the feature card grows to match it: the body
   keeps its natural height and the image absorbs the difference, cropping
   with `object-fit: cover` rather than distorting. That is also why the
   card does not carry the theme's `height-330` class any more — a 330px
   cap on the image is precisely what prevented this.

   Only from 992px up: `col-lg-6` is a single full-width column below that
   breakpoint, so there is nothing to balance and a stretched image would
   just be a very tall picture.
*/
@media only screen and (min-width: 992px) {
    .rbt-card.blog-card--feature {
        height: 100%;
        display: flex;
        flex-direction: column;
    }

    /* `min-height: 0` because a flex item defaults to `min-height: auto`,
       which refuses to shrink below its content and would let the image
       push the card past the column instead of fitting inside it. */
    .rbt-card.blog-card--feature .rbt-card-img {
        display: flex;
        flex: 1 1 auto;
        min-height: 0;
        overflow: hidden;
    }

    /* The theme wraps the image in an <a>. It is a child of the block
       above, not a flex item of the card, so `flex: 1` does nothing to it
       — it needs a plain `height: 100%` or the picture stays at its
       natural size and the extra space shows as a gap under it. */
    .rbt-card.blog-card--feature .rbt-card-img a {
        display: block;
        width: 100%;
        height: 100%;
    }

    /* `max-height: none` clears the theme's second cap: dropping the
       `height-330` class removed one (330px), but `.rbt-card.variation-02`
       imposes its own 350px, which leaves the picture floating in a taller
       box. `cover` is what makes the stretch safe — the image is cropped to
       fill, never scaled out of proportion. */
    .rbt-card.blog-card--feature .rbt-card-img a img {
        width: 100%;
        height: 100%;
        max-height: none;
        min-height: 330px;
        object-fit: cover;
        object-position: center;
    }

    /* The body is the fixed part of the pair: it must not be squeezed to
       make the image's sums work. */
    .rbt-card.blog-card--feature .rbt-card-body {
        flex: 0 0 auto;
    }
}

/* ---------------------------------------------------------------------
   Grid cards: equal height per row
   ---------------------------------------------------------------------
   Same root cause as the overflow above. A three-column row mixes
   one-line and three-line headlines, and because the card is only as tall
   as its content, the row ends up visibly ragged with the "Learn More"
   links at three different heights.

   The column already stretches (Bootstrap's default `align-items`), so
   the card only has to fill it, and the body becomes a flex column whose
   last row is pushed to the bottom. The feature card is excluded — it
   sits alone in its column beside the three stacked list cards, so
   stretching it to that column's height would leave a large empty gap
   under its text.
*/
.rbt-card.blog-card--grid {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.rbt-card.blog-card--grid .rbt-card-body {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.rbt-card.blog-card--grid .rbt-card-bottom {
    margin-top: auto;
}

/* Below 768px the theme already switches card-list to a stacked block with
   `height: auto`, so the floors above would only force dead space. */
@media only screen and (max-width: 767px) {
    .rbt-card.blog-card.card-list,
    .rbt-card.blog-card.card-list .rbt-card-img a img {
        min-height: 0;
    }
}

/* ---------------------------------------------------------------------
   Article page
   --------------------------------------------------------------------- */

/* The mockup puts a like button here; this page shows the read count
   instead, which needs the same alignment without the link styling. */
.blog-view-count {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--color-body);
}

/* Images inside an author-written body arrive at whatever size the source
   had, so they are constrained here rather than trusted to be sensible. */
.blog-content-wrapper .content img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
}

/* Hero. The global header is `.rbt-transparent-header` (absolute over
   <main>), so the wrapper reserves its height — the same 110px as
   includes/page_banner.html — and the band starts below it instead of
   running under the nav links. The theme's band is `top:-243px` and a
   `margin-top:120px` card; both are pulled in to fit the reserved gap. */
.rbt-overlay-page-wrapper.blog-detail {
    padding-top: 110px;
    box-shadow: none;
}
.blog-detail .breadcrumb-image-container {
    margin: 60px auto 0;
    box-shadow: var(--shadow-2);
}
.blog-detail .breadcrumb-image-container .blog-detail-band {
    top: -60px;
    bottom: auto;
    height: 320px;
    background: linear-gradient(
        270deg,
        rgba(40, 28, 92, 0.97) 0%,
        rgba(40, 28, 92, 0.8) 100%
    );
}
@media only screen and (max-width: 767px) {
    .rbt-overlay-page-wrapper.blog-detail {
        padding-top: 100px;
    }
    .blog-detail .breadcrumb-image-container {
        margin-top: 40px;
    }
    .blog-detail .breadcrumb-image-container .blog-detail-band {
        top: -40px;
        height: 240px;
        min-width: 0;
    }
}

/* The featured image, shown whole rather than cover-cropped. */
.blog-detail-featured {
    margin: 0 0 40px;
}
.blog-detail-featured img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 6px;
}

/* ---------------------------------------------------------------------
   Share row
   --------------------------------------------------------------------- */

/* Values in px, not rem: the theme's root font-size is 10px, so a rem
   figure copied from a 16px mockup renders at 62.5% of its intended size
   (CLAUDE.md).

   The circle, the border and the hover fill all come from the theme's
   `.social-default.transparent-with-border li a` rule. Nothing here
   redefines them — these rules only cover the two controls that rule
   cannot reach: an inline SVG (Zalo has no feather glyph) and a <button>
   (copy-link goes nowhere, so an <a href="#"> would only add a junk
   history entry). */

.social-icon .blog-share-zalo svg {
    vertical-align: middle;
    width: 18px;
    height: 18px;
}

/* The hover fill is the theme's ::after overlay, so the brand colour is
   set there — a `background-color` on the anchor would sit underneath it
   and never be seen. */
.social-default.transparent-with-border li .blog-share-zalo::after {
    background: #0068ff;
    border-color: #0068ff;
}

/* Match the anchor geometry exactly, then undo the button defaults the
   theme never had to deal with. */
.social-default li .blog-share-copy,
.social-default li .blog-share-instagram {
    width: 48px;
    height: 48px;
    line-height: 41px;
    padding: 0;
    text-align: center;
    display: inline-block;
    border-radius: 100%;
    background: transparent;
    border: 2px solid var(--color-border);
    color: var(--color-body);
    font: inherit;
    cursor: pointer;
    transition: 0.3s;
}

.social-default li .blog-share-copy:hover {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-white);
}

.social-default li .blog-share-instagram:hover {
    border-color: #e4405f;
    background: #e4405f;
    color: var(--color-white);
}

.social-default li .blog-share-copy:focus-visible,
.social-default li .blog-share-instagram:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.social-default li .blog-share-copy i,
.social-default li .blog-share-instagram i {
    vertical-align: middle;
}
