/* ==========================================================================
   Archive card
   The ONE listing card: Blog Hub, every Post archive, the Projects Hub, every
   projects taxonomy archive, and the Related Projects carousel on a Project.
   Loaded by uq_hub_card_assets() (inc/hub.php).
   ==========================================================================

   WHY THIS FILE EXISTS AT ALL

   The hub cards used to BE the Related Articles / Related Projects carousel
   cards -- the grid borrowed .uq-blog-related__* and .uq-related-projects__*
   wholesale. The client's direction is that the archive card should follow the
   Quo archive reference instead:

       image  ->  small meta/date  ->  title  ->  small identity row

   with the image dominant, no card box, no shadow and no border. That is a
   different card from the carousel card, so it is a different component --
   .uq-hub-card -- rather than a second set of overrides fighting the first.

   Two consequences, both deliberate:

     - RELATED ARTICLES IS UNTOUCHED. It keeps its own card, now drawn by
       template-parts/blog/related-article-card.php, and its CSS in css/blog.css
       is not modified by one byte. The client has a separate design coming for
       it.

     - RELATED PROJECTS ADOPTS THIS CARD. The client asked for exactly one
       Project card language, so the carousel renders .uq-hub-card too. Only the
       card changed: the track, the viewport, the arrows, the peek, the manual
       selection and js/related-projects.js are all untouched, which is why this
       sheet also loads on a single Project.

   WHERE THE VALUES COME FROM

   Layout rhythm is the Quo archive reference, measured from the page itself
   (.article-grid__article):

       image -> text          20px   (24 at <=767, 16 at <=479)
       text block rows        12px
       date -> title           8px
       image                  object-fit: cover; aspect-ratio: 16 / 9
       author avatar          26px, 1 / 1, beside the name at 8px

   Media corners are ROUNDED at 10px, via --uq-hc-radius below. The image IS the
   Project card's only surface -- the card itself has no background, no border
   and no shadow -- so "Project cards rounded corners like the rest" is a radius
   on the media and nothing else. 10px is the same value the Blog panel beside
   it uses and the same one the Service card, the Why Choose Us card, the Service
   Comparison column card and Project Details' --uq-pd-card-radius all measure.
   Still scoped to this component: no global token changes, and every other
   rounded surface on the site is untouched.

   Everything else is Roofer On Demand's: --uq-site-font-heading (Roobert) for
   the title, --uq-site-font-body (Inter) for the meta and the identity row, and
   --uq-theme-primary for focus. No new colour, and no new type scale --
   22 / 20 / 18px is the ladder the site's card titles already walk.
*/

