/**
 * Theme Name: Blocksy Child
 * Description: Blocksy Child theme
 * Author: Creative Themes
 * Template: blocksy
 * Text Domain: crystal-cleanse
 * Domain Path: /languages
 */

/* -----------------------------------------------------------------------------
 * Crystal Cleanse additions
 * -----------------------------------------------------------------------------
 * Theme Name and Author are left exactly as Blocksy generated them — that is
 * what WordPress already has this theme registered as, and renaming buys
 * nothing. Two header fields were changed, though, so don't read the block
 * above as untouched:
 *
 *   Text Domain  corrected from 'blocksy' to 'crystal-cleanse'. The strings in
 *                this child theme belong to the child's domain, and the .mo
 *                files in /languages are named for it. functions.php calls
 *                load_child_theme_textdomain() explicitly, so translations
 *                resolve either way — but a header declaring the wrong domain
 *                misleads translation tooling.
 *   Domain Path  added, pointing at /languages, for the same reason.
 *
 * THIS FILE IS NOT LOADED AUTOMATICALLY. WordPress does not enqueue a classic
 * child theme's stylesheet, and Blocksy deliberately skips it for performance.
 * It is enqueued explicitly in functions.php as 'crystal-cleanse-child'. That
 * was missing at first and every rule here was silently inert — the Query Loop
 * grid below in particular, which is why the blog section could not render its
 * "1 pinned + 2 latest" row. If that enqueue is ever removed, this whole file
 * stops applying again, with nothing to tell you.
 *
 * Everything below is WordPress/Blocksy-specific glue: rules that exist because
 * of how Gutenberg emits pattern markup or because Blocksy's builders do not
 * expose a precise design value. The landing-page design system itself lives in
 * assets/css/crystal-cleanse.css, scoped to .cc and enqueued from functions.php.
 * -------------------------------------------------------------------------- */

/* The .cc wrapper renders as a Gutenberg "constrained" layout block, which
   caps its children's width via the --wp--style--global--content-size custom
   property. That variable inherits WordPress/Blocksy's generic default
   (750px) here, far narrower than this design was built for -- it squeezes
   every section (hero, ritual, steps, etc.) into a column so narrow that
   headlines wrap mid-word and the former hero photo's aspect-ratio box got
   stretched tall by the taller text column next to it. Override it to the
   width this design assumes (1180px is --cc-maxw; see CLAUDE.md metrics). */
/* 1124, not 1180, and the difference is not a typo. In the prototype the 1180
   belongs to `.container`, which carries `padding: 0 28px` INSIDE that width —
   so its actual content is 1180 - 56 = 1124. Gutenberg's content-size caps the
   content itself, with the gutter added outside it below. Setting 1180 here
   made every row 56px wider than the prototype, which is what pushed the
   crystal chips narrow enough to wrap "+ many more in the app".
   Measured identical to the prototype at 1211px: grid 1124, chips 214. */
.cc {
	--wp--style--global--content-size: 1124px;
	--wp--style--global--wide-size: 1400px;
}

/* Full-bleed bands -------------------------------------------------------------
   The content-size override above fixes the 750px squeeze, but on its own it
   caps the SECTION ELEMENTS at 1180 too — so the charcoal band, the sage app
   panel and the newsletter band stopped ~260px short of each edge instead of
   spanning the window. Four sections paint a background (ritual, dark, saluxe,
   news). The hero paints no background; its photo reaches the window edge
   because the section is full width. Those sections were inset.

   The prototype's structure is: <section> full width, <div class="container">
   inside it capping content at 1180 with a 28px gutter. There is no .container
   element in the port, so this rebuilds that arrangement:

     1. free .cc and its sections from the constrained layout's max-width and
        its `margin-inline: auto !important`;
     2. give the sections the 28px gutter the .container used to provide.

   Each section is itself a constrained group, so its CHILDREN are still capped
   at --wp--style--global--content-size and centered. That is what keeps the
   content at 1180 while the background runs edge to edge.

   Note this deliberately does NOT use the usual `width:100vw` full-bleed trick.
   100vw includes the scrollbar, which would push the page 15px wide and
   reintroduce exactly the horizontal drift CLAUDE.md decision 9 documents.

   Verified at three container widths: 1697 (band 1697, content 1180 centered),
   900 (band 900, content 844, 28px gutter) and 420 (band 420, content 364,
   28px gutter). No horizontal overflow at any of them.

   This must stay AFTER crystal-cleanse.css, whose `.cc .cc-section` sets
   `padding: clamp(...) 0` and would otherwise reset the inline padding to 0.
   functions.php enqueues it that way on purpose. */
