/*
 * scbt-blog-band.css — the intro articles of a category blog page on a band of
 * colour, with a concave arc bitten out of its top edge (and out of its bottom
 * edge when that depth is set). The leading article above it keeps the page
 * background. Part of plg_system_scbtblogband.
 *
 * The reference is development/image.png.
 *
 * ---------------------------------------------------------------------------
 * WHAT IT STYLES, AND WHY NO TEMPLATE FILE WAS TOUCHED
 *
 * Helix's blog.php already separates the two groups for us:
 *
 *   blog.php:74   <div class="article-list articles-leading clearfix">   ← leading
 *   blog.php:94   <div class="article-list">                             ← intro
 *                   <div class="row">
 *                     <div class="col-md-4">          round(12 / num_columns)
 *                       <div class="article"> …
 *   blog.php:111  <div class="articles-more">         ← "# Links", when set
 *   blog.php:117  <div class="cat-children">          ← sub-categories, when shown
 *   blog.php:126  <nav class="d-flex pagination-wrapper">
 *
 * So :not(.articles-leading) is the whole structural change. There is nothing to
 * override and no markup to emit.
 *
 * SCOPE — TWO LAYERS, AND THE OUTER ONE IS PHP
 *
 * This sheet is not loaded on every page and then narrowed by a selector. The
 * plugin's bandActive() decides per request whether to enqueue it at all: it must
 * be com_content's category view, and the category must be one of the chosen ones.
 * A selector cannot express that — the body class Helix builds carries the view
 * but never the category.
 *
 * Every rule is still prefixed .view-category, the body class Helix builds from
 * the request's view (plugins/system/helixultimate/core/helixultimate.php:49).
 * That is belt and braces rather than the mechanism, and it costs nothing.
 *
 * If the design does not appear, look in view-source for the <link> before looking
 * at the CSS: an absent stylesheet means the category filter did not match, and a
 * present one that does nothing means the body class is missing.
 *
 * ---------------------------------------------------------------------------
 * THE RULE THIS FILE IS BUILT AROUND: IT WINS ON SPECIFICITY, NEVER ON ORDER
 *
 * plg_system_scbtbrand's scbt-blog.css styles the same cards, from the same
 * onBeforeCompileHead event, and the relative order of two system plugins is
 * whatever the Plugins manager's ordering happens to be. Nothing here may depend
 * on loading second.
 *
 *   scbt-blog.css   .view-category .article-list .article .article-header h2
 *                   → (0,4,2)
 *   this sheet      .view-category .article-list:not(.articles-leading)
 *                                  .article .article-header h2
 *                   → (0,5,2)
 *
 * :not() contributes the specificity of its argument, so :not(.articles-leading)
 * is scoping and the extra class of specificity in one token. EVERY selector in
 * this file carries it, including ones that have nothing to beat — because a rule
 * without it is a rule that would also style the leading article. build.php fails
 * the build if one loses it.
 *
 * Note that no !important appears anywhere in this file. It is not needed.
 * ---------------------------------------------------------------------------
 */


/* ---------------------------------------------------------------------------
 * 1. The block that carries the band
 *
 * z-index:0 gives this element a stacking context of its own, which is what lets
 * the ::before below sit behind the cards without a NEGATIVE z-index.
 *
 * That distinction is load-bearing. A negative-z child paints in step 3 of its
 * stacking context — BEFORE the in-flow block backgrounds of every ancestor
 * between it and that context's root, which paint in step 4. #sp-main-body and
 * .body-innerwrapper have no background today (template.css:179-190), so
 * z-index:-1 would work right now; the day either one gets a background colour the
 * band would silently disappear behind it. Ordering the two children inside a
 * stacking context of our own cannot fail that way.
 *
 * The padding is the arc depth PLUS the clearance param, added here rather than in
 * PHP, so raising the curve can never push the first row of cards up into the arc
 * and the administrator never has to keep two numbers in step.
 * ------------------------------------------------------------------------- */

