/* /css/blog/default.css
 *
 * The module's only PUBLIC asset, of any kind, and the only file a visitor's browser
 * ever fetches on this module's account. It lays out the listing, the category view,
 * the article, the related block, the chip row and the sidebar block, and it declares
 * nothing else (D-115).
 *
 * Linked root-relative from the module's own pages only, in <head> immediately after
 * the host's include/css.php and before scripts.php - the slot every neighbouring
 * section on these sites already uses for its own per-section sheet. It is never
 * linked from a host page, which is why admin/blog/nav-item.php carries no class out
 * of this file and takes no rule from it (A51).
 *
 * THE CLASSES THIS FILE DECLARES. 06-UI-SPEC's class table names every one of them,
 * every selector below carries at least one, and each is rendered by module markup.
 * A class with no rule behind it is a silent visual regression rather than a failure
 * anything notices, so the list is asserted by name rather than counted.
 *
 *    .blog-main          the col-md-8 content column, on all six renderings
 *    .blog-chips         the category chip row - the list itself
 *    .blog-chip          one chip: a link to a category view
 *    .blog-chip-current  the chip for the view you are already on, which is not a
 *                        link, because a link to the page you are on is a dead end
 *    .blog-cards         the card grid - the list itself
 *    .blog-card          one card in that grid
 *    .blog-shot          the 16:9 crop box, shared by the cards, the article hero
 *                        and the related thumbnails - one ratio everywhere, so one
 *                        rule, one fallback and one mental model for the client
 *    .blog-card-cat      a card's category eyebrow
 *    .blog-card-title    a card's title heading
 *    .blog-card-date     a card's publish-date line
 *    .blog-teaser        a card's teaser paragraph
 *    .blog-empty         the lede line on the empty listing, on the empty category
 *                        and on the 404 - one class carries all three
 *    .blog-article       the article wrapper, and the scope that tells the hero
 *                        image apart from a related thumbnail
 *    .blog-crumb         the breadcrumb list
 *    .blog-byline        the author, category and date line under the heading
 *    .blog-body          the client's own prose, out of blog_body_clean()
 *    .blog-foot          the article footer, and the hairline that opens it
 *    .blog-related       the aside inside that footer
 *    .blog-minis         the related mini-card row - the list itself
 *    .blog-mini          one mini-card
 *    .blog-mini-title    a mini-card's title heading
 *    .blog-mini-meta     a mini-card's category and date line
 *    .blog-back          the closing "back to the section" line
 *    .blog-side          the sidebar block in the col-md-4 column
 *    .blog-side-head     one of its two fixed headings
 *    .blog-side-list     one of its two lists
 *
 * FOUR RULES. Every one of them is asserted by
 *
 *      php harness/module-probe.php --check style
 *
 * 1. EVERY SELECTOR BELOW CARRIES A .blog- PREFIXED CLASS, so no rule in this file
 *    can match an element on a page the module does not own. There is no bare
 *    element selector anywhere in it. That is what makes "the site's other modules
 *    still work untouched" (VER-07) a property of the file rather than a review
 *    convention - and it matters more here than it did in the admin panel, because
 *    the neighbours on a public page are the client's own sections and whatever else
 *    the deployer has bolted on, none of which this module has ever seen.
 *
 * 2. THIS FILE NAMES EXACTLY TWO COLOURS AND NO OTHER HUE ANYWHERE - not in a rule
 *    and not in prose, because the palette check reads the whole file including its
 *    comments. A hue named in a comment is a hue the next person pastes into a rule.
 *
 *      #666666  every meta line: the breadcrumb trail's own words and separators,
 *               the byline's unlinked words, a card's category and date, a mini-card's
 *               meta. It measures 5.74:1 on the white the host paints behind it, an
 *               AA pass at every size on these pages, and it is the same muted grey
 *               blog-admin.css already declares - so the module carries one muted
 *               grey and not two. The two greys the host's own public stylesheets
 *               offer measure 2.85:1 and 3.95:1 and both fail AA, so neither could
 *               carry a byline.
 *
 *      #cacaca  spent exactly once, on the hairline that opens the article footer
 *               (A59). Byte-identical in all five of the public global.css files
 *               this module deploys beside, where it is the host's own hairline.
 *
 *    The host's link colour is named NOWHERE here, and neither is a number standing
 *    in for it. The five trees paint their links five different ways, so a value
 *    written into this file would be right on one site and visibly wrong on the
 *    other four (D-115, A55).
 *
 * 3. THIS FILE NEVER REACHES FOR THE CSS PRIORITY FLAG, and its prose never spells
 *    that flag either, because the check greps the whole file including comments. A
 *    module that has to shout over its host is a module that loses the argument on
 *    the next host stylesheet edit. Where this file has to win it wins by scoping:
 *    the article hero's margin is written .blog-article > .blog-shot so that it
 *    beats the shared crop rule on depth and reaches no thumbnail.
 *
 * 4. THIS FILE DECLARES NO FONT, NO LINK COLOUR AND NO HEADING COLOUR, AND NO RULE
 *    FOR THE PAGE HEADING AT ALL (D-115). Five body faces, two Font Awesome majors
 *    and two Bootstrap URLs across the five trees is the whole argument: a module
 *    that named a face, a heading hue or a link hue would be right on one of them
 *    and visibly wrong on the other four. The page heading is 42px on four trees and
 *    52px on the fifth, each with its own margin, weight and hue, and it stays the
 *    host's in full.
 *
 *    What this file DOES declare is the two sizes beneath it - 24 and 18 - which no
 *    host stylesheet sets. Left alone a browser supplies 24px for the second level
 *    and about 18.7px for the third: one of those is a size this contract never
 *    chose and the other is not a whole pixel. Declaring both makes the browser's
 *    own value the value the module chose on the one element where it is right, and
 *    replaces it everywhere else.
 *
 * LENGTHS. Every length this file CHOOSES is a multiple of 4 - 4, 8, 16, 24, 32 and
 * 48 - used exactly where 06-UI-SPEC's spacing table assigns it. There is no 64:
 * page-level spacing on these pages is the host's own .content inset, measured
 * identical in all five trees, and a module value at that scale would fight it.
 *
 * TWO off-scale lengths are the module's own and are recorded here rather than left
 * to be discovered. The 1px hairline opening the article footer (A59) reproduces the
 * host's own p.lead border byte for byte. The 2px underline beneath the current chip
 * (A43) is the thinnest width that reads as a deliberate mark rather than as a
 * text-decoration artefact under 16px text at weight 700, and it names no hue at all
 * - currentColor inherits whatever the host gives that element, so the mark is right
 * on all five trees without this file knowing any of them.
 *
 * THREE more numbers below are not rhythm and are not on the scale by definition:
 * the crop box's top padding is a ratio, nine over sixteen; the 200px on a mini-card
 * is a flex basis, picked so three sit comfortably in the column, four still fit and
 * more wrap rather than crush; and 767px is a breakpoint, expressed in the module's
 * own media query so the one-up point is identical on all five sites whichever
 * Bootstrap edition each of them loads.
 *
 * WHAT THIS FILE DELIBERATELY DOES NOT DECLARE. No paragraph margin: the host sets
 * 16px with an 18px bottom margin on prose, byte-identical in all five trees, and
 * client copy belongs on that rhythm rather than on one this module invented. No
 * width cap on the article body (A54) - the col-md-8 column is the measure, exactly
 * as it is for every neighbouring section's copy. No column width, no gutter and no
 * float: Bootstrap owns those, it is loaded from two different URLs across the five
 * trees, and this repo does not contain either file - so a number written here would
 * be competing with something nobody can read.
 */