.uq-hub-card {
    /* Image -> text. */
    --uq-hc-gap: 20px;
    /* Text block -> identity row. */
    --uq-hc-body-gap: 12px;
    /* Date -> title. */
    --uq-hc-text-gap: 8px;

    --uq-hc-media-ratio: 16 / 9;
    /* SQUARE. The first pass rounded the media to the site's 10px card radius;
       the client's note is that the reference archive squares its media blocks
       off and the hub should too.

       Scoped to this component only -- no global radius token is touched, and
       the Blog Header hero, the Project gallery, the CTA card, Related Articles
       and every other rounded surface on the site keep the radius they have. */
    /* The media radius, and its ONLY consumer is .uq-hub-card__media below --
       nothing else in the theme reads this token. The Blog panel carries its own
       border-radius and has no media element at all, so this value cannot reach
       it. The wrapper already has overflow: hidden for the hover scale, so the
       image is clipped to the corners with no further rule. */
    --uq-hc-radius: 10px;
    /* NOT a border. The reference has none, and the client asked for no heavy
       box: this is the ground behind a transparent or still-loading image, so a
       card is never a white hole. */
    --uq-hc-media-bg: #eef1f4;

    --uq-hc-title-size: 22px;
    /* A heading, so darker than the --uq-theme-text body grey. */
    --uq-hc-title-color: #111111;
    --uq-hc-meta-size: 14px;
    /* 4.54:1 on white -- the smallest text on the card clears WCAG AA. */
    --uq-hc-meta-color: #767676;
    --uq-hc-identity-color: #111111;
    --uq-hc-avatar-size: 26px;
    --uq-hc-accent: var(--uq-theme-primary, #104E8B);

    display: flex;
    box-sizing: border-box;
    width: 100%;
    /* Fills its grid cell / carousel slot, so every card in a row shares a
       baseline for its identity row (see margin-top: auto below). */
    height: 100%;
    min-width: 0;
    flex-direction: column;
}

.uq-hub-card *,
.uq-hub-card *::before,
.uq-hub-card *::after {
    box-sizing: border-box;
}

/* The whole card is one link. No box, no border, no shadow: the image is the
   card, and the text sits bare underneath it. */
.uq-hub-card__link {
    display: flex;
    width: 100%;
    height: 100%;
    flex-direction: column;
    gap: var(--uq-hc-gap);
    color: inherit;
    /* Beats the global `a { font-weight: 600 }`. */
    font-weight: 400;
    text-decoration: none;
}

.uq-hub-card__link:focus-visible {
    outline: 2px solid var(--uq-hc-accent);
    outline-offset: 4px;
}

/* ---------- Image ---------- */
.uq-hub-card__media {
    display: block;
    width: 100%;
    /* aspect-ratio rather than a height: the card holds its final size before
       the lazy image arrives, so a grid page loads with no layout shift, and
       every card in every row keeps the same proportion at every width. */
    aspect-ratio: var(--uq-hc-media-ratio);
    overflow: hidden;
    border-radius: var(--uq-hc-radius);
    background: var(--uq-hc-media-bg);
}

.uq-hub-card__image {
    display: block;
    width: 100%;
    height: 100%;
    /* cover, so a portrait and a panorama fill the same frame instead of
       letterboxing and breaking the row's rhythm. */
    object-fit: cover;
    object-position: center;
    transition: transform 420ms cubic-bezier(0.4, 0, 0.2, 1);
}

.uq-hub-card__link:hover .uq-hub-card__image {
    transform: scale(1.03);
}

/* ---------- Text ---------- */
.uq-hub-card__body {
    display: flex;
    min-width: 0;
    /* Takes the leftover height, which is what lets the identity row sit on the
       card's bottom edge. */
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--uq-hc-body-gap);
}

.uq-hub-card__text {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: var(--uq-hc-text-gap);
}

.uq-hub-card__meta {
    display: block;
    min-width: 0;
    color: var(--uq-hc-meta-color);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
    font-size: var(--uq-hc-meta-size);
    font-weight: 400;
    line-height: 1.4;
}

/* NOT clamped. The brief asks for titles that wrap naturally, and the reference
   does the same; cards still align because the card is height: 100% and the
   identity row holds margin-top: auto, so a one-line title makes a taller gap,
   never a shorter card. */
.uq-hub-card__title {
    display: block;
    min-width: 0;
    /* This is a <span>: the card's whole clickable area is one <a>, and a real
       heading inside a link on every card would add nothing to the outline. A
       <span> is not in the :root `h1..h6 { font-family: ... !important }` list,
       so the heading face is declared here -- the same reason the two carousel
       card titles declare it. */
    font-family: var(--uq-site-font-heading, Arial, sans-serif);
    font-size: var(--uq-hc-title-size);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--uq-hc-title-color);
    /* The title, not the line, is what breaks. */
    overflow-wrap: anywhere;
}

.uq-hub-card__link:hover .uq-hub-card__title {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ---------- Identity row ----------
   The reference's author row: a 26px round avatar and a name. The Project card
   puts a location pin and a place in the same slot, so the two grids share one
   rhythm rather than two. */
.uq-hub-card__identity {
    display: flex;
    margin-top: auto;
    gap: 8px;
    align-items: center;
    min-width: 0;
    color: var(--uq-hc-identity-color);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
    font-size: var(--uq-hc-meta-size);
    font-weight: 500;
    line-height: 1.4;
}

.uq-hub-card__avatar {
    display: inline-flex;
    flex: 0 0 auto;
    width: var(--uq-hc-avatar-size);
    height: var(--uq-hc-avatar-size);
    overflow: hidden;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--uq-hc-media-bg);
}