.cc.cc {
	max-width: none;
	width: 100%;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
.cc > .cc-section {
	max-width: none;
	width: 100%;
	margin-left: 0 !important;
	margin-right: 0 !important;
	padding-left: 28px;
	padding-right: 28px;
	/* margin-block:0 is not cosmetic. Blocksy gives every child of a flow or
	   constrained layout `margin-block-end: var(--theme-content-spacing)` =
	   1.5em = 25.5px, and these sections are such children. That put a 26px
	   band of page-surface between every pair of sections — visible as a pale
	   stripe wherever two colored bands meet (sage against charcoal, most
	   obviously). The prototype has all nine sections flush, gap 0 throughout.
	   The section's own vertical rhythm comes from padding, not margin, so
	   zeroing this changes only the seams. Same fault as the grid-item margins
	   below, one level up the tree. */
	margin-block: 0;
}

/* The section's children need an explicit width, not just the max-width the
   constrained layout gives them. Without it they were sized to 1090 rather than
   filling to the 1124 cap — 34px narrow, and enough to make the crystal chips
   wrap. max-width still wins where a block sets its own (the centered heads stay
   at 680, the newsletter inner at 640). */
.cc > .cc-section > * {
	width: 100%;
}

/* Blocksy adds `margin-block-end: var(--theme-content-spacing)` (1.5em ≈ 22px)
   to the children of any flow or constrained layout. Gutenberg marks these grid
   wrappers `is-layout-flow`, so every grid ITEM was carrying 22px of bottom
   margin — invisible on its own, but it inflated each grid row from 53px to
   74.8px. That is what made "the library" look loosely spaced and stretched the
   "+ many more" tile taller than the chips beside it. The text was never
   wrapping; measured 165px into 180px of space on both sides.
   Zeroed here rather than in crystal-cleanse.css because it is a WordPress
   artifact, not a design decision.

   THIS KEEPS RECURRING. Any new wrapper laid out with grid or flex will hit it,
   because Gutenberg marks these wrappers `is-layout-flow` whatever the CSS does
   with them. Most recently .cc-about-note: the figure carried 25.5px of bottom
   margin, which showed as a band of white under the photograph and made the
   card 27px taller than its own image. Add new wrappers to this list. */
.cc .crystal-grid > *,
.cc .steps > *,
.cc .cc-blog-grid > *,
.cc .feat > *,
.cc .hero-grid > *,
.cc .ritual-grid > *,
.cc .saluxe-grid > *,
.cc .contact-grid > *,
.cc .cc-about-note > * {
	margin-block: 0;
}

/* The Contact page hits the same thing one level deeper. .contact-grid > *
   above zeroes the two COLUMNS; these are children of the columns, and of the
   group inside the left one. Measured on the live page: the mailto paragraph
   carried 25.5px, which collapsed over .cc-contact-note's own 8px margin-top
   and put 25.5px between the address and "We read everything." where the design
   wants 8. The form carried it too, which is why the privacy line sat 62px
   below the button instead of 14.4.

   margin-block-END, not the margin-block shorthand, and the difference is
   load-bearing. This file loads AFTER crystal-cleanse.css so its declarations
   win ties, and the shorthand also zeroed .cc-contact-note's own margin-top —
   the gap went from 25.5px straight past the intended 8 to 0. The wrappers
   above can use the shorthand because grid items have no top margin to
   protect; these do. */
.cc .cc-contact-body .contact-form,
.cc .cc-contact-direct > * {
	margin-block-end: 0;
}

/* The prototype carries `style="justify-self:start"` inline on this button; the
   port dropped it, so the submit stretched the full width of its grid column
   (592px against the prototype's 177px). */
.cc .contact-form .btn-primary {
	justify-self: start;
	width: auto;
}

/* Form control sizing ----------------------------------------------------------
   Blocksy sets an explicit `height: 40px` on inputs. With box-sizing:border-box
   that 40px has to absorb the design's own 15.2px vertical padding plus the 1px
   border, leaving ~7.6px for the text — so the field renders crushed, not
   narrow. The width was never wrong: 331px on both sides. Height auto lets the
   padding define the box, the way the prototype does.

   line-height:normal restores the browser default that form controls get. The
   prototype never sets one on them, so its inputs and its two <button>s size
   from `normal` while Blocksy inherits 1.6 from the body. Without this the
   controls come out 57px against the prototype's 52px.

   Note this makes the two FORM buttons 52px while the <a class="btn"> CTAs stay
   56px. That asymmetry is in the prototype too — a browser default rather than
   a decision — and matching it is what makes the newsletter row line up: input
   and "Join the List" are then the same height, which is the visible fault.

   Verified equal to the prototype: news input 52, news button 52, contact input
   52, textarea 132, submit 52. */
.cc .news input,
.cc .contact-form input,
.cc .contact-form textarea {
	height: auto;
	line-height: normal;
}
.cc button.btn {
	line-height: normal;
}

/* The newsletter micro-copy is shrunk twice ------------------------------------
   The pattern emits <p class="cc-news-small"><small>…</small></p>. The class
   sets the PARAGRAPH to .8rem (12.8px), but the text lives in the nested
   <small>, which the browser then shrinks again by its own ~0.8 factor — so it
   rendered at 10.24px against the prototype's 12.8px. The prototype has a
   single <small> carrying the class, with nothing nested inside it.
   Fixed here rather than by unwrapping the markup, because the markup lives in
   the database for any page already published — CSS reaches the live page,
   a pattern edit would not.
   Verified: rendered string width 416.86px, identical to the prototype. */
.cc .cc-news-small small {
	font-size: inherit;
}

/* `.cc a` resets links to plain text; the Privacy Policy link in the small
   print has to read as one (5 October 2026). */
.cc .cc-news-small a {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}
.cc .cc-news-small a:hover {
	color: var(--cc-accent);
}

/* Query Loop wrappers must not create their own layout boxes. A wp:query emits a
   <div> and its post-template emits a <ul>, either of which would sit between
   .cc-blog-grid and the cards and collapse the 3-column grid to a single column.
   display:contents removes both boxes so the post items become direct grid
   children. (This originally existed so a pinned loop and a latest loop could
   share one row; blog.php is a single loop now, but the wrappers still need
   flattening.) */
.cc .cc-blog-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
	margin-top: 8px;
}
.cc .cc-blog-grid .wp-block-query,
.cc .cc-blog-grid .wp-block-post-template {
	display: contents;
}
.cc .cc-blog-grid .wp-block-post-template {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Featured image fills the card thumb the way the prototype's gradients did.
   The .t1/.t2/.t3 gradients remain as the no-featured-image fallback. */
.cc .post .thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Gutenberg wraps buttons in its own elements; neutralize them so the
   prototype's .btn rules are what actually style the control. */
.cc .wp-block-button.btn .wp-block-button__link {
	all: unset;
	cursor: pointer;
}

/* The padding that draws the button is on Gutenberg's wrapper, so only the
   link's text was clickable: 97×24 inside a 175×56 button, measured live on
   29 September 2026 (issue #20). A ::after stretched over the wrapper makes the
   whole drawn button the link. The wrapper's own ::after is the arrow, a flex
   item; the link's is free. */
.cc .wp-block-button.btn {
	position: relative;
}
.cc .wp-block-button.btn .wp-block-button__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* all: unset also removed the browser's focus ring, so keyboard focus drew
   nothing. The ring goes on the wrapper, the shape a sighted user sees. */
.cc .wp-block-button.btn:has(.wp-block-button__link:focus-visible) {
	outline: 2px solid var(--cc-accent);
	outline-offset: 3px;
}
.cc .saluxe .wp-block-button.btn:has(.wp-block-button__link:focus-visible),
.cc .cc-about-cta .wp-block-button.btn:has(.wp-block-button__link:focus-visible),
.cc .dark .wp-block-button.btn:has(.wp-block-button__link:focus-visible) {
	outline-color: var(--cc-accent-on-dark);
}

/* App mockup images -----------------------------------------------------------
   Two renders of the same mockup, swapped at the breakpoint the CSS version
   used: above 760px both phones tilted, at/below 760px the front phone alone.
   Both are transparent WebP, so they must sit on the sage panel unflattened. */
.cc .cc-mockup {
	margin: 0;
}
.cc .cc-mockup img {
	width: 100%;
	height: auto;
	display: block;
}
.cc .cc-mockup--pair {
	display: block;
	max-width: 540px;
	margin-inline: auto;
}
.cc .cc-mockup--single {
	display: none;
	max-width: 410px;
	margin-inline: auto;
}

/* Feature list, text side ------------------------------------------------------
   The icon is handled in crystal-cleanse.css as a ::before in the item's
   padding gutter. What is left here is the difference in TEXT markup, which is
   a Gutenberg artifact rather than a design choice.

   The prototype nests <div><b>Term</b><p>desc</p></div>, so the <p> supplies
   both the line break and the smaller gray description style. core/list-item
   cannot nest a div or a p, so the pattern emits a flat
   <strong>Term</strong><br>description. Two consequences:

     1. Blocking <strong> to break the line makes the <br> a SECOND break, which
        opened a blank line between term and description. The <br> is redundant
        once <strong> is a block, so it is hidden rather than removed — the
        markup is in the database and cannot be edited from here.
     2. The description is a bare text node with nothing to select it by. So the
        <li> carries the description's type and <strong> is bumped back up to
        the term's, which is the inverse of how the prototype does it but lands
        on identical values.

   Palette 2 puts the term at 21px and description at 17px. Their resulting
   rendered height needs a preview check (issue #20). */
.cc .feat li {
	font-size: 17px;
	color: var(--cc-gray);
}
.cc .feat li br {
	display: none;
}
.cc .feat strong {
	display: block;
	font-size: 21px;
	font-weight: 600;
	color: var(--cc-ink);
	margin-bottom: 4px;
}

@media (max-width: 760px) {
	.cc .cc-blog-grid {
		grid-template-columns: 1fr;
	}
	.cc .cc-mockup--pair {
		display: none;
	}
	.cc .cc-mockup--single {
		display: block;
	}
	/* the CSS mockup reserved 540px of height; images size themselves */
	.cc .phones {
		min-height: 0;
	}
}

/* Blocksy styles wp-block-quote with a 4px left border in the accent color.
   The About page's signed note is a card, not a pull-quote — the mockup has no
   rule, and a violet bar down the inside of a white card reads as an error.
   Neutralized rather than restyled: this is a theme default leaking in, which
   is what this file is for. */
.cc .cc-about-note blockquote {
	border-left: 0;
	padding-left: 0;
	margin-left: 0;
}

/* Blocksy footer --------------------------------------------------------------
   Blocksy's builder owns the footer structure and responsive column layout.
   These rules carry only the approved visual refinements its controls cannot
   express precisely. The block and menu-item IDs come from the live WordPress
   database; if those builder items are recreated, re-check the IDs in the live
   DOM because a mismatch fails silently. */
#footer [data-row="middle"] {
	color: #DCD3E8;
	background: #1C1426;
}