/* The content column. Bootstrap's col-md-8 already sets the width and the gutter, so
 * this rule claims neither; it exists to give the module's own rules a scope and to
 * make the column a positioning context of its own, so that nothing the module
 * places can ever resolve against a host element further up the page. */
.blog-main {
	position: relative;
}

/* The chip row (D-118). The list reset is not cosmetic: the host's prose rule puts a
 * bullet and an 18px bottom margin on every list item on the page, so without it the
 * chip row arrives as a bulleted column instead of a row (A58). The 16px to the
 * right of each chip and the 8px beneath it are what let the row wrap on a phone
 * without the chips colliding on the line below. */
.blog-chips {
	margin: 0 0 32px;
	padding: 0;
	list-style: none;
}

.blog-chips li {
	display: inline-block;
	margin: 0 16px 8px 0;
}

/* A chip is inline-block rather than inline so that the current chip's underline is
 * a clean rectangle under the whole label instead of a line that restarts on every
 * wrap. Its line height is the meta line height, because a chip is a label rather
 * than prose. */
.blog-chip {
	display: inline-block;
	line-height: 1.4;
}

/* The current chip is marked three ways and none of them is a colour (A43): it is
 * not a link at all, it is the file's one declared weight, and it carries a 2px
 * underline in whatever colour the host has already given it. */