.view-category .article-list:not(.articles-leading) {
	position: relative;
	z-index: 0;
	margin-top: var(--scbtband-margin-top, 0px);
	margin-bottom: var(--scbtband-margin-bottom, 0px);
	padding-top: calc(var(--scbtband-curve-top, 8vw) + var(--scbtband-pad-top, 2.5rem));
	padding-bottom: calc(var(--scbtband-curve-end, 0px) + var(--scbtband-pad-bottom, 2.5rem));

	/*
	 * WHICH EDGES OF THE BAND THIS SEGMENT CARRIES.
	 *
	 * The band does not necessarily end at the last row of cards: section 3
	 * continues it through whatever blog.php puts after the intro list — the
	 * pagination row above all — so that it reaches the footer with no white
	 * space left in between. Each segment therefore declares which arc belongs to
	 * it, and the mask in section 2 reads these two properties rather than the
	 * params directly.
	 *
	 * This segment always carries the top arc. It carries the bottom one only
	 * when nothing follows it.
	 */
	--scbtband-curve-start: var(--scbtband-curve-top, 8vw);
	--scbtband-curve-end: var(--scbtband-curve-bottom, 0px);
}

/*
 * "Something follows it" is a :has() question, and there is no other way to ask
 * it in CSS. The degrade is mild: a browser without :has() drops this rule as an
 * invalid selector, so the bottom arc stays on this segment and is bitten out of
 * the middle of the band rather than out of its bottom edge. At the 0px default
 * that is invisible, so it costs nothing unless a bottom curve was actually set.
 * Firefox 121 was the last engine to ship :has(); scbt-blog.css already depends on
 * it for the pagination end buttons, with the same reasoning.
 */
.view-category .article-list:not(.articles-leading):has(~ *) {
	--scbtband-curve-end: 0px;
}

/* The cards ride above the band. Both children are positioned, so they are
   ordered by z-index inside the context established above. */
.view-category .article-list:not(.articles-leading) > .row {
	position: relative;
	z-index: 1;
}