/* get_avatar() emits its own <img class="avatar">; sized here rather than by
   asking WordPress for a fixed pixel size, so a retina file still fits. */
.uq-hub-card__avatar img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
}

/* The pin, where a Blog card has an avatar. Brand blue, like every other pin
   on the site. */
.uq-hub-card__pin {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    color: var(--uq-hc-accent);
}

.uq-hub-card__pin svg {
    display: block;
    width: 12px;
    height: 14px;
}

.uq-hub-card__identity-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ==========================================
   The Blog archive card -- A TEXT PANEL, NO IMAGE
   Drawn by template-parts/hub/blog-card.php
   ==========================================
   The client's direction changed for this card and only this card: "no
   thumbnails for blogs", with a Semrush archive as the reference -- a clean
   tinted panel holding the whole article summary.

       Blog Title
       Published September 5, 2026

       Short excerpt...

       Roofing Tips - Araby

   IT DELIBERATELY MIRRORS RELATED ARTICLES. The client asked the two to stay
   consistent, so every value below is the value .uq-blog-related__card already
   uses in css/blog.css:

       panel tint      #f5f8fc        --uq-theme-primary thinned almost to white
       hover tint      #eef3f9
       hairline        #e6edf5        (hover #dbe6f2)
       corners         0              square, like the rest of the hub
       padding         24px
       title           20px / 600 / 1.28 / -0.015em / #111111
       summary         15px / 1.55 / 3-line clamp / --uq-theme-text
       metadata        13px / #767676  (4.54:1 on white -- clears WCAG AA)

   WHY MIRRORED AND NOT SHARED. Related Articles' rules live in css/blog.css,
   which loads on a single Post and on no archive; this sheet loads on archives
   and on a single Project. Making them one component would mean either a third
   stylesheet loaded in both places or editing Related Articles -- and the brief
   is explicit that Related Articles must not change. So the PHP helpers are
   genuinely shared (uq_blog_card_excerpt(), uq_blog_primary_category()) and the
   CSS is a documented mirror. If Related Articles is ever restyled, this block
   and the .uq-blog-related__* block are the two places to keep in step.

   NO NEW COLOUR, NO NEW TYPE SCALE. Everything above is either an existing
   theme token or a value already on the site.

   The element names are its own -- __heading, __heading-link, __date,
   __summary, __meta-line, __meta-item -- so not one rule of the image-led
   Project card (__link, __media, __image, __title, __identity) is touched, and
   the two cards cannot drift into each other. */