#footer [data-row="middle"] #block-7 img {
	display: block;
	width: 217px;
	height: auto;
	max-width: 100%;
}

#footer [data-row="middle"] #block-8 {
	margin-top: 1rem;
}

#footer [data-row="middle"] #block-8 p {
	max-width: 34ch;
	margin: 0;
	color: #DCD3E8;
	font-size: 17px;
	line-height: 1.6;
}

#footer [data-row="middle"] #block-9 {
	margin-top: 12px;
}

#footer [data-row="middle"] #block-9 p {
	max-width: 34ch;
	margin: 0;
	/* onDarkSubtle is calculated at 6.95:1 on session and 3.80:1 on plum;
	   use it only on the flat footer ground (issue #20). */
	color: #A89DB8;
	font-family: Newsreader, Georgia, serif;
	font-size: 14px;
	line-height: 1.55;
}

#footer [data-row="middle"] #block-10 {
	margin-top: 20px;
}

#footer [data-row="middle"] #block-10 .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	padding: 12px 16px;
	border: 1px solid rgba(246, 242, 251, .45);
	border-radius: 14px;
	background: transparent;
	color: #F6F2FB;
	font-size: 17px;
	font-weight: 600;
	line-height: 1.6;
	transition: border-color .3s, transform .3s;
}