/* ---------------------------------------------------------------------------
 * 2. The band itself, and the arcs
 *
 * WHY A ::before AND NOT THE ELEMENT'S OWN BACKGROUND
 *
 * The band has to reach the edges of the screen while the cards stay at container
 * width and stay lined up with everything else on the page. Widening
 * .article-list itself to 100vw would take its .row and its columns with it. So
 * the colour is a separate, absolutely-positioned box behind content that keeps
 * its normal width.
 *
 * WHY calc(50% - 50vw) REACHES THE VIEWPORT EDGE
 *
 * left/right percentages on an absolutely-positioned box resolve against its
 * containing block's width — here .article-list, which sits inside
 *   section#sp-main-body > .container > .container-inner > .row >
 *   main#sp-component.col-lg-12 > .sp-column
 * and is therefore centred on the window. Its left edge is (100vw - W)/2 from the
 * window; offsetting by W/2 - 50vw from there lands on exactly 0. Nothing in that
 * chain sets overflow, a transform or a filter, so the box is free to grow past
 * its column.
 *
 * THE ONE THING THAT BREAKS IT: #sp-component is col-lg-12 only because the Main
 * Body row's `left` and `right` positions are empty and
 * helixultimate.php:400-402 folds their six columns into the component. Publish a
 * module to either and the component becomes col-lg-9, the container stops being
 * centred, and the band runs off one side. Turn "Full-width band" off if that
 * happens; preview.html reports the off-centre distance.
 *
 * 100vw includes the scrollbar, so the band overhangs the page by its width.
 * .body-innerwrapper already carries overflow-x:hidden (template.css:179-181),
 * which swallows exactly that. Do NOT add overflow-x:hidden anywhere higher up to
 * "make sure" — it forces overflow-y to a non-visible value too and would slice
 * the header's dropdown panels off (§8.15).
 *
 * THE ARCS
 *
 * Measured off development/image.png: the band's top edge sits at y=0 at both
 * outer edges and y=26 at the centre of a 326px-wide crop — a sag of 7.98% of the
 * width. At the eighth, quarter and three-eighth points the measured pixels are
 * 10, 18 and 24; a parabola predicts 11.4, 19.5 and 24.4, an ellipse 17.2, 22.5
 * and 25.2. It is a PARABOLA, which is why the usual trick of a page-coloured
 * overlay with border-radius:50% comes out visibly flatter through the middle —
 * and is wrong in a second way, because it has to be painted the page's background
 * colour where a mask cuts through to whatever is actually behind.
 *
 * A quadratic Bézier IS a parabola, so each arc is one `Q` command: from (0,0) to
 * (100,0) with the control point at (50,200) passes through (50,100) — full depth
 * at the centre, zero at both ends. preserveAspectRatio="none" lets each strip
 * stretch to the full width; a stretched parabola is still a parabola.
 *
 * THREE MASK LAYERS, NOT ONE IMAGE: a strip at the top exactly the top arc's depth
 * tall, a strip at the bottom exactly the bottom arc's depth tall, and a solid fill
 * between them. Sizing the strips rather than stretching one image over the whole
 * box is what keeps each sag equal to its setting at every band height.
 *
 * A DEPTH OF 0px GIVES A STRAIGHT EDGE FOR FREE — that strip collapses to nothing
 * and the fill grows to cover it. That is what makes the bottom edge a setting
 * rather than a second layout, it is why the default costs no extra code, and it
 * is also what lets a middle segment of the band (section 3) reuse this same block
 * with both depths at 0px and come out a plain rectangle.
 *
 * The shapes are painted WHITE. A mask image referenced as an image uses its alpha
 * channel (mask-mode: match-source resolves to alpha for anything that is not an
 * SVG <mask> element), so black would work too — but white is also correct under
 * luminance masking, and costs nothing.
 *
 * These three shapes are declared here rather than emitted by the plugin because
 * they are geometry, not settings. Only the depths are params.
 *
 * Where masks are unsupported the band renders as a plain rectangle: right colour,
 * right place, straight edges.
 * ------------------------------------------------------------------------- */