.uq-hub-card--blog {
    /* The panel's own tokens. Named apart from --uq-hc-title-size on purpose:
       the responsive block at the foot of this file steps that variable down
       for the image-led card, and the panel title has its own ladder. */
    /* The two the client can set from Theme Settings. The literal stays as the
       var() fallback, so an empty setting emits nothing and the panel renders
       exactly as it always has; inc/hub.php prints --uq-blog-card-bg /
       --uq-blog-card-border on :root only when the field holds a real colour.
       Because both names are read only here, that override cannot reach the
       image-led Project card, which has no panel at all.

       The two -hover tints ARE now wired up as well, to their own pair of
       settings -- Blog Card Hover Background/Border Color -- so the note that
       used to sit here ("a strongly different card colour will still hover
       towards these near-white tints") no longer applies: an editor who changes
       the resting colour can change what it hovers to.
       Each of the four is independent and each keeps its own literal as the
       var() fallback, so an empty hover field preserves the hover styling
       exactly as it was. Only the two paint properties are variable; the
       `transition: background-color 0.2s ease, border-color 0.2s ease` above and
       the hover rule's own structure are untouched. */
    --uq-hc-panel-bg: var(--uq-blog-card-bg, #f5f8fc);
    --uq-hc-panel-bg-hover: var(--uq-blog-card-bg-hover, #eef3f9);
    --uq-hc-panel-border: var(--uq-blog-card-border, #e6edf5);
    --uq-hc-panel-border-hover: var(--uq-blog-card-border-hover, #dbe6f2);
    --uq-hc-panel-pad: 24px;
    --uq-hc-panel-gap: 12px;
    /* 20px -> 22px -> 24px. The first bump did not give the client the emphasis
       they were after, so the title takes the next step on the site's own card
       ladder: 24px is already the card-title size the Service Comparison
       design-3 table and the Footer CTA cards resolve to, so nothing new is
       invented here either.

       This is the one place the panel and its mirror deliberately diverge. The
       Related Articles card stays at 20px: it sits three-up inside an article
       column, not in the hub's own grid, and it is a footnote to the post above
       it rather than the thing the page is for. Only the SIZE moves -- the 600
       weight, the 1.28 line-height and the -0.015em tracking are shared with
       that card and are left alone.

       Nothing clamps this heading, so a long title takes a third line and its
       card grows. That is already handled: `margin-top: auto` on the bottom
       group keeps the metadata and date level across the row whatever the
       titles do. */
    --uq-hc-heading-size: 24px;
    --uq-hc-summary-size: 15px;

    /* The anchor for the stretched link below. */
    position: relative;
    gap: var(--uq-hc-panel-gap);
    padding: var(--uq-hc-panel-pad);
    border: 1px solid var(--uq-hc-panel-border);
    /* 10px, the radius this site's bordered content cards already use: the
       Service card, the Why Choose Us card, the Service Comparison column card
       and the Footer CTA card all measure 10px, and it is the value
       --uq-pd-card-radius holds for Project Details' cards. Measured rather
       than picked -- the site also has 12px and 16px, but those are on media
       frames and full-width panels, not on a bordered card like this one.

       It replaces the `border-radius: 0` an earlier pass set when the client
       asked for square corners; the current direction is "Blog cards rounded
       corners like the rest". The hub MEDIA keeps its own --uq-hc-radius, so
       the Project card is untouched -- that is item #22. */
    border-radius: 10px;
    background: var(--uq-hc-panel-bg);
    /* No shadow. The panel and its hairline are the whole of the container. */
    box-shadow: none;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.uq-hub-card--blog:hover {
    background: var(--uq-hc-panel-bg-hover);
    border-color: var(--uq-hc-panel-border-hover);
}

/* An <h2>: the archive owns the one <h1>, so the cards sit one level under it.
   Every property the global `h2 { font-size: 38px; font-weight: 700; color:
   #104E8B; margin: 0 0 15px }` sets is restated here -- a class beats an element
   selector, and leaving any of them out would let that rule through. */
/* Client feedback (#8): these titles read as a different typeface from every
   other card title on the site, and they measured that way. Whitelisted in the
   shared card-title rule in style.css, .uq-multi-services__card-title,
   .uq-filterable-cards__card-title, .uq-how-it-works__card-title,
   .uq-service-feature__card-title, .uq-footer-cta__card-title and
   .uq-manufacturers__name ALL render Roobert / 500 / 1.35 / -0.015em. Only the
   SIZE varies by context -- 18, 19, 22, 24 -- which is why the size below stays
   on this component's own token and is the one property not touched here.

   THREE of the four constant properties were out of step:

       family  the visible text is inside the <a>, and :root's
               `body, p, a, li, ... { font-family: var(--uq-site-font-body)
               !important }` beat the `font: inherit` on the link -- so the
               heading face declared on the heading never reached the words. The
               link rule below now restates it with the same !important
               .uq-multi-services__tab and .uq-footer-cta__card-title need for
               exactly this reason.
       weight  600 -- the SemiBold band this system reserves for buttons. Every
               card title on the site is Medium.
       lh      1.28 against the shared 1.35.

   letter-spacing was already -0.015em; it is said through the token now so the
   four move together in future.

   Colour, margins, padding, the stretched ::after hit area, the hover and the
   focus ring are all untouched. */
.uq-hub-card__heading {
    margin: 0;
    padding: 0;
    font-family: var(--uq-site-font-heading, Arial, sans-serif);
    font-size: var(--uq-hc-heading-size);
    font-weight: var(--uq-module-card-title-weight, 500);
    line-height: var(--uq-module-card-title-line-height, 1.35);
    letter-spacing: var(--uq-module-card-title-letter-spacing, -0.015em);
    color: var(--uq-hc-title-color);
    text-transform: none;
    /* The title, not the line, is what breaks. */
    overflow-wrap: anywhere;
}

.uq-hub-card__heading::before,
.uq-hub-card__heading::after {
    display: none;
    content: none;
}

/* The one link on the card. Colour and weight are inherited from the heading so
   the theme's global `a { color: #FDBB2F; font-weight: 600 }` cannot reach it. */
.uq-hub-card__heading-link {
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    /* `font: inherit` above asks for the heading's Roobert and does not get it:
       :root's `body, p, a, li, ... { font-family: ... !important }` reaches this
       <a> as an element selector, and !important beats a plain shorthand however
       specific. Restating it !important at (0,1,0) is what actually lands the
       face on the words -- see the note above the heading rule. */
    font-family: var(--uq-site-font-heading, Arial, sans-serif) !important;
    text-decoration: none;
}

/* STRETCHED: the whole card is clickable, without a second <a> and without
   wrapping the card in one -- the same mechanism Related Articles uses. */
.uq-hub-card__heading-link::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
    content: "";
}

.uq-hub-card--blog:hover .uq-hub-card__heading-link {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* BRAND BLUE ON HOVER, NEVER THE SITE'S YELLOW.

   The rule above only ever set the underline, and the title still turned
   #FDBB2F on hover -- because style.css carries a global
   `a:hover { color: #FDBB2F }` and that selector, at (0,1,1), OUTRANKS the
   `color: inherit` on .uq-hub-card__heading-link at (0,1,0). The card was
   inheriting the site's link yellow rather than choosing it.

   Adding the class to the state selector takes it to (0,2,0), which beats the
   global cleanly -- no !important, and no change to the global rule, so every
   other link on the site keeps the yellow it has.

   BOTH PATHS ARE LISTED, and they are different events: :hover fires when the
   pointer is over the link, including anywhere on the card via the stretched
   ::after, while the descendant selector covers the card's own hover state.
   :focus and :active are here so no interactive state can leak the yellow back.

   The DEFAULT title colour is untouched -- still --uq-hc-title-color (#111111)
   through `color: inherit`. Only the hovered/focused/active state is blue. */
.uq-hub-card__heading-link:hover,
.uq-hub-card__heading-link:focus,
.uq-hub-card__heading-link:active,
.uq-hub-card--blog:hover .uq-hub-card__heading-link {
    color: var(--uq-hc-accent);
}

/* FOCUS, IN TWO LAYERS, AND THE ORDER MATTERS.

   The link is stretched over the whole card, so a ring drawn on the <a> itself
   traces the title text rather than the thing the reader is about to activate.
   The ring therefore belongs on the CARD -- but only where the browser can
   express that, which needs :has().

   So the link keeps a real ring by default and it is moved to the card ONLY
   inside @supports. A browser with :focus-visible but without :has() would
   otherwise get the suppression and none of the replacement, which is a keyboard
   user left with no visible focus at all. */
.uq-hub-card__heading-link:focus-visible {
    outline: 2px solid var(--uq-hc-accent);
    outline-offset: 2px;
}

@supports selector(:has(a)) {
    .uq-hub-card--blog:has(.uq-hub-card__heading-link:focus-visible) {
        outline: 2px solid var(--uq-hc-accent);
        outline-offset: 2px;
    }

    .uq-hub-card__heading-link:focus-visible {
        outline: none;
    }
}

/* Published <date>, directly under the title -- the client's own structure. The
   negative top margin pulls it against the heading so the pair reads as one
   block and the 12px card gap falls between that block and the excerpt. */
/* The card's last row. `margin-top: auto` is what pins the bottom group to the
   card's lower edge -- it used to be -6px, a nudge for when the date sat
   directly under the title, which it no longer does.

   The auto lives on whichever element STARTS that bottom group: normally
   .uq-hub-card__meta-line, and the rule below zeroes it here so the two do not
   each claim half the free space and open a gap between them. On a post with
   neither a category nor an author there is no metadata row at all, and then
   the date starts the group and keeps its own auto. */
.uq-hub-card__date {
    margin: auto 0 0;
    padding: 0;
    color: var(--uq-hc-meta-color);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.45;
}

.uq-hub-card__meta-line + .uq-hub-card__date {
    margin-top: 0;
}

.uq-hub-card--blog .uq-hub-card__summary {
    /* Three lines, so a long excerpt cannot make one card twice the height of
       its neighbour before the grid equalises them. */
    -webkit-line-clamp: 3;
    line-clamp: 3;
    /* The site's shared card-description colour, the same token Service Cards,
       Why Choose Us, How It Works and Filterable Cards read. This card was on
       --uq-theme-text (#3F4B58), which is the colour for section copy, not for
       a card description -- no new value is introduced here.

       Scoped to --blog on purpose: the base .uq-hub-card__summary rule is
       shared with the image-led Project card, which keeps its own colour. */
    color: var(--uq-module-card-description-color, rgba(0, 0, 0, 0.7));
    font-size: var(--uq-hc-summary-size);
}

/* ---------- The metadata line: Category - Author ---------- */
.uq-hub-card__meta-line {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    /* margin-top: auto pins the row to the bottom edge whatever the title and
       excerpt lengths are -- the brief's "equal height on desktop". */
    margin: auto 0 0;
    padding: 0;
    gap: 2px 6px;
    color: var(--uq-hc-meta-color);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.45;
}

.uq-hub-card__meta-item {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}

/* The middot TRAILS the item it follows rather than leading the next one, and
   that is the difference between a tidy row and a broken-looking one: the row
   wraps on a narrow card, and a leading separator puts a stray middot at the
   START of the second line.

   :not(:last-child) rather than a + sibling rule, so a post with no category
   still ends on its author and never on a divider. */
.uq-hub-card__meta-item:not(:last-child)::after {
    content: "\00B7";
    opacity: 0.7;
}

/* Client feedback: "Blog cards category and author should be bold."
 *
 * NO MARKUP CHANGE WAS NEEDED ON THIS CARD, unlike the Related Articles one.
 * .uq-hub-card__meta-line holds exactly two items here -- the category and the
 * author -- because this card's date lives in its own .uq-hub-card__date
 * element below the row (the client's own ordering: Title, Excerpt, Category +
 * Author, then the date). So weighting every item in the row weights exactly
 * the two things asked for and cannot reach the date.
 *
 * 600 is the theme's bold step. (It was also .uq-hub-card__heading's weight when
 * this was written; feedback #8 has since put the heading on the shared card
 * title's 500, and the client asked for the row's weight to stay as it is, so
 * the two no longer match and that is deliberate.) Size, gap, baseline alignment
 * and the row's `margin-top: auto` pinning are all untouched.
 *
 * SCOPED TO --blog. The image-led Project card shares this stylesheet but draws
 * its meta as .uq-hub-card__meta, not __meta-item, so it never matched; the
 * modifier makes that a guarantee rather than a coincidence. */
.uq-hub-card--blog .uq-hub-card__meta-item {
    font-weight: 600;
    /* Client feedback (#10): Category and Author take the CARD TITLE's colour
       rather than the meta grey. --uq-hc-title-color, not a literal #111111, so
       the two keep matching if the title colour is ever re-pointed -- which it
       can be: the Theme Settings note further up this file exists because that
       token is overridable. The row's own --uq-hc-meta-color is left in place on
       .uq-hub-card__meta-line, so .uq-hub-card__date below -- which is NOT part
       of this row on the blog card -- stays grey, and so does the Project card,
       which draws its meta as .uq-hub-card__meta and never matches this
       selector. Only the colour moves: the 600 above, the 13px, the 2px/6px gap,
       the baseline alignment and the bottom pinning are all untouched. */
    color: var(--uq-hc-title-color, #111111);
}

/* The middot is an ::after on the item and would inherit both the bold and, now,
   the title colour. Pinned back to the row's own weight AND its own grey, so
   every separator in the line still matches -- exactly as on the Related
   Articles card. An inherited value loses to any declared one, so this needs no
   extra specificity. */
.uq-hub-card--blog .uq-hub-card__meta-item::after {
    font-weight: 400;
    color: var(--uq-hc-meta-color, #767676);
}

/* ==========================================
   Card description / excerpt
   ==========================================
   Shared by both cards, clamped in both, and sized per card above and below.
   `display: -webkit-box` is what makes -webkit-line-clamp work; every current
   browser supports it, and one that does not simply shows the full text, which
   is a longer card rather than a broken one. */
.uq-hub-card__summary {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    min-width: 0;
    margin: 0;
    padding: 0;
    color: var(--uq-theme-text, #3F4B58);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
    font-weight: 400;
    line-height: 1.55;
}

/* The Project card's description sits between the title and the location row,
   inside the card's single <a>, so it is a <span> there rather than a <p>.

   TWO LINES, not three: this card is image-led and the description is a
   supporting line under the title, not the body of the card. It is the same two
   lines in the Related Projects carousel, so those cards grow by a fixed amount
   and stay level with each other -- and no carousel behaviour is touched. */
.uq-hub-card--project .uq-hub-card__summary {
    -webkit-line-clamp: 2;
    line-clamp: 2;
    /* +2px on the 8px flex gap the text block already has, so the description
       reads as a paragraph under the title rather than a third meta row. */
    margin-top: 2px;
    font-size: 15px;
}

/* ==========================================
   Inside the Related Projects carousel
   ==========================================
   The carousel's <li> is a flex item with a fixed basis and align-items:
   stretch, so the card only needs to fill it. Nothing else about the carousel
   is touched: this sheet declares no rule for the track, the viewport, the
   arrows, the peek or the status line. */
.uq-related-projects__item > .uq-hub-card {
    width: 100%;
    height: 100%;
}

/* The location pin, black in this carousel rather than brand blue.

   `inherit`, not a literal: the pin's parent .uq-hub-card__identity already
   carries --uq-hc-identity-color (#111111), which is the colour of the city
   name sitting right beside it. So the icon takes exactly the text's colour and
   the pair reads as one label -- and if that text colour is ever retuned, the
   pin follows it instead of drifting to a hard-coded black.

   Scoped to the carousel because that is what the client asked for. The same
   card draws the Projects Hub grid, where the pin is still brand blue; the base
   rule above is untouched, so nothing outside this carousel changes.

   Colour only. The 12x14 svg, the 8px gap to the label, the flex alignment and
   every other value on .uq-hub-card__pin stay exactly as they are. */
.uq-related-projects__item .uq-hub-card__pin {
    color: inherit;
}

/* The carousel card is narrower than a grid column at every width, so it takes
   the same one-notch-down title ladder the old card had. */
@media screen and (max-width: 1199px) {
    .uq-related-projects__item > .uq-hub-card {
        --uq-hc-title-size: 20px;
    }
}

@media screen and (max-width: 767px) {
    .uq-related-projects__item > .uq-hub-card {
        --uq-hc-title-size: 18px;
    }
}

/* The description steps down with the title in the carousel, for the same
   reason: the card is narrower than a grid column at every width. */
@media screen and (max-width: 1199px) {
    .uq-related-projects__item > .uq-hub-card .uq-hub-card__summary {
        font-size: 14px;
    }
}

/* ==========================================
   Responsive
   ==========================================
   The site's own breakpoints -- 1200 / 991 / 767 / 479 -- so the card changes
   shape at the same widths every other page does. */
@media screen and (max-width: 1199px) {
    .uq-hub-card {
        --uq-hc-title-size: 20px;
    }

    /* THE PROJECT DESCRIPTION STEPS WITH THE TITLE, as it already did in the
       Related Projects carousel.

       Client: the description under a Projects Hub card title should read like
       the one under a Related Projects card title. Measured on the live site,
       the two already agreed above 1200px -- both 15px / 1.55 / 400 -- and
       diverged everywhere below it, because only the carousel carried the step:

           viewport   Related Projects   Projects Hub (was)
           1440       15px               15px
           1100       14px               15px   <- one step too large
            800       14px               15px   <- one step too large
            420       14px               14px

       The carousel's own rule 60 lines above is the source of truth and is NOT
       touched: at (0,3,0) it still outranks this (0,2,0) rule, so Related
       Projects resolves through its own declaration exactly as before and
       renders 14px at every width it did. This only lifts the same step up to
       the shared project card, which is what the Hub grid draws.

       SIZE ONLY. line-height stays the 1.55 on .uq-hub-card__summary and simply
       follows -- 23.25px at 15px, 21.7px at 14px, which is what the carousel
       computes today -- and the weight, the colour, the 2/3-line clamp, the
       title, the date, the location row and every margin are untouched. */
    .uq-hub-card--project .uq-hub-card__summary {
        font-size: 14px;
    }
}

/* The reference opens the image-to-text gap on a stacked layout, where the card
   is wide and there is only one per row. */
@media screen and (max-width: 767px) {
    .uq-hub-card {
        --uq-hc-gap: 24px;
        --uq-hc-title-size: 20px;
    }

    /* The Project description gets one more line back on a stacked layout: the
       card is full-width there, so two lines leave a lot of the sentence out. */
    .uq-hub-card--project .uq-hub-card__summary {
        -webkit-line-clamp: 3;
        line-clamp: 3;
    }
}

@media screen and (max-width: 479px) {
    .uq-hub-card {
        --uq-hc-gap: 16px;
        --uq-hc-title-size: 18px;
        --uq-hc-meta-size: 13px;
    }

    /* The panel keeps its proportions on a phone: a little less padding, a
       slightly smaller title, and the summary down one step with it. */
    .uq-hub-card--blog {
        --uq-hc-panel-pad: 20px;
        /* Tracks the desktop step, so the phone title stays exactly 1px under
           it and the ladder keeps its shape. */
        --uq-hc-heading-size: 23px;
        /* THE SUMMARY STEPS TOO, which it did not before.

           This card and the Related Articles card are deliberately the same
           card -- same tint, same hairline, same 15px/1.55 summary clamped to
           the same three lines, as the comment on .uq-blog-related__summary in
           css/blog.css says. Their ladders had drifted apart on exactly one
           line: css/blog.css steps --uq-ra-summary-size to 14px at this same
           breakpoint, and that step had no counterpart here, so measured on the
           live pages the two agreed at 1440, 1100 and 800 and diverged only on
           a phone -- 15px on the Hub against 14px in Related Articles.

           14px is that card's own value, not a new size, and this is its own
           breakpoint. The title ladder already matched at this width (23px on
           both), so only the summary needed the step. */
        --uq-hc-summary-size: 14px;
    }

    .uq-hub-card--project .uq-hub-card__summary {
        font-size: 14px;
    }
}

/* ==========================================
   Reduced motion
   ========================================== */
@media (prefers-reduced-motion: reduce) {
    .uq-hub-card__image {
        transition: none;
    }

    .uq-hub-card__link:hover .uq-hub-card__image {
        transform: none;
    }
}