#footer [data-row="middle"] #block-10 .wp-block-button__link:hover {
	border-color: #CBB8EF;
	background: transparent;
	color: #F6F2FB;
	transform: translateY(-2px);
}

#footer [data-row="middle"] #block-10 .wp-block-button__link:focus-visible,
#footer [data-row="middle"] .widget_nav_menu a:focus-visible {
	outline: 2px solid #CBB8EF;
	outline-offset: 3px;
}

#footer [data-row="middle"] .widget_nav_menu .widget-title {
	margin: 0 0 16px;
	color: #A89DB8;
	font-family: "Rethink Sans", sans-serif;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: .18em;
	text-transform: uppercase;
}

/* Each standalone link needs a 44px target. At the new 17px size and 1.55
   line-height, 11px vertical padding gives a calculated 48.35px box.
   The negative margins retain the existing spacing; their previous alignment
   measurement was made at the old type size and needs preview review. */
#footer [data-row="middle"] .widget_nav_menu ul {
	display: grid;
	gap: 0;
	margin: -7px 0 -11px;
	padding: 0;
	list-style: none;
}

#footer [data-row="middle"] .widget_nav_menu a {
	display: block;
	width: fit-content;
	padding-block: 11px;
	color: #DCD3E8;
	font-size: 17px;
	line-height: 1.55;
	text-decoration: none;
	transition: color .25s;
}

#footer [data-row="middle"] .widget_nav_menu a:hover {
	color: #F6F2FB;
}

/* Menu item 103 is intentionally brighter than the topic links so the route
   out to the full archive reads as a separate action. */
#footer [data-row="middle"] #menu-item-103 a {
	color: #F6F2FB;
}

/* Blocksy adds 16px inside its Socials element. An 8px outer margin therefore
   produces the approved 24px visible gap from the Saluxe button to the icons. */
#footer [data-row="middle"] #block-11 {
	margin-top: .5rem;
}

/* The divider belongs to Blocksy's bottom row, not the middle-row columns; this
   keeps it flush with the legal strip without fighting the row's own spacing. */
#footer [data-row="bottom"] {
	border-top: 1px solid rgba(246, 242, 251, .08);
	background: #1C1426;
}

#footer [data-row="bottom"] .ct-container {
	padding-top: 28px;
	padding-bottom: 36px;
}

#footer [data-row="bottom"] .ct-footer-copyright,
#footer [data-row="bottom"] .ct-footer-copyright a,
#footer [data-row="bottom"] #footer-menu a {
	color: #A89DB8;
	font-size: 14px;
	font-weight: 400;
	line-height: 1.3;
	letter-spacing: .01em;
}

#footer [data-row="bottom"] .ct-footer-copyright p {
	margin: 0;
}

#footer [data-row="bottom"] .ct-footer-copyright a,
#footer [data-row="bottom"] #footer-menu a {
	transition: color .25s;
}

#footer [data-row="bottom"] .ct-footer-copyright a:hover,
#footer [data-row="bottom"] #footer-menu a:hover {
	color: #F6F2FB;
}

#footer [data-row="bottom"] .ct-footer-copyright a:focus-visible,
#footer [data-row="bottom"] #footer-menu a:focus-visible {
	outline: 2px solid #CBB8EF;
	outline-offset: 3px;
}