/* Every segment of the band: the colour, and the bleed out to the screen edges. */
.view-category .article-list:not(.articles-leading)::before,
.view-category .article-list:not(.articles-leading) ~ *::before {
	content: "";
	position: absolute;
	z-index: 0;
	top: 0;
	bottom: 0;
	left: var(--scbtband-pull, calc(50% - 50vw));
	right: var(--scbtband-pull, calc(50% - 50vw));

	background-color: var(--scbtband-bg, var(--scbt-brand, #E6007E));
}

/* The two segments that can carry an EDGE of the band: the intro list, which
   always has the top arc, and whatever ends the band, which has the bottom one.
   Both read --scbtband-curve-start / --scbtband-curve-end, which each segment
   sets for itself in section 1 or section 3. */
.view-category .article-list:not(.articles-leading)::before,
.view-category .article-list:not(.articles-leading) ~ *:last-child::before {
	--scbtband-arc-top: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0 0 Q50 200 100 0 L100 100 L0 100 Z' fill='%23ffffff'/%3E%3C/svg%3E");
	--scbtband-arc-bottom: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0 100 Q50 -100 100 100 L100 0 L0 0 Z' fill='%23ffffff'/%3E%3C/svg%3E");
	--scbtband-arc-fill: linear-gradient(#ffffff, #ffffff);

	-webkit-mask-image: var(--scbtband-arc-top), var(--scbtband-arc-fill), var(--scbtband-arc-bottom);
	        mask-image: var(--scbtband-arc-top), var(--scbtband-arc-fill), var(--scbtband-arc-bottom);

	/*
	 * Declared twice on purpose, plain calc() first and the max()-guarded form
	 * second. If a browser rejects max() here the guarded line is dropped and the
	 * plain one still stands — whereas dropping mask-size outright would leave the
	 * layers at `auto`, which for a sizeless SVG means 100% 100%: all three
	 * stretched over the whole band, with arcs half its height deep. That is a far
	 * worse failure than the negative-size case the guard is for.
	 */
	-webkit-mask-size:
		100% var(--scbtband-curve-start, 8vw),
		100% calc(100% - var(--scbtband-curve-start, 8vw) - var(--scbtband-curve-end, 0px)),
		100% var(--scbtband-curve-end, 0px);
	-webkit-mask-size:
		100% var(--scbtband-curve-start, 8vw),
		100% max(0px, calc(100% - var(--scbtband-curve-start, 8vw) - var(--scbtband-curve-end, 0px))),
		100% var(--scbtband-curve-end, 0px);
	        mask-size:
		100% var(--scbtband-curve-start, 8vw),
		100% calc(100% - var(--scbtband-curve-start, 8vw) - var(--scbtband-curve-end, 0px)),
		100% var(--scbtband-curve-end, 0px);
	        mask-size:
		100% var(--scbtband-curve-start, 8vw),
		100% max(0px, calc(100% - var(--scbtband-curve-start, 8vw) - var(--scbtband-curve-end, 0px))),
		100% var(--scbtband-curve-end, 0px);

	/*
	 * The middle layer is positioned EXPLICITLY at the top arc's depth, not
	 * centred.
	 *
	 * scbt-article.css can centre its fill because its two arcs are always the
	 * same depth. Here they are independent params, and with an asymmetric pair a
	 * centred fill leaves a gap: with the bottom at 0px the fill is 100% - top
	 * tall, centred, so it starts top/2 down and ends top/2 short of the bottom —
	 * slicing the bottom of the band clean off. Anchoring it to the top arc's depth
	 * makes it end at exactly 100% - bottom, which is where the bottom strip
	 * begins, for every combination of the two.
	 */
	-webkit-mask-position: left top, left var(--scbtband-curve-start, 8vw), left bottom;
	        mask-position: left top, left var(--scbtband-curve-start, 8vw), left bottom;

	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
}


/* ---------------------------------------------------------------------------
 * 3. The tail: the band runs on to the footer
 *
 * THE PROBLEM THIS SOLVES
 *
 * The band used to stop at the bottom of the intro list, and everything after it
 * was white: the pagination row, and then #sp-main-body's own bottom padding — a
 * hard `padding: 100px 0` at template.css:188-190, with no responsive override.
 * On a twenty-page announcements list that is a pagination row stranded on white
 * between a coloured band and a dark footer, with about 140px of nothing beneath
 * it.
 *
 * TWO HALVES, AND THEY ARE INDEPENDENT
 *
 * (a) Everything blog.php emits AFTER the intro list gets a segment of the band
 *     of its own. `~ *` covers .articles-more, .cat-children and the pagination
 *     nav without naming any of them, so a menu item that switches one on cannot
 *     punch a white hole in the band. The segments abut because their vertical
 *     margins are zeroed, and each one is the same ::before as section 2 —
 *     rectangular, because both arc depths are 0px on it.
 *
 * (b) The LAST of them — or the intro list itself, when nothing follows — pulls
 *     the footer up by --scbtband-reach-bottom with a negative bottom margin.
 *     That number is #sp-main-body's bottom padding, so the section's content box
 *     shrinks by exactly what its padding then adds and the footer ends up flush
 *     against the bottom edge of the band. Setting it to 0px restores the stock
 *     gap.
 *
 * WHY A NEGATIVE MARGIN AND NOT A RULE ON #sp-main-body
 *
 * Because there is no honest selector for it. Every rule in this file has to
 * carry :not(.articles-leading) — that is what wins the specificity contest with
 * scbt-blog.css and what keeps these rules off the leading article — and
 * #sp-main-body is an ANCESTOR of the element that class is on, so no descendant
 * selector can reach it. Pulling the footer up from the last child does the same
 * job from the inside, and it degrades to "the stock gap" rather than to a broken
 * page if it ever stops applying.
 *
 * The pull does reach the section: .sp-column and .blog have no padding or border
 * of their own, so the last child's bottom margin collapses through them, and
 * #sp-component is a flex item whose height therefore includes it. If a template
 * update ever gives one of those wrappers a padding the pull still works — it just
 * stops being exact, and preview.html's readout is what would show it.
 *
 * WHY EVERY SEGMENT HAS TO LIFT ITS OWN CONTENT
 *
 * A positioned ::before at z-index 0 paints in step 6 of its stacking context —
 * AFTER the text of non-positioned descendants. So the content of each segment
 * has to be positioned too, exactly as .row is in section 1, or the band paints
 * over the pagination numbers.
 * ------------------------------------------------------------------------- */

.view-category .article-list:not(.articles-leading) ~ * {
	position: relative;
	z-index: 0;

	/* The segments must abut. A margin here is a white stripe across the band. */
	margin-top: 0;
	margin-bottom: 0;

	/* A middle segment carries neither arc; both strips collapse and the fill
	   covers the whole rectangle. */
	--scbtband-curve-start: 0px;
	--scbtband-curve-end: 0px;
}

.view-category .article-list:not(.articles-leading) ~ * > * {
	position: relative;
	z-index: 1;
}

/*
 * A segment with no padding or border of its own does not contain its first
 * child's top margin — the margin collapses THROUGH it and moves the whole
 * segment down, which opens exactly the stripe of page colour the zeroed margins
 * above are there to prevent. Bootstrap's reboot already zeroes the top margin of
 * every list and heading that can appear here, so this only ever matters for
 * markup that arrives with its own; the fix costs one rule and cannot be applied
 * the usual way, because display:flow-root would destroy the pagination row's
 * `d-flex`.
 */
.view-category .article-list:not(.articles-leading) ~ * > :first-child {
	margin-top: 0;
}

/* The end of the band: the bottom arc belongs here, the clearance param becomes
   the space between the last thing on the band and the footer, and the negative
   margin swallows #sp-main-body's bottom padding. */
.view-category .article-list:not(.articles-leading) ~ *:last-child {
	padding-bottom: calc(var(--scbtband-curve-bottom, 0px) + var(--scbtband-pad-bottom, 2.5rem));
	margin-bottom: calc(-1 * var(--scbtband-reach-bottom, 100px));

	--scbtband-curve-end: var(--scbtband-curve-bottom, 0px);
}

/* …and the same pull when the intro list IS the last thing on the page, which is
   any category short enough not to paginate. Its own padding already includes the
   bottom arc, because :has(~ *) did not match. */
.view-category .article-list:not(.articles-leading):last-child {
	margin-bottom: calc(-1 * var(--scbtband-reach-bottom, 100px));
}


/* ---------------------------------------------------------------------------
 * 4. Everything printed on the band
 *
 * scbt-blog.css colours the card titles var(--scbt-blog-title-color,
 * var(--scbt-brand, #E6007E)) and the intro text #555555, both of which are
 * invisible or nearly so on a strong band colour. These restate them at (0,5,2)
 * against its (0,4,2) — see the note at the top about winning on specificity and
 * never on order.
 *
 * Hover is the same colour at reduced opacity rather than a fourth colour param:
 * over an arbitrary band colour there is no second colour that is reliably
 * readable, and dimming is.
 * ------------------------------------------------------------------------- */

.view-category .article-list:not(.articles-leading) .article .article-header h1,
.view-category .article-list:not(.articles-leading) .article .article-header h2,
.view-category .article-list:not(.articles-leading) .article .article-header h1 a,
.view-category .article-list:not(.articles-leading) .article .article-header h2 a {
	color: var(--scbtband-title-color, #ffffff);
}

.view-category .article-list:not(.articles-leading) .article .article-header h1 a:hover,
.view-category .article-list:not(.articles-leading) .article .article-header h2 a:hover,
.view-category .article-list:not(.articles-leading) .article .article-header h1 a:focus,
.view-category .article-list:not(.articles-leading) .article .article-header h2 a:focus,
.view-category .article-list:not(.articles-leading) .article .article-header h1 a:active,
.view-category .article-list:not(.articles-leading) .article .article-header h2 a:active {
	color: var(--scbtband-title-color, #ffffff);
	opacity: 0.75;
}

.view-category .article-list:not(.articles-leading) .article .article-introtext {
	color: var(--scbtband-text-color, #ffffff);
}

/*
 * The info block and the Read More button are both switched off by the menu item's
 * settings on this site (§5k), so neither is on the page today. They are covered
 * anyway, because the cost of covering them is three rules and the cost of not
 * covering them is a brand-pink link on a brand-pink band the day someone turns
 * one of those settings back on.
 */
.view-category .article-list:not(.articles-leading) .article .article-info,
.view-category .article-list:not(.articles-leading) .article .article-info a,
.view-category .article-list:not(.articles-leading) .article .article-info time {
	color: var(--scbtband-text-color, #ffffff);
}

.view-category .article-list:not(.articles-leading) .article .readmore a,
.view-category .article-list:not(.articles-leading) .article .readmore .btn {
	border-color: var(--scbtband-title-color, #ffffff);
	background-color: transparent;
	color: var(--scbtband-title-color, #ffffff);
}


/* ---------------------------------------------------------------------------
 * 5. The pagination row, which is now ON the band
 *
 * Section 3 carries the colour under it, so its circles have to read against the
 * band rather than against the page. scbt-blog.css draws them in the brand
 * colour — which over a brand-coloured band is nothing at all.
 *
 * These are its own selectors with this file's two extra classes in front, so
 * they win by (0,9,2) against its (0,7,2) and by (0,8,2) against its (0,6,2) —
 * on specificity, never on order, exactly as everywhere else here. Nothing about
 * WHICH buttons render is touched: the digit-matching rule that hides
 * Почеток / Пред / Следна / Крај lives in scbt-blog.css and is left to it.
 *
 * The current page inverts rather than filling with a fourth colour — the title
 * colour becomes the fill and the band colour becomes the label — so the filled
 * circle reads on any band the administrator picks.
 * ------------------------------------------------------------------------- */

.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item > .page-link {
	color: var(--scbtband-title-color, #ffffff);
}

.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item > a[href].page-link:hover,
.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item > a[href].page-link:focus {
	background-color: transparent;
	color: var(--scbtband-title-color, #ffffff);
	opacity: 0.75;
}

.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item.active > .page-link,
.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item.active > .page-link:hover,
.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination > li.page-item.active > .page-link:focus {
	background-color: var(--scbtband-title-color, #ffffff);
	color: var(--scbtband-bg, var(--scbt-brand, #E6007E));
	opacity: 1;
}

.view-category .article-list:not(.articles-leading) ~ .pagination-wrapper .pagination-counter {
	color: var(--scbtband-text-color, #ffffff);
}

/*
 * The "# Links" list, for the same reason and with the same odds of being on:
 * .list-group-item ships a white background from Bootstrap, which on the band is
 * a row of white boxes. This is the pagination's counterpart and costs two rules.
 * The hairline is a literal white at low alpha rather than a param — it is a
 * divider, not a colour anybody chooses, and on a light band it simply disappears.
 */
.view-category .article-list:not(.articles-leading) ~ .articles-more .list-group-item {
	background-color: transparent;
	border-color: rgba(255, 255, 255, 0.25);
	color: var(--scbtband-text-color, #ffffff);
}

.view-category .article-list:not(.articles-leading) ~ .articles-more .list-group-item a {
	color: var(--scbtband-title-color, #ffffff);
}