.blog-chip-current {
	font-weight: 700;
	border-bottom: 2px solid currentColor;
}

/* The card grid (A38). A module flex grid rather than the host's own float or
 * Bootstrap's columns: flex wraps into equal-height rows with no nth-child clear to
 * maintain as the card count changes, the 16px gap is the module's own token rather
 * than Bootstrap's 30, and if flex fails outright the cards stack full width, which
 * is the phone layout and is readable rather than broken. The negative side margin
 * and the matching card padding are the same 8px half-gutter, so the gap between two
 * cards is 16px while the outer edges still line up with the column. */
.blog-cards {
	display: flex;
	flex-wrap: wrap;
	margin: 0 -8px;
	padding: 0;
	list-style: none;
}

.blog-card {
	width: 50%;
	padding: 0 8px;
	margin-bottom: 32px;
}

/* One-up below the host's own two-column point (A39). Written as the module's own
 * query so the behaviour is identical on all five sites whichever Bootstrap edition
 * each of them loads. */
@media (max-width: 767px) {
	.blog-card {
		width: 100%;
	}
}

/* The 16:9 crop, and the reason it is written twice (A40). The percentage box is the
 * base and the modern property is the override, so the ratio is correct on every
 * browser and only the newer ones get the simpler box. The percentage resolves
 * against the box's own width, which is why a ratio can be expressed as a length at
 * all. The image is stretched over the box and cropped from the centre, which is
 * what the editor's own "keep the subject near the middle" hint promises the client.
 * On a browser too old to crop, the image fills the box distorted instead - a
 * visible imperfection on a dead browser, not a broken page. */
.blog-shot {
	position: relative;
	display: block;
	padding-top: 56.25%;
	margin-bottom: 8px;
	overflow: hidden;
}

.blog-shot img {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 50%;
}

@supports (aspect-ratio: 16 / 9) {
	.blog-shot {
		padding-top: 0;
		aspect-ratio: 16 / 9;
	}

	.blog-shot img {
		position: static;
	}
}

/* A card's four text parts, in the order D-117 enumerates them. The eyebrow's own
 * bottom margin is 4px, and the title's margin is zeroed so that 4px is the gap that
 * actually renders: no host stylesheet sets a margin on this heading level, so the
 * browser would otherwise insert about 15px of its own and the declared step would
 * be a number that appears nowhere on the page. */
.blog-card-cat {
	margin: 0 0 4px;
	color: #666666;
	line-height: 1.4;
}

.blog-card-title {
	margin: 0;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.2;
}

.blog-card-date {
	margin: 4px 0;
	color: #666666;
	line-height: 1.4;
}

/* The teaser is derived from the client's own prose, so it keeps the host's
 * paragraph rhythm and takes only the reading line height. */
.blog-teaser {
	line-height: 1.5;
}

/* The one lede line, shared by the empty listing, the empty category and the 404.
 * A step above body copy because on those three pages it is the only sentence in the
 * column, and the page heading above it is the only other thing to read. */
.blog-empty {
	font-size: 18px;
	line-height: 1.5;
}

/* Preserve the semantic article header while overriding the site's unscoped fixed
 * masthead rule, which otherwise treats every header element as the site header. */