@media (max-width: 689px) {
	#footer [data-row="bottom"] .ct-container {
		row-gap: 20px;
	}

	#footer [data-row="bottom"] [data-column="menu"] {
		align-items: flex-start;
	}

	#footer [data-row="bottom"] #footer-menu .menu {
		justify-content: flex-start;
	}
}

/* -----------------------------------------------------------------------------
 * The production note appended to single guide articles by cc_append_ai_note()
 * in functions.php.
 *
 * It is styled here rather than in crystal-cleanse.css because a single post's
 * content is not inside the .cc wrapper, so none of the --cc-* custom
 * properties resolve there. The two colors below are those tokens written out,
 * not new values: #423C4B is --cc-gray and #E1DBE9 is --cc-line-soft. If the
 * tokens change, change these with them — nothing links the two.
 *
 * Gray remains the note role (decisions 3 and 7). On the palette-2 surface,
 * gray calculates to 9.54:1. The WordPress post background must still be
 * updated through Blocksy before that ratio describes the rendered page.
 *
 * The note uses the body text's 17px Rethink Sans so it is easy to read, set
 * in italic so it reads as a note, not the article's last paragraph (Henrik
 * chose this over regular sans and over 17px Newsreader italic, whose smaller
 * letters still looked like small print; 10 October 2026). Rethink Sans
 * italic 400 is a real loaded face, not a slant the browser fakes.
 * -------------------------------------------------------------------------- */

.cc-ai-note {
	padding-top: 20px;
	border-top: 1px solid #E1DBE9;
	font-family: "Rethink Sans", sans-serif;
	font-style: italic;
	font-size: 17px;
	line-height: 1.55;
	color: #423C4B;
}

/*
 * The gap above the note needs .entry-content in front of the class, and that
 * extra specificity is the entire point of the rule. This stylesheet is
 * enqueued BEFORE Blocksy's main.min.css, so a bare .cc-ai-note (0,1,0) loses
 * every specificity tie to Blocksy's own flow spacing on the entry content —
 * margin-top then computes to 0 with nothing overriding it visibly and no
 * !important anywhere to find. Measured on the live page: the rule above on its
 * own left a 25.5px gap, which is the previous paragraph's margin-bottom, not
 * the 48px asked for here.
 *
 * Kept as a separate rule on purpose. If Blocksy ever renames .entry-content,
 * the note loses its spacing and keeps everything else, rather than losing all
 * of its styling at once.
 */
.entry-content .cc-ai-note {
	margin-top: 48px;
}

/* The review credit is a sentence in the article's gray, not a second
   byline row: in Blocksy's uppercase 600 meta style, on a line of its own,
   it read as a stray piece of that row (Henrik chose option B, 3 October
   2026). 14px is the small-print step, as in the byline.
   Blocksy leaves 40px after the title/byline area; 12px above and 24px
   below keep the credit with the byline rather than the article.
   Colors are the --cc-* tokens written out (see the AI note above):
   gray #423C4B on the palette-2 surface is 9.54:1, accent #4B3A73 8.78:1,
   ink #1F1A27 15.29:1. The link sits in a sentence, so the 44px target
   floor does not apply; its underline is the non-color affordance. */
body.single-post .hero-section:has(+ .cc-review-credit) {
	margin-bottom: 12px;
}

body.single-post .cc-review-credit {
	margin: 0 0 24px;
	font-size: 14px;
	font-weight: 400;
	line-height: 1.45;
	color: #423C4B;
}

body.single-post .cc-review-credit a {
	font-weight: 600;
	color: #4B3A73;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

body.single-post .cc-review-credit a:hover {
	color: #1F1A27;
}

/* Links in the author box bio (the profile's Biographical Info) get the
   underline that article links already have; Blocksy gave them the accent
   color only, which read as plain text (Henrik, 4 October 2026). Hover is
   ink, as for the review credit. */
body.single-post .author-box-bio a {
	text-decoration: underline;
}

body.single-post .author-box-bio a:hover {
	color: #1F1A27;
}

/* Blog tables use Gutenberg's existing Table block, so a theme rule reaches
   published posts without changing their blocks. The single-post scope keeps
   the landing and other pages out of it. These colors mirror the shared design
   values; article content sits outside .cc, where the --cc-* tokens are defined.
   The three-column minimum width keeps the explanation readable on phones;
   the figure scrolls horizontally rather than compressing all three columns. */
body.single-post .entry-content figure.wp-block-table {
	margin-block: 2rem 2.25rem;
	overflow-x: auto;
	border: 1px solid #E1DBE9;
	border-radius: 18px;
	background: #FFFFFF;
}

body.single-post .entry-content figure.wp-block-table table {
	width: 100%;
	border: 0 !important;
	border-collapse: collapse;
}

body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) {
	min-width: 620px;
	table-layout: fixed;
}

body.single-post .entry-content figure.wp-block-table th,
body.single-post .entry-content figure.wp-block-table td {
	border: 0 !important;
	padding: 12px 16px;
	text-align: left;
	vertical-align: top;
	font-size: 17px;
	line-height: 1.5;
}

body.single-post .entry-content figure.wp-block-table th {
	background: #E9E4F0;
	color: #1F1A27;
	font-weight: 700;
	border-bottom: 2px solid #E1DBE9 !important;
}

