/**
 * ContentGrid listing styles (CV Pro replacement).
 *
 * Reproduces the former Content Views Pro appearance from scratch with
 * portfoliocharts-cg-* classes (zero CV dependency). Values mirror the extracted
 * visual spec: Bootstrap float grid, 250px square cover thumbnails, centered
 * titles (26px uppercase for cover, scaled down on mobile / 18px for insights),
 * #464d4d / #7f8d8c filter
 * buttons, full-width #f1f2f3 search, Source Sans Pro.
 *
 * Palette: #464d4d slate · #25282c title · #e06d5e coral hover ·
 *          #7f8d8c muted · #f1f2f3 light gray.
 */

.portfoliocharts-content-grid {
    font-family: "Source Sans Pro", sans-serif;
}
.portfoliocharts-content-grid * {
    box-sizing: border-box;
}

/* ---------------------------------------------------------------- Controls */
.portfoliocharts-cg-controls {
    /* Whitespace below the control row, down to the first thumbnail row. Measured
       off the active chip's gray box rather than the text inside it, matching the
       22px bottom margin the theme puts on the image above — so the row sits in an
       even band once the lit chip gives the eye a hard edge to read from. */
    margin-bottom: 22px;
}

/* Inline keyword search — the last chip in the filter row.
   Every metric here is duplicated from .portfoliocharts-cg-filter-btn below (and
   shared with the mirror probe) so the three stay on one baseline; the selectors
   carry the grid class purely for specificity, since site themes style bare
   `input` with their own padding and borders and would otherwise win. */
.portfoliocharts-cg-search {
    position: relative;
    display: inline-block;
    /* A long enough term would otherwise size the chip past the row and push the
       listing sideways; capped, the input scrolls its own text instead. */
    max-width: 100%;
}
.portfoliocharts-content-grid .portfoliocharts-cg-search-input,
.portfoliocharts-content-grid .portfoliocharts-cg-search-mirror {
    padding: 6px 12px;
    font-family: inherit;
    font-size: 18px;
    line-height: 1.3;
    letter-spacing: inherit;
    border: 0;
    border-radius: 0;
}
.portfoliocharts-content-grid .portfoliocharts-cg-search-input {
    display: inline-block;
    /* Placeholder-width seed; JS re-measures against the mirror as you type. */
    width: 6em;
    max-width: 100%;
    color: #7f8d8c;
    background: transparent;
    box-shadow: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    transition: color 0.15s ease, background-color 0.15s ease;
}
.portfoliocharts-cg-search-input::placeholder {
    color: #7f8d8c;
    opacity: 1;
}
/* Both halves have to darken together: an empty chip paints its label through
   ::placeholder, so the input's own color has nothing visible to act on until a
   term is typed. Without the second rule the word "Search" ignores hover while
   every filter word beside it darkens. */
.portfoliocharts-cg-search-input:hover,
.portfoliocharts-cg-search-input:hover::placeholder {
    color: #464d4d;
}
/* Lit while focused, and while it holds a term after you click away — a live
   keyword filter reads the same as a live category filter. */
.portfoliocharts-content-grid .portfoliocharts-cg-search-input:focus,
.portfoliocharts-content-grid .portfoliocharts-cg-search-input.is-active {
    color: #fff;
    background: #464d4d;
    caret-color: #fff;
    cursor: text;
    outline: none;
}
/* Blank the placeholder on focus so clicking in leaves just the blinking caret. */
.portfoliocharts-cg-search-input:focus::placeholder {
    color: transparent;
}
/* WebKit's clear affordance draws dark-on-dark on the lit chip; Escape clears. */
.portfoliocharts-cg-search-input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}
/* Off-layout width probe: same metrics as the input, never painted. */
.portfoliocharts-content-grid .portfoliocharts-cg-search-mirror {
    position: absolute;
    top: 0;
    left: 0;
    visibility: hidden;
    white-space: pre;
    pointer-events: none;
}