.blog-article > .blog-article-head {
	height: auto;
	position: static;
	top: auto;
	left: auto;
	z-index: auto;
	-webkit-transition: none;
	-moz-transition: none;
	-ms-transition: none;
	-o-transition: none;
	transition: none;
}
/* The article hero, told apart from a related thumbnail by depth rather than by a
 * second class: the hero is a direct child of the article and the thumbnails are
 * not. It takes the largest step on the scale because it separates the header block
 * from the body, which is the biggest break above the footer. */
.blog-article > .blog-shot {
	margin-bottom: 32px;
}

/* The breadcrumb. Items run inline because a crumb trail is a sentence, and the list
 * reset is the same host-prose correction the chip row needs (A58). The separators
 * themselves are markup the module writes and hides from a screen reader; nothing
 * about them is declared here. */
.blog-crumb {
	margin: 0 0 16px;
	padding: 0;
	list-style: none;
	color: #666666;
	line-height: 1.4;
}

.blog-crumb li {
	display: inline;
}

/* The byline. Meta grey carries the distinction between the byline and the body
 * rather than a fifth type size: the host's prose size is the only size on the page
 * this file has not chosen, and dropping meta text below it on pages read on phones
 * would buy hierarchy the grey already buys. The author and category links inside
 * stay the host's colour, which is what makes them read as links. */
.blog-byline {
	margin: 0 0 24px;
	color: #666666;
	line-height: 1.4;
}

/* The client's prose. The line height is the one typographic value the module both
 * owns and needs: no host stylesheet sets a line height on body text, so long-form
 * copy would otherwise read at the browser's own cramped default. At the host's
 * prose size 1.5 computes to 24px, so the body's vertical rhythm lands on the scale
 * by construction. The two heading levels beneath are the client's to write and the
 * module's to size, because the editor offers exactly these two and no host
 * stylesheet gives either of them a size. */
.blog-body {
	line-height: 1.5;
}

.blog-body h2 {
	margin: 32px 0 8px;
	font-size: 24px;
	font-weight: 700;
	line-height: 1.2;
}

.blog-body h3 {
	margin: 24px 0 8px;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.2;
}

/* The article footer. The hairline is the lightest thing that says "after the
 * article" rather than "more article", and it stays when the related block is hidden
 * at zero - so a footer holding only the back link still reads as a footer (A59). */
.blog-foot {
	margin-top: 48px;
	padding-top: 24px;
	border-top: 1px solid #cacaca;
}

/* The related block. Its heading sits a level below the article's own, at the same
 * size as a card title, because it introduces the same kind of thing. */
.blog-related h2 {
	font-size: 18px;
	font-weight: 700;
	line-height: 1.2;
}

/* The mini-card row (A57). How many mini-cards there are is configuration, so the
 * row has to be count-agnostic: a flex basis rather than a width lets three sit
 * comfortably in the column, four still fit, and anything more wrap onto a second
 * line rather than crush. The half-gutter is the card grid's, so the two rows of
 * pictures on an article page are spaced alike. */
.blog-minis {
	display: flex;
	flex-wrap: wrap;
	margin: 0 -8px;
	padding: 0;
	list-style: none;
}

.blog-mini {
	flex: 1 1 200px;
	padding: 0 8px;
}

.blog-mini-title {
	font-size: 16px;
	font-weight: 700;
	line-height: 1.2;
}

.blog-mini-meta {
	color: #666666;
	line-height: 1.4;
}

/* The closing line. It takes the reading line height because it is a sentence rather
 * than a control, and nothing else: its colour is the host's, like every link. */
.blog-back {
	line-height: 1.5;
}

/* The sidebar block (D-112). It borrows no host sidebar class on purpose: the two
 * house idioms for a sidebar heading exist in only three of the five trees and both
 * paint their heading with the site's own brand hue, which this file may not name
 * (A41). What those heads genuinely share is a size step above the list beneath and
 * a heavier weight; this takes the size and the weight and leaves the paint, so the
 * same file is right on all five (A42). */
.blog-side {
	margin-bottom: 32px;
}

.blog-side-head {
	margin: 0 0 8px;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.2;
}

.blog-side-list {
	margin: 0 0 24px;
	padding: 0;
	list-style: none;
	line-height: 1.5;
}

.blog-side-list li {
	margin: 0 0 8px;
}