body.single-post .entry-content figure.wp-block-table tbody tr:nth-child(even) td {
	background: #F4F2F7;
}

body.single-post .entry-content figure.wp-block-table tbody tr:not(:last-child) td {
	border-bottom: 1px solid #E1DBE9 !important;
}

body.single-post .entry-content figure.wp-block-table td:first-child,
body.single-post .entry-content figure.wp-block-table.cc-table-verdict td:nth-child(2) {
	font-weight: 600;
	color: #1F1A27;
}

/* Two shapes of three-column table (functions.php, cc_mark_verdict_table()).
   A verdict table keeps a narrow, semibold middle column beside a wide
   explanation; a table with sentences in both later columns splits them
   evenly, in body weight. Before 6 October 2026 every table had the verdict
   layout, which squeezed the sound guide's instructions into 19% in bold. */
body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) th:first-child,
body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) td:first-child {
	width: 23%;
}

body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) th:nth-child(2),
body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) td:nth-child(2),
body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) th:nth-child(3),
body.single-post .entry-content figure.wp-block-table table:has(tr > :nth-child(3):last-child) td:nth-child(3) {
	width: 38.5%;
}

body.single-post .entry-content figure.wp-block-table.cc-table-verdict table:has(tr > :nth-child(3):last-child) th:nth-child(2),
body.single-post .entry-content figure.wp-block-table.cc-table-verdict table:has(tr > :nth-child(3):last-child) td:nth-child(2) {
	width: 19%;
}

body.single-post .entry-content figure.wp-block-table.cc-table-verdict table:has(tr > :nth-child(3):last-child) th:nth-child(3),
body.single-post .entry-content figure.wp-block-table.cc-table-verdict table:has(tr > :nth-child(3):last-child) td:nth-child(3) {
	width: 58%;
}

/* -----------------------------------------------------------------------------
 * Mobile menu panel (Henrik, 6 October 2026)
 *
 * The Customizer does most of it: Off Canvas reveals as a full-screen Modal
 * and holds the Off Canvas Logo (34px), Mobile Menu 1 and the header Button;
 * the menu's Items Vertical Spacing is 8px and its Items Divider is 1px
 * `line` #E1DBE9 (BLOCKSY-SETUP.md, Header). What its controls cannot do is
 * here, so the panel opens over the header and repeats its row.
 *
 * The row: the logo and the close button sit where the header's logo and menu
 * button are, measured on the live site at 375 and 820px. The header's Main
 * Row is 78px and its content runs at Blocksy's container edge, 88vw on
 * phones and 90vw on tablets, which --theme-container-edge-spacing carries.
 * The logo's top is 22px; the 44px close button's top is 17px and its right
 * edge 13px past the container's, centering it on the 18px menu icon.
 * -------------------------------------------------------------------------- */

#offcanvas[data-behaviour="modal"] {
	--cc-panel-edge: calc((100vw - var(--theme-container-edge-spacing)) / 2);
}
#offcanvas[data-behaviour="modal"] .ct-panel-actions {
	position: absolute;
	top: 17px;
	inset-inline-end: calc(var(--cc-panel-edge) - 13px);
	z-index: 1;
	padding: 0;
}
/* Blocksy draws it 32 × 32 with -10px margins; this is the 44px target. */
#offcanvas[data-behaviour="modal"] .ct-toggle-close {
	width: 44px;
	height: 44px;
	margin: 0;
}
#offcanvas[data-behaviour="modal"] .ct-panel-content-inner {
	padding: 22px var(--cc-panel-edge) 32px;
}
/* 30px below the 34px logo puts the first link at 86px, 8px under the row.
   Blocksy's `#offcanvas .ct-panel-content-inner > *` sets every item's margin
   at the same specificity and loads later, hence body here and on the button
   (measured live 6 October 2026: 20px and 0px without it). */
body #offcanvas [data-id="offcanvas-logo"] {
	margin-bottom: 30px;
}

/* Blocksy 2 writes the Items Divider into --mobile-menu-divider but ships no
   rule that draws it (checked 6 October 2026: no stylesheet on the page reads
   the variable), so the Customizer value is drawn here, between the links. */
#offcanvas .mobile-menu > ul > li + li {
	border-top: var(--mobile-menu-divider);
}

/* "Open the App" as the panel's main action: the full row width, 48px tall.
   Its color, type and 14px radius stay the header button's. */
body #offcanvas [data-id="button"] {
	align-self: stretch;
	margin-top: 12px;
}
#offcanvas [data-id="button"] .ct-button {
	width: 100%;
	min-height: 48px;
}

/* -----------------------------------------------------------------------------
 * 44px targets on Blocksy's own controls (issue #20)
 *
 * design-system.md sets 44 × 44 CSS px as the house minimum for every
 * standalone control; a link inside a sentence is exempt. These were measured
 * short on the live site on 29 September 2026, at 390 and 1440 px.
 *
 * Where a control is already drawn at its approved size, an invisible ::after
 * stretches its clickable area instead, so nothing on the page moves. Each one
 * was checked to have no ::after of its own. This file loads before Blocksy's
 * main.min.css and loses specificity ties to it, hence the body prefix where a
 * rule overrides a Blocksy value.
 *
 * Not reachable here: the byline avatar on single posts (25px) clips its own
 * overflow, so it cannot carry an extension; the author's name beside it is
 * the same link.
 * -------------------------------------------------------------------------- */