/* Filter button bar */
.portfoliocharts-cg-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    /* Breathing room between wrapped lines when the row is too narrow to hold
       every filter (mobile), where the chips would otherwise stack edge to edge. */
    row-gap: 4px;
    /* The controls wrapper owns the gap down to the cards. */
    margin-bottom: 0;
}
.portfoliocharts-cg-filter-btn {
    display: inline-block;
    padding: 6px 12px;
    font-size: 18px;
    line-height: 1.3;
    color: #7f8d8c;
    text-decoration: none;
    background: transparent;
    border-radius: 0;
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease;
}
.portfoliocharts-cg-filter-btn:hover {
    color: #464d4d;
}
.portfoliocharts-cg-filter-btn.is-active {
    color: #fff;
    background: #464d4d;
}

/* --------------------------------------------------------------- Grid */
/* CSS Grid — 3 cols desktop/tablet, 2 cols mobile. Unlike a float grid, rows
   stay aligned regardless of card height, so uneven title lengths never leave
   gaps (this replaces CV's pt-cv-same-height JS height-equalization entirely). */
.portfoliocharts-cg-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: 30px;
    /* Row gap intentionally larger than the 10px thumbnail-to-title gap so each
       title reads as belonging to the image above it, not the row below. */
    row-gap: 40px;
}
.portfoliocharts-cg-item {
    min-width: 0;
    overflow: hidden;
}
@media (max-width: 767px) {
    .portfoliocharts-cg-row {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* --------------------------------------------------------------- Carousel */
/* display="carousel": the same cards, shown one group at a time — 3 across on
   desktop, 1 on mobile. The arrows page the whole post set server-side over AJAX
   (each click swaps in the next/prev group), so the group in the DOM is always
   exactly what's visible: there's nothing to scroll or swipe (overflow is clipped).
   Arrows ship hidden and are revealed by JS only when there's more than one page. */
.portfoliocharts-cg-carousel {
    display: flex;
    /* Top-align the arrows; JS then translates each onto the thumbnail's vertical
       midline (the thumbnail height is dynamic, so it can't be centered in pure CSS). */
    align-items: flex-start;
    gap: 12px;
}

/* Override the CSS-Grid row with a plain flex row of the current group. */
.portfoliocharts-content-grid--carousel .portfoliocharts-cg-row {
    display: flex;
    grid-template-columns: none;
    flex: 1 1 auto;
    min-width: 0;
    column-gap: 30px;
    row-gap: 0;
    overflow: hidden; /* arrows page the strip — no manual scroll/swipe */
}

/* Prefetch + slide: the JS layer wraps the row in a clipping viewport and a sliding
   track. On an arrow click the incoming group (served from a client cache) is placed
   alongside the current one on the track, which is then translated by exactly one
   viewport width; the outgoing group is dropped once the transform settles. With no
   JS the wrapper never appears and the plain row above stands in. */
.portfoliocharts-cg-viewport {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden; /* clipping moves here from the row during a slide */
}
/* `will-change: transform` is deliberately NOT declared here — animateTo() sets it
   for the duration of a slide and settle() takes it off again.

   Declared permanently it gives the track its own compositing layer for the whole
   life of the page, and everything inside is then painted from that layer's raster
   texture rather than straight to the screen. Vector content pays for that: the
   donut cards read visibly softer than the identical cards in the grid listing,
   worst of all through the drop shadow, because the arcs sit inside an SVG filter
   and filter output is rastered at the layer's resolution rather than the display's.
   The grid listing has no layer, which is exactly why it looked crisp by comparison.

   Nothing is lost by moving it: the hint only means anything while a transform is
   actually changing, and the browser composites a running transform transition on
   its own regardless. See also MDN's own warning against declaring it up front. */
.portfoliocharts-cg-track {
    display: flex;
    width: 100%;
    transition: transform 0.35s ease;
}
/* Each group fills the viewport (100% of the track's own width), so two groups sit
   edge-to-edge and translateX(-100%) advances by exactly one group. This overrides
   the flex:1 1 auto above (3 classes vs 2) so the rows don't share the track width. */
.portfoliocharts-content-grid--carousel .portfoliocharts-cg-track .portfoliocharts-cg-row {
    flex: 0 0 100%;
    width: 100%;
    overflow: visible;
}
@media (prefers-reduced-motion: reduce) {
    .portfoliocharts-cg-track { transition: none; }
}

/* Desktop: --pc-cg-cols cards across (set inline from the group size; default 3),
   each taking an equal share of the row minus the 30px inter-card gaps. */
.portfoliocharts-content-grid--carousel .portfoliocharts-cg-item {
    flex: 0 0 calc((100% - (var(--pc-cg-cols, 3) - 1) * 30px) / var(--pc-cg-cols, 3));
}
@media (max-width: 767px) {
    /* Mobile: one full-width card at a time — advance with the arrows only. */
    .portfoliocharts-content-grid--carousel .portfoliocharts-cg-item {
        flex-basis: 100%;
    }
}

/* Prev/next arrow buttons (revealed by JS; hidden attribute wins until then). The
   chevron is a pure-CSS triangle drawn with borders in currentColor, so it inverts to
   white on hover along with the button text color. */
.portfoliocharts-cg-arrow {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    color: #464d4d;
    background: #fff;
    border: 1px solid #464d4d;
    border-radius: 50%;
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease, opacity 0.15s ease;
}
.portfoliocharts-cg-arrow::before {
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-style: solid;
}
.portfoliocharts-cg-arrow--prev::before {
    border-width: 8px 11px 8px 0;
    border-color: transparent currentColor transparent transparent;
    margin-right: 2px; /* optical centering of the leftward triangle */
}
.portfoliocharts-cg-arrow--next::before {
    border-width: 8px 0 8px 11px;
    border-color: transparent transparent transparent currentColor;
    margin-left: 2px; /* optical centering of the rightward triangle */
}
/* The button keeps focus after a click. Without an explicit focus/active style, a
   host theme's global `button:focus`/`button:active` color (Illustratr paints it
   salmon-red) wins and sticks until focus leaves. Pin focus/active back to the
   resting look — these class selectors outrank the theme's element selectors, and
   sit *before* :hover so hovering a still-focused arrow keeps filling gray (equal
   specificity, later rule wins). Keyboard users still get a visible ring below. */
.portfoliocharts-cg-arrow:focus,
.portfoliocharts-cg-arrow:active {
    color: #464d4d;
    background: #fff;
    border-color: #464d4d;
}
.portfoliocharts-cg-arrow:focus-visible {
    outline: 2px solid #464d4d;
    outline-offset: 2px;
}
.portfoliocharts-cg-arrow:hover {
    color: #fff;
    background: #464d4d;
    border-color: #464d4d; /* else a host theme's button:hover border (salmon) shows */
}
.portfoliocharts-cg-arrow:disabled {
    opacity: 0.3;
    cursor: default;
    color: #464d4d;
    background: #fff;
}
.portfoliocharts-cg-arrow[hidden] {
    display: none;
}

/* --------------------------------------------------------------- Card */
.portfoliocharts-cg-card {
    display: block;
}
.portfoliocharts-cg-card > * {
    margin-bottom: 10px;
}
.portfoliocharts-cg-card > *:last-child {
    margin-bottom: 0;
}

/* Insights date line (above thumbnail) */
.portfoliocharts-cg-date {
    text-align: left;
    font-size: 14px;
    color: #7f8d8c;
}

/* Square cover thumbnail */
.portfoliocharts-cg-thumb {
    display: block;
    width: 250px;
    max-width: 100%;
    aspect-ratio: 1 / 1;
    margin: 0 auto 10px;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-color: #f1f2f3;
    overflow: hidden;
}
.portfoliocharts-cg-thumb--empty {
    background-color: #e7e9ea;
}

/* Portfolio cards draw their allocation instead of showing a picture of it — the
   same live donut the portfolio slider's tiles carry (see slider.md). It occupies
   the ordinary thumbnail box, so the card's geometry, the row alignment and the
   carousel's arrow positioning are all unchanged; only the box's own painting goes.

   No background, because the donut is a shape rather than a picture and the grey
   plate would read as a tile behind it. No clip either: the drop shadow scales with
   the donut and reaches past the arc, and cutting it flat at the edge is visible as
   a hard line — the inset the painter draws with leaves it room inside the square. */
.portfoliocharts-cg-thumb--donut {
    background-color: transparent;
    overflow: visible;
}
.portfoliocharts-cg-donut {
    display: block;
    /* This is the donut's actual size. The SVG is drawn against a viewBox and takes
       100% of this box, so the drawing follows the column exactly as the cover
       images beside it do — continuously, with no JS in the loop. The painter
       deliberately leaves no inline width behind, which would outrank this.

       No height: the SVG derives its own from the viewBox's square ratio, so this
       box ends up exactly as tall as it is wide — the same square the thumb's
       aspect-ratio gives an image — without either one resolving a percentage
       height against the other. */
    width: 100%;
    /* Decoration — the card is the control. Without this the donut's own hit arcs
       swallow the click meant for the card's link and fire
       portfoliocharts:donut-hover, which any Full UI grid on the page listens to. */
    pointer-events: none;
}

/* Title — centered; sizing/casing driven by the layout modifier */
.portfoliocharts-cg-title {
    display: block;
    text-align: center;
    text-decoration: none;
    font-weight: 600;
    line-height: 1.3;
    color: #25282c;
    transition: color 0.15s ease;
}
.portfoliocharts-cg-title:hover {
    color: #e06d5e;
}

/* Cover variant: 26px uppercase (portfolios / charts / assets). Font size is a
   variable so the reserved 2-line min-height below tracks it when it shrinks. */
.portfoliocharts-content-grid--cover .portfoliocharts-cg-title {
    --pc-cg-cover-fs: 26px;
    font-size: var(--pc-cg-cover-fs);
    text-transform: uppercase;
    /* Equalize to ~2 lines in pure CSS (replaces CV's pt-cv-same-height JS). */
    min-height: calc(var(--pc-cg-cover-fs) * 1.3 * 2);
    /* Safety net: let a single word that still can't fit break rather than spill
       past the card and get clipped by the item's overflow:hidden. */
    overflow-wrap: break-word;
}
@media (max-width: 767px) {
    /* At 2 columns the card is only ~145px wide, so a fixed 26px overflows on long
       single words like "INDEPENDENCE" or "DRAWDOWNS" — the item's overflow:hidden
       then clips the last glyphs. Scale the title with the viewport (which tracks
       the column width) so the widest title fits across phone sizes. */
    .portfoliocharts-content-grid--cover .portfoliocharts-cg-title {
        --pc-cg-cover-fs: clamp(16px, 5.2vw, 22px);
    }
}

/* Insights variant: 18px, mixed case */
.portfoliocharts-content-grid--insights .portfoliocharts-cg-title {
    font-size: 18px;
    min-height: calc(18px * 1.3 * 2);
}

/* Empty state */
.portfoliocharts-cg-empty {
    color: #7f8d8c;
    font-size: 18px;
    padding: 20px 0;
}

/* --------------------------------------------------------- Pagination */
.portfoliocharts-cg-pagination {
    margin-top: 20px;
    text-align: center;
}
.portfoliocharts-cg-pagination .page-numbers {
    display: inline-block;
    padding: 6px 12px;
    margin: 0 2px;
    font-size: 18px;
    line-height: 1.3;
    color: #464d4d;
    text-decoration: none;
    border-radius: 0;
}
.portfoliocharts-cg-pagination a.page-numbers:hover {
    color: #e06d5e;
}
.portfoliocharts-cg-pagination .page-numbers.current {
    color: #fff;
    background: #464d4d;
}