/* Mobile menu button: an 18px icon. */
.ct-header-trigger::after {
	content: "";
	position: absolute;
	inset: -13px;
}

/* Header search button: an 18px icon (added 5 October 2026). */
.ct-header-search {
	position: relative;
}
.ct-header-search::after {
	content: "";
	position: absolute;
	inset: -13px;
}
/* On phones it sits beside the menu button, whose own target is drawn later and
   would take 7px of this one; 16px between them leaves both 44 × 44 (measured
   at 390px, 5 October 2026). */
#header [data-device="mobile"] .ct-header-search {
	margin-inline-end: 16px;
}

/* Logo: 125 × 34. */
.site-branding .site-logo-container::after {
	content: "";
	position: absolute;
	inset: -5px 0;
}

/* Header "Open the App": 38px tall; its ::before is Blocksy's. */
.ct-header-cta .ct-button::after {
	content: "";
	position: absolute;
	inset: -3px 0;
}

/* Desktop menu: "About" is 43px wide. The items sit 25px apart. */
header .ct-menu-link::after {
	content: "";
	position: absolute;
	inset: 0 -4px;
}

/* Cookie notice buttons: 35px tall. */
.cookie-notification .ct-button::after {
	content: "";
	position: absolute;
	inset: -5px 0;
}

/* Footer social icon colors. The Socials block saves no color of its own, so the
   icons fell back to the body-text color; when palette 2 made that #423C4B (29
   September 2026) they sank to about 1.8:1 on the footer's #1C1426, and the
   hover color was darker still. onDarkSubtle #A89DB8 (6.95:1), as the footer
   headings; #F6F2FB on hover (5 October 2026). */
#footer .ct-social-box a {
	--theme-icon-color: #A89DB8;
	--theme-icon-hover-color: #F6F2FB;
}

/* Footer social icons: 43 × 43. */
#footer .ct-social-box a {
	position: relative;
}
#footer .ct-social-box a::after {
	content: "";
	position: absolute;
	inset: -1px;
}

/* Legal row: the new 14px text at 1.3 line-height is 18.2px high. The 14px
   extension on each side gives a calculated 46.2px target; row spacing keeps
   neighboring targets apart. Rendered geometry still needs preview review. */
#footer [data-row="bottom"] #footer-menu a::after {
	content: "";
	position: absolute;
	inset: -14px 0;
}

/* Blocksy's inline-block byline items can wrap only about one text line apart,
   making their padded link targets overlap. Flex keeps its item separators,
   margins and shared text baseline; the calculated 28px row gap equals the
   links' vertical padding (18px + 10px), leaving each wrapped row its own
   target space. A single row gets no gap. Archive cards only: on a single
   post the gap pushed a wrapped category far below the author on phones, and
   Henrik chose Blocksy's own wrap there (3 October 2026; see the padding rule
   below). */
body .entry-card .entry-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	row-gap: 28px;
}

/* The byline links keep 18px above and 10px below their text: the archive card
   title sits 25px below, and its target needs 8px of that gap. Inline padding
   leaves the one-line byline height and title position unchanged. */
body .entry-meta a:not(.ct-media-container-static) {
	padding-block: 18px 10px;
}

/* A single post's byline wraps as Blocksy sets it, rows 23px apart (text 18px,
   5px between). The target leans up instead: 4px below the text stops the
   author's target at the category's first text line, so a tap anywhere on
   the category text opens the category; 22px above keeps 44px. Measured on
   the live first-session guide at 390px, 3 October 2026: author 605-649,
   category text from 650, hit-tested in steps of 2px. The 22px reaches 2px
   into the 20px above the byline, where the title is not a link. On one line
   nothing moves. */
body.single-post .entry-meta a:not(.ct-media-container-static) {
	padding-block: 22px 4px;
}

/* The author's name is 41px wide; widened without moving the byline. */
body .entry-meta .ct-meta-element-author {
	position: relative;
}
body .entry-meta .ct-meta-element-author::after {
	content: "";
	position: absolute;
	inset: 0 -3px;
}

/* Post titles in the archive cards and the sidebar's latest posts are links in
   a list, and a two-line title left gaps beside its shorter line. Inline-block
   makes the whole text block the target; the padding reaches 44px on a single
   line, and the equal negative margin gives it back so nothing moves. It leans
   downward to clear the byline's target above. */
body .entry-card .entry-title a,
body .wp-block-latest-posts__post-title {
	display: inline-block;
	padding-block: 8px 14px;
	margin-block: -8px -14px;
}

/* Single post: share buttons (35px) and previous / next (28px on phones). */
.ct-share-box a,
.post-navigation .nav-item-prev,
.post-navigation .nav-item-next {
	position: relative;
}
.ct-share-box a::after {
	content: "";
	position: absolute;
	inset: -5px 0;
}
.post-navigation .nav-item-prev::after,
.post-navigation .nav-item-next::after {
	content: "";
	position: absolute;
	inset: -8px 0;
}

/* Author box: the website icon (30px) and the article count (18px). */
.author-box .author-box-socials a,
.author-box .ct-author-box-more {
	position: relative;
}
.author-box .author-box-socials a::after {
	content: "";
	position: absolute;
	inset: -7px;
}
.author-box .ct-author-box-more::after {
	content: "";
	position: absolute;
	inset: -13px 0;
}

/* Sidebar search: 40px tall field and button. */
body .wp-block-search__input,
body .wp-block-search__button {
	min-height: 44px;
}

/* Sidebar category and archive lists: 22px links on a 28px pitch, so the pitch
   grows as the footer's did. The negative margin keeps the first link where
   it was. */
body .wp-block-categories-list,
body .wp-block-archives-list {
	margin-block: -8px;
}
body .wp-block-categories-list a,
body .wp-block-archives-list a {
	display: inline-block;
	padding-block: 8px;
	line-height: 28px;
}

/* Guide sidebar ----------------------------------------------------------------
   Since 5 October 2026 the Main Sidebar holds, in order: an app card, Guides by
   Topic (a Categories block) and a Saluxe card. Search moved to the header the
   same day. The cards are core blocks in block widgets, so they
   stay editable in Appearance → Widgets; these rules give them the landing
   page's look outside `.cc`, so the values are written out. The sidebar shows
   above 1000px only, at 303px; Mediavine's sidebar ad needs at least 300px.
   The Saluxe card's sentence describes the amethyst shop (issue #1); when the
   box is ready, swap its image, sentence and link and keep the card. */
#sidebar .cc-side-app > *,
#sidebar .cc-side-topics > *,
#sidebar .cc-side-saluxe-text > * {
	margin: 0;
}
#sidebar .cc-side-eyebrow {
	font-weight: 600;
	font-size: 14px;
	letter-spacing: .2em;
	text-transform: uppercase;
	margin-bottom: 10px;
}

#sidebar .cc-side-app {
	background: linear-gradient(165deg, #4B3A73 0%, #1C1426 100%);
	border-radius: 18px;
	padding: 28px 26px;
	color: #DCD3E8;
}
#sidebar .cc-side-app .cc-side-eyebrow {
	color: #CBB8EF;
}
#sidebar .cc-side-app h3 {
	font-size: 27px;
	line-height: 1.12;
	color: #F6F2FB;
	margin-bottom: 12px;
}
#sidebar .cc-side-app h3 em {
	color: #CBB8EF;
}
#sidebar .cc-side-app p {
	font-size: 16px;
	line-height: 1.55;
	color: #DCD3E8;
}
#sidebar .cc-side-app .cc-side-cta {
	margin-top: 20px;
}
#sidebar .cc-side-btn {
	display: block;
	text-align: center;
	background: #F6F2FB;
	color: #1F1A27;
	font-weight: 600;
	font-size: 17px;
	border-radius: 14px;
	padding: 12px 18px;
	text-decoration: none;
}
#sidebar .cc-side-btn:hover {
	background: #FFFFFF;
	color: #1F1A27;
}

#sidebar .cc-side-topics h3 {
	font-size: 27px;
	margin-bottom: 8px;
}
#sidebar .cc-side-topics ul {
	list-style: none;
	margin: 0;
	padding: 0;
}
#sidebar .cc-side-topics li {
	margin: 0;
	border-top: 1px solid #E1DBE9;
}
#sidebar .cc-side-topics li:last-child {
	border-bottom: 1px solid #E1DBE9;
}
/* Each row is a 44px+ target: 11px padding around the 17px text. */
#sidebar .cc-side-topics a {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 11px 0;
	font-size: 17px;
	color: #423C4B;
	text-decoration: none;
}
#sidebar .cc-side-topics a::after {
	content: "→";
	color: #877A9E;
}
#sidebar .cc-side-topics a:hover {
	color: #4B3A73;
}

#sidebar .cc-side-saluxe {
	display: flex;
	gap: 16px;
	align-items: center;
	background: #E9E4F0;
	border-radius: 18px;
	padding: 20px 22px 20px 18px;
}
#sidebar .cc-side-saluxe > * {
	margin: 0;
}
#sidebar .cc-side-saluxe figure {
	flex: none;
}
#sidebar .cc-side-saluxe img {
	width: auto;
	height: 118px;
	filter: drop-shadow(0 10px 14px rgba(28, 20, 38, .35));
}
#sidebar .cc-side-saluxe .cc-side-eyebrow {
	color: #4B3A73;
}
#sidebar .cc-side-saluxe p {
	font-size: 15px;
	line-height: 1.5;
	color: #423C4B;
}
#sidebar .cc-side-saluxe .cc-side-link {
	margin-top: 10px;
}
/* A standalone link: inline padding gives it 44px without moving the line. */
#sidebar .cc-side-saluxe .cc-side-link a {
	padding-block: 11px;
	font-weight: 600;
	font-size: 16px;
	color: #4B3A73;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}
