/* ==========================================================================
   Aspiring Quotes — Ghost theme  (aspiringquotes.com)

   GENERATED FILE — DO NOT EDIT BY HAND.
   Source:    wisdom-quotes-and-stories v3.6.0 assets/css/screen.css
   Generator: output/ghost-fleet-port-v3/gen/build.js
   Built:     2026-08-06

   To change the DESIGN, change the master and re-run the generator. To change
   this SITE's colours, change its entry in gen/sites.js and re-run. A hand edit
   here survives exactly until the next port and is then silently gone.

   ────────────────────────────────────────────────────────────────────────────
   READ THIS BEFORE TRUSTING A NUMBER IN A COMMENT BELOW.

   Every contrast figure in the prose comments in this file was written for
   wisdomquotesandstories.com and describes ITS palette — navy #022A5C, ocean
   #0072A1, apricot #FFCD9C. They are kept because the REASONING they carry is
   what makes this stylesheet maintainable, and that reasoning is palette-
   independent. The NUMBERS are not.

   The measured figures for aspiringquotes.com are the table inside the
   :root block below, computed from this site's own values at build time. Where
   a prose comment and that table disagree, the table is right.

   This is the third time this fleet has been bitten by a copied contrast
   comment reading as a verified measurement. Stating it once, loudly, is the
   fix that scales.
   ========================================================================== */

/* ==========================================================================
   SELF-HOSTED WEBFONTS — added 2026-08-05
   --------------------------------------------------------------------------
   Until now this theme shipped NO font files and no @font-face, and the site's
   Ghost heading_font/body_font settings are empty — so it rendered in whatever
   system font the visitor happened to have. The WordPress theme this site
   replaced self-hosted Poppins and Lora; that typographic identity was dropped
   at migration, on this site and on all eleven others.

   Both faces are SIL OFL. Served from the theme, never fonts.googleapis.com —
   a third-party stylesheet on the critical path costs a DNS lookup, a TLS
   handshake and a round trip before the first byte of font CSS arrives, and it
   hands the visitor's IP to a third party on every page view.

   Only latin and latin-ext ship. unicode-range means latin-ext downloads only
   if a page actually contains a character in it. Lora is the variable release,
   so 400..700 is one file; Poppins has no variable release, so 600 and 700 are
   separate. Per page that is ~50 KB, not the 138 KB on disk.

   THE FALLBACK METRICS ARE MEASURED, NOT GUESSED. font-display:swap trades
   FOIT for CLS — text paints in the fallback then reflows when the webfont
   lands. Rendering both faces at 200px and comparing advance widths gave:

       Lora    vs Georgia    103.1%   (x-height 104.2%)  <- chosen
       Lora    vs Times      112.0%
       Poppins vs Arial      112.7%   (x-height 106.7%)  <- chosen
       Poppins vs Segoe UI   113.0%

   Georgia sits within 3.1% of Lora, which is why it leads the serif stack.
   size-adjust closes the remainder so the swap barely moves the text.
   ========================================================================== */

/* Lora — body copy and the quotations. Variable, 400..700. */
@font-face{ font-family:'Lora'; font-style:normal; font-weight:400 700; font-display:swap;
  src:url('../fonts/lora-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Lora'; font-style:normal; font-weight:400 700; font-display:swap;
  src:url('../fonts/lora-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face{ font-family:'Lora'; font-style:italic; font-weight:400 700; font-display:swap;
  src:url('../fonts/lora-italic-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Lora'; font-style:italic; font-weight:400 700; font-display:swap;
  src:url('../fonts/lora-italic-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* Poppins — headings and UI. No variable release, so 600 and 700 are separate. */
@font-face{ font-family:'Poppins'; font-style:normal; font-weight:600; font-display:swap;
  src:url('../fonts/poppins-600-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Poppins'; font-style:normal; font-weight:600; font-display:swap;
  src:url('../fonts/poppins-600-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face{ font-family:'Poppins'; font-style:normal; font-weight:700; font-display:swap;
  src:url('../fonts/poppins-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Poppins'; font-style:normal; font-weight:700; font-display:swap;
  src:url('../fonts/poppins-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* Metric-matched fallbacks. These carry the MEASURED ratios above, so the
   swap-in barely moves the text instead of reflowing the page. */
@font-face{ font-family:'Lora Fallback'; src:local('Georgia'), local('Times New Roman');
  size-adjust:103.1%; ascent-override:100.5%; descent-override:27.5%; }
@font-face{ font-family:'Poppins Fallback'; src:local('Arial'), local('Helvetica');
  size-adjust:112.7%; ascent-override:105.0%; descent-override:35.0%; }

:root {
    /* --- PALETTE — this site's own brand kit, not the master's ---------------

       GENERATED. Regenerate with output/ghost-fleet-port-v3/gen/build.js rather
       than editing here; a hand edit is lost on the next port and, worse, it
       will not be re-measured.

       MEASURED FOR aspiringquotes.com, at build time, against the three grounds
       these colours actually land on. This table is the authority for this file:
       every other contrast figure in the comments below came from the master
       stylesheet and describes wisdomquotesandstories.com, not this site.

       role            colour     page #FFFFFF   card #FBFBF9   footer #03203A
       -------------------------------------------------------------------------
       ink             #0A1A2F    17.48:1       16.87:1         1.06:1
       title           #03203A    16.51:1       15.94:1         1.00:1
       accent          #0F4661    10.15:1        9.80:1         1.63:1
       muted           #2B5D72     7.21:1        6.96:1         2.29:1
       accent-alt      #86714E     4.68:1        4.52:1         3.53:1
       focus ring      #2B5D72     7.21:1        6.96:1         2.29:1
       white on foot   #FFFFFF         —            —        16.51:1
       foot focus      #F4CD8E         —            —        10.99:1
       pill hover ink  #03203A  on #F4CD8E   10.99:1

       AA for body text is 4.5:1. WCAG 1.4.11 asks 3:1 of a focus ring and of a
       control's edge — a lower bar, deliberately, and the reason the focus ring
       is allowed on grounds where text in the same colour would not be.         */

    --aq-ink:           #0A1A2F;  /* body ink, borders, the dark half of the brand */
    --aq-ink-strong:    #03203A;  /* darkest brand ink — link hover, footer ground */
    --aq-title:         #03203A;  /* every heading on a light ground */
    --aq-accent:        #0F4661;  /* links, chips, pills, buttons, focus, nav hover */
    --aq-accent-alt:    #86714E;  /* the accent-deep body variant; form errors */
    --aq-muted:         #2B5D72;  /* meta, bylines, the header tagline */
    --aq-focus:         #2B5D72;  /* page focus ring — 1.4.11 wants 3:1, not 4.5 */
    --aq-tint:          #FDF8EC;  /* pale fill that takes dark ink */
    --aq-surface:       #FBFBF9;  /* card face, wells, the related band */
    --aq-paper:         #FFFFFF;  /* page ground */
    --aq-white:         #FFFFFF;
    --aq-text:          var(--aq-ink);

    /* THE HEADER IS WHITE AND THE FOOTER IS THE BRAND'S DARKEST INK.
       Until 2026-08-06 these were the same near-black bar at both ends of the
       page. The master moved its header to white and its footer to the mark's
       own ink, and this port follows it.

       THAT MADE THE NAV HOVER A PAIR CHANGE, AND IT IS THE ONE THAT BITES.
       This site's previous nav hover was #F4CD8E — chosen as a LIGHT ink on a
       near-black bar, where it measures 10.99:1. On a white bar the same
       colour is 1.50:1: invisible. So the header's hover is now the
       accent (10.15:1 on white) and #F4CD8E survives only below, where it
       is still sitting on the ground it was measured against. */
    --aq-head:          #FFFFFF;  /* header ground */
    --aq-foot:          #03203A;  /* footer ground — white on it is 16.51:1 */
    --aq-foot-focus:    #F4CD8E;  /* footer focus ring — 10.99:1 on the footer */
    --aq-pillhover:     #F4CD8E;  /* footer tag-pill hover fill */
    --aq-pillink:       #03203A;  /* and its ink — 10.99:1 on that fill */

    /* Hairlines and shadows are the ink at low alpha, so they follow the brand
       instead of being a neutral grey laid over it. Kept as an RGB triplet
       because rgba() cannot take a hex custom property. */
    --aq-ink-rgb:       10,26,47;

    --wrap:      1180px;
    --wrap-narrow: 720px;
    --radius:    10px;
    --gap:       clamp(1rem, 2.5vw, 1.75rem);
    --tap:       44px;         /* WCAG 2.5.8 target size                  */

    /* Ghost still injects --gh-font-heading / --gh-font-body if an owner picks a
       font in admin, and that must keep winning — it is the site owner's choice.
       Poppins for display, Lora for body, self-hosted from this theme. */
    --font-body: var(--gh-font-body, 'Lora', 'Lora Fallback', Georgia, "Iowan Old Style", "Times New Roman", serif);
    --font-head: var(--gh-font-heading, 'Poppins', 'Poppins Fallback', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif);

    --shadow-sm: 0 1px 2px rgba(var(--aq-ink-rgb),.06), 0 2px 8px rgba(var(--aq-ink-rgb),.05);
    --shadow-md: 0 4px 16px rgba(var(--aq-ink-rgb),.10);
}

body.accent-deep { --aq-accent: var(--aq-accent-alt); }

/* --- reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0;
    background: var(--aq-paper);
    color: var(--aq-text);
    font-family: var(--font-body);
    font-size: 1.0625rem;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
/* <picture> defaults to display:inline, which would become the img's containing
   block and break every rule below that sizes or centres the img directly
   (.quote-card-img height:100%, .post-media img margin-inline:auto). */
picture { display: block; }
a { color: var(--aq-accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
/* Hover DARKENS toward the brand ink rather than shifting hue: ocean-ink 5.36:1
   at rest -> navy-true 14.11:1 on hover. Plum #4C1656 was the old pair to the
   amethyst accent and is the same violet family that has just been removed
   everywhere else. */
a:hover { color: var(--aq-ink-strong); }
h1, h2, h3, h4 { font-family: var(--font-head); line-height: 1.22; color: var(--aq-title); margin: 0 0 .5em; }

/* WCAG 1.4.11 asks 3:1 of a focus indicator, not the 4.5:1 a text colour needs.
   outline-offset puts a 2px gap between the ring and the element, so the ring's
   neighbour on both sides is the container background, never a button fill —
   which is why the ring on an --aq-brown button is not the comparison that
   matters. RE-MEASURED 2026-08-05 for the badge palette: --aq-rust-ink is now
   the ocean ink #0072A1, and it rings at 5.36:1 on the white page, 5.04:1 on a
   card and 3.69:1 on the apricot .sections band — the band figure STILL clears
   the 3:1 that 1.4.11 asks, so the ring is correct on a band where TEXT in the
   same colour (3.69, under 4.5) is not. That is precisely why 1.4.11 and 1.4.3
   set different thresholds, and why the band rule above constrains text without
   touching the focus ring.
   Twice now this comment has carried another palette's numbers and read as
   verified — first an orange-on-cream pair from a different site, then the
   violet 4.83/3.19 set from the wrong logo. Re-measure it on every repalette. */
:focus-visible {
    outline: 3px solid var(--aq-accent);
    outline-offset: 2px;
    border-radius: 3px;
}

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--aq-ink); color: var(--aq-white); padding: .75rem 1.25rem;
}
.skip-link:focus { left: 0; }

.wrap { width: min(100% - 2rem, var(--wrap)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 2rem, var(--wrap-narrow)); }

/* --- header ------------------------------------------------------------- */
/* HEADER GROUND CHANGED AGAIN 2026-08-06, by request: #300060 -> WHITE.
   History of this one bar: white -> #300050 (v1.7.1) -> #300060 (v2.0.0) ->
   white. A turn to white was also asked for and withdrawn mid-turn at v1.9.1,
   so this is the second time it has been requested and the first time it ships.

   THE SAME RULE APPLIES IN REVERSE, AND IT IS THE WHOLE OF THIS CHANGE. Every
   element in this bar had been re-inked to WHITE-ON-VIOLET at v1.7.1. On a white
   ground those inks measure:

     .site-title       --aq-white  #FFFFFF   1.00:1   invisible
     .site-tagline     --aq-white  #FFFFFF   1.00:1   invisible
     nav links         --aq-white  #FFFFFF   1.00:1   invisible
     nav hover         #FFCB9A                1.44:1   invisible
     .nav-toggle-bar   --aq-white  #FFFFFF   1.00:1   invisible
     .nav-toggle-label --aq-white  #FFFFFF   1.00:1   invisible
     header icons      --aq-white  #FFFFFF   1.00:1   invisible
     borders           rgba(255,255,255,.12-.30)        invisible

   Repointing the background alone would have produced an empty white strip with
   a logo in it. Changing the ground is never the change; it is half of a pair.

   WHICH COLOURS THE BAR TAKES NOW — the request was "brandkit colours according
   to logo", so the inks below are the MEASURED palette from the 1600x1600 badge
   (Brand Kit/02-Color/palette.md), not the #300050/#300060/#FFCB9A literals that
   had accumulated here. None of those three appears anywhere in the artwork:
   #300060 was specified by hand, and the violet family entered this theme from a
   palette built off a derived wordmark that was later superseded. The badge is
   navy silhouette, sky, ocean and apricot. So on white:

     .site-title       --aq-ink       #022A5C  14.11:1  AAA   the mark's own ink
     .site-tagline     --aq-ink-soft  #4C6F81   5.39:1  AA    the kit's secondary
     nav links         --aq-ink       #022A5C  14.11:1  AAA
     nav hover         --aq-ocean-ink #0072A1   5.36:1  AA    the working ocean
     nav hover pill    --aq-sky       #C5EAFF    fill         + navy ink 11.14:1
     .nav-toggle-bar   --aq-ink       #022A5C  14.11:1        (needs 3:1)
     .nav-toggle-label --aq-ink       #022A5C  14.11:1  AAA
     header icons      --aq-ink       #022A5C  14.11:1
     icon hover        --aq-sky fill + --aq-ink glyph        11.14:1

   Every figure is from the kit's own contrast matrix, measured against paper
   #FFFFFF. The bar is now MORE legible than it was on violet, not less.

   THE FOCUS RING IMPROVES AND IS STILL THE THING TO WATCH. --aq-ocean-ink was
   3.03:1 on #300060 — over WCAG 1.4.11's 3:1 with almost nothing to spare. On
   white it is 5.36:1. That margin is why the same token can now also carry nav
   hover text, which needs 4.5:1 and could not have had it on the old bar.

   THE FOOTER FOLLOWED LATER THE SAME DAY. It was left on #300060 when this bar
   went white, which broke the open-and-close-on-one-colour symmetry that
   justified darkening the header at v1.7.1. It is now --aq-navy-true #022A5C —
   the badge's own silhouette navy — so the page is white at the top and the
   logo's navy at the bottom, and BOTH grounds are measured brand colours for the
   first time. See the .site-foot rule for what that move cost (the focus ring).

   SEPARATION IS A SHADOW, NOT A BORDER — 2026-08-06, by request. The 3px sky
   rule this shipped with earlier the same day is gone. The job is unchanged and
   it still has to be done: this bar is STICKY over a white page, so with no
   ground contrast and no edge it would dissolve into the content scrolling under
   it. --shadow-sm does it without drawing a line, and it is already tinted with
   --aq-ink rather than being neutral grey, so the lift reads as the brand's
   navy rather than as a generic drop shadow.
   A shadow also degrades better than the border did: the sky rule was a fixed
   3px band that sat there whether or not anything was under it, whereas this
   only reads where content passes beneath. */
.site-head {
    --aq-head: var(--aq-paper);
    background: var(--aq-head);
    box-shadow: var(--shadow-sm);
    position: sticky; top: 0; z-index: 40;
}
/* 68px -> 90px by request. The wrap measurements recorded further down were all
   taken at 68px and REMAIN VALID: they are about the bar's WIDTH — whether the
   brand lockup and the button fit on one line — and a taller bar changes neither
   term. Nothing keys off this height. */
.site-head-inner {
    display: flex; align-items: center; gap: 1rem;
    min-height: 90px; padding-block: .5rem;
    flex-wrap: wrap;
}
.site-brand {
    display: flex; align-items: center; gap: .7rem;
    text-decoration: none; color: inherit; margin-right: auto;
    min-height: var(--tap);
}
/* CHANGED 2026-08-05 — the logo is now the BADGE, not the wordmark.
   The wordmark was a 502x82 violet script quantised from a derived asset; it
   shares no colour with this brand and clashed with the badge palette once that
   shipped. The master mark is a square illustrated badge, so this reverts to the
   46px circle the rest of this lineage uses.
   CONSEQUENCE THAT MUST NOT BE MISSED: the wordmark carried the site's NAME, and
   .site-title was hidden precisely because of that. A square badge says nothing,
   so the title is now VISIBLE again — badge + name + tagline is a lockup, which
   is what a 6:1 landscape header slot actually wants. Dropping the badge in
   without un-hiding this would have left the header nameless. */
/* 46 -> 50px by request, 2026-08-06. THE WIDTH/HEIGHT ATTRIBUTES IN default.hbs
   MOVED WITH IT, BOTH OF THEM. A circular mark's size lives in three places on
   this site — this rule, the <img> in the {{#if @site.logo}} branch, and the
   <img> in the {{else}} fallback — and the attributes are what reserve the box
   before the file lands. Changing only the CSS leaves the browser reserving 46px
   for a 50px image, which is a layout shift on every page load: exactly the
   thing those attributes exist to prevent, reintroduced by a cosmetic edit.
   The FOOTER lockup (.foot-brand-logo) is deliberately left at 46px — it is a
   separate element and was not part of the request. */
.site-logo { height: 50px; width: 50px; object-fit: contain; border-radius: 50%; flex: none; }
.site-brand-text { display: flex; flex-direction: column; }
.site-title {
    /* 19px by request, 2026-08-06 — was 1.2rem. Stated in px rather than rem
       because the ask was in px; note this makes the brand name the one piece of
       type on the site that no longer scales with the reader's root font size.
       At the default 16px root it is a 0.2px change, so nothing moved visually;
       the difference only appears for a reader who has enlarged their base font,
       where the title now stays put while the rest of the page grows. */
    font-family: var(--font-head); font-size: 19px; font-weight: 700;
    /* The ACCENT, matching enlighteningquotes.com, which sets its site title in
       --eq-brown rather than its ink. Amethyst is 7.02:1 on paper — AAA — so the
       match costs nothing in contrast. */
    /* RE-INKED AGAIN for the white bar, 2026-08-06. White was correct on the
       violet ground and is 1.00:1 on this one. --aq-ink #022A5C is the badge's
       own silhouette-and-wordmark navy — 6.13% of the artwork by area, the
       largest non-white share — and 14.11:1 on paper.
       NOT --aq-title #300050, which every other heading on a light ground uses:
       that is a hand-picked violet with no counterpart in the logo, and the
       request was for the kit's colours. The two are close in tone (16.92 vs
       14.11) so this is a hue decision, not a contrast one. Flagged rather than
       quietly propagated: the body headings still carry #300050. */
    color: var(--aq-ink); line-height: 1.1;
    letter-spacing: -.01em;
}
/* --aq-ink-soft #4C6F81 — the kit's own secondary ink, 5.39:1 on paper, AA at
   this size. It is what the palette lists for "meta, bylines", which is exactly
   the role a tagline plays under the site name. The footer's #C9BAB2 was chosen
   against the violet and is 1.61:1 here. */
/* 13px by request, 2026-08-06 — was .78rem (12.48px at a 16px root), so this is
   a half-pixel larger and, like .site-title above, no longer scales with the
   reader's root font size. It stays --aq-ink-soft: at 5.39:1 that clears AA,
   and WCAG has no minimum font size, so 13px is a legibility judgement rather
   than a compliance one. */
.site-tagline { font-size: 13px; color: var(--aq-muted); line-height: 1.25; }

/* The button now holds a visible "Menu" label under the bars, so it can no
   longer be a fixed 44x44 square — a hard height would clip the text and a hard
   width would squeeze it. min-* keeps the WCAG 2.5.8 floor while letting the
   box grow to whatever the word needs; align-items centres the bars over the
   label now that the two have different natural widths (previously the bars
   were the only children and stretched edge to edge). */
.nav-toggle {
    display: inline-flex; flex-direction: column;
    justify-content: center; align-items: center; gap: 4px;
    min-width: var(--tap); min-height: var(--tap);
    /* Was rgba(255,255,255,.30) — a white wash, invisible on a white bar. Same
       shape, same alpha, the ink flipped to the brand navy. */
    background: none; border: 1px solid rgba(var(--aq-ink-rgb),.30); border-radius: 8px;
    cursor: pointer; padding: 6px 10px;
}
/* The bars lost their stretch when align-items became centre, so they now need
   an explicit width — without one an empty span with no content is 0px wide and
   the burger disappears entirely. */
.nav-toggle-bar { width: 22px; }
.nav-toggle-label {
    font-family: var(--font-head);
    font-size: .68rem; font-weight: 700; line-height: 1;
    letter-spacing: .03em;
    color: var(--aq-ink);
    margin-top: 2px;
}
/* The bars ARE the control — WCAG 1.4.11 wants 3:1 of them. On the white bar
   --aq-ink is 14.11:1, so the burger is the highest-contrast thing in the
   header. This is also the only element here that has now been re-inked three
   times (amethyst -> white -> navy); it is re-measured each time rather than
   assumed to have survived, because at 2px tall it is the first thing to
   disappear and the last thing anyone notices. */
.nav-toggle-bar { display: block; height: 2px; background: var(--aq-ink); border-radius: 2px; }

/* {{navigation}} emits its own <ul class="nav"> — style that, never wrap it
   in another <ul> or you get nested lists and stray bullet markers. */
.site-nav { flex-basis: 100%; display: none; }
.site-nav.is-open { display: block; }
/* CHILD combinator, not descendant. .site-nav now holds two lists — {{navigation}}'s
   <ul class="nav"> as a direct child, and .social-icons nested inside .site-social.
   Written as `.site-nav ul` and `.site-nav li a` these rules also captured the icon
   row: flex-direction:column stacked the three icons vertically in the open mobile
   menu, and min-height/padding/border-radius turned the 38px circles into 38x44
   pills with a hairline under each. Measured, not guessed. */
.site-nav > ul {
    list-style: none; margin: .5rem 0 0; padding: 0;
    display: flex; flex-direction: column;
}
.site-nav > ul li { list-style: none; }
.site-nav > ul li a {
    display: flex; align-items: center; min-height: var(--tap);
    padding: 0 .25rem; text-decoration: none; font-weight: 600;
    /* NAVY at rest on the white bar — 14.11:1, the mark's own ink. Was white,
       which is 1.00:1 here.
       The divider follows: rgba(255,255,255,.14) was a white hairline in the
       open mobile menu and is now invisible, so it becomes the same navy wash at
       the same weight. */
    color: var(--aq-ink); border-bottom: 1px solid rgba(var(--aq-ink-rgb),.14);
}
/* HOVER ON THE PLAIN BAR — --aq-ocean-ink #0072A1, 5.36:1 on paper, clear of
   the 4.5:1 hover TEXT needs. It is the palette's "working ocean", derived from
   the #0293CE ocean in the badge, and it is a genuine hue shift away from navy
   rather than a tonal nudge, so the hover reads on a phone where there is no
   pill behind it.
   The old #FFCB9A apricot was the right answer on a dark bar and is 1.44:1 on
   white — the single worst survivor of this inversion.
   NOTE the desktop block below OVERRIDES this colour when the sky pill appears:
   ocean-ink on --aq-sky measures 4.23:1, which fails AA. Same colour, different
   ground, different verdict — the pair has to be read together. */
.site-nav > ul li a:hover { color: var(--aq-accent); }

/* In the stacked mobile menu the icon row sits under the links, separated by the
   same hairline the links use. .social-icons is already a flex row, so it stays
   horizontal while the nav list is a column. */
.site-social { padding-top: .5rem; }

/* CENTRE THE BURGER WHEN THE BAR WRAPS — 2026-08-05, by request.

   Measured in a same-origin iframe harness (Chrome will not open a window under
   ~500px, so a screenshot cannot see this):

     412px+   brand + button share one row, button hard right, bar 68px
     390px    button WRAPS to its own row, x=16-60 — hard LEFT, bar 122px
     360px    same, bar 122px
     320px    same, bar 149px

   So on most real phones the button was sitting alone on a second line against
   the left edge, under the brand.

   justify-content, NOT a margin-inline:auto on the button. An auto margin would
   also fire on the ONE-row layout at 412-799px, where .site-brand's
   margin-right:auto currently pushes the button to the right edge — the two
   autos would share the free space and drag the button inward at widths where
   nothing was wrong. Auto margins consume free space BEFORE justify-content is
   applied, so on the single-row layout this rule is inert and the button stays
   right; on the wrapped line the button is the only item, carries no auto
   margin, and centres. One rule, correct on both sides of the wrap, with no
   breakpoint guess about where the wrap happens — which depends on the length
   of the site title and would drift if it were ever edited. */
@media (max-width: 799px) {
    /* Fallback only. The rules below now keep the button ON the brand's row at
       every width we ship, so this should never fire — it is kept because the
       wrap point depends on the length of the site title, and if that is ever
       edited to something much longer the button dropping to a CENTRED second
       row is a far better failure than it dropping to a left-aligned one. */
    .site-head-inner { justify-content: center; }

    /* KEEP THE BUTTON BESIDE THE BRAND — 2026-08-05, by request.
       It was wrapping to its own row on every phone width (320-412px), because
       the brand lockup plus a 54px button exceeds the line. The wrap is fixed
       by letting the BRAND shrink rather than by forbidding the wrap:
       flex-wrap:nowrap would also apply to .site-nav, which has flex-basis:100%
       precisely so the open menu takes its own full-width line — the menu would
       have been crushed onto the header row instead.
       min-width:0 ALONE DOES NOT WORK, and this cost a deploy to learn: a
       wrapping flex container decides where to break the line using each item's
       HYPOTHETICAL main size — for the brand, its max-content width, the full
       unwrapped title — and only then shrinks whatever ended up on the line.
       min-width:0 changes how far an item may shrink; it does not change the
       size the line-breaking step measured. The button was already on line two
       by the time shrinking was considered.
       flex-basis:0 is what actually fixes it: the brand's hypothetical size
       becomes 0, so the line-breaker sees 0 + 54px and keeps both together,
       then flex-grow:1 hands the brand every remaining pixel and the title
       wraps inside it. min-width:0 is still required alongside — without it the
       auto minimum re-imposes the content width. */
    .site-brand { flex: 1 1 0; min-width: 0; }
    .site-brand-text { min-width: 0; }
    /* Never let the button itself be the thing that shrinks. */
    .nav-toggle { flex: none; }
}

/* Below ~500px there is not enough room for the tagline AND a title AND the
   button on one line: the title would wrap to three lines to make space. The
   tagline is the descriptive half of the lockup and the site name is the
   identifying half, so the tagline is what goes. It returns at 500px, where the
   measurements show everything already fits. */
@media (max-width: 499px) {
    .site-tagline { display: none; }
}

@media (min-width: 800px) {
    .nav-toggle { display: none; }
    /* flex, NOT block: .site-nav now has two children — {{navigation}}'s <ul> and
       the icon row — and block would stack them, dropping the icons onto a second
       line under the menu. */
    /* .is-open must be repeated here. A media query adds NO specificity, so the
       base `.site-nav.is-open { display: block }` (0,2,0) outranks a bare
       `.site-nav` (0,1,0) even inside this block. With one child that was
       harmless; now .site-nav has two, and block stacks them — a reader who opens
       the menu on a phone and then rotates to landscape got a 101px header with
       the icons on their own row. Measured by forcing .is-open at every width. */
    .site-nav,
    .site-nav.is-open { display: flex; align-items: center; gap: .6rem; flex-basis: auto; }
    .site-nav > ul { flex-direction: row; gap: .35rem; margin: 0; }
    .site-nav > ul li a { border-bottom: 0; padding-inline: .85rem; border-radius: 8px; }
    /* THE HOVER PILL IS A PAIR — fill AND ink, set together, because changing
       one without the other is what this file keeps recording as the recurring
       mistake (the footer tag-pill's amber, the header's own v1.7.1 inversion).
       rgba(255,255,255,.12) on a white bar is no pill at all, so the fill becomes
       --aq-sky #C5EAFF, a measured logo colour (upper sky, 7.7% of the artwork
       across two buckets).
       And the ink goes BACK to --aq-ink for the duration of the pill: the base
       rule's --aq-ocean-ink is 5.36:1 on white but only 4.23:1 on sky, under the
       4.5 it needs. Navy on sky is 11.14:1 (kit matrix, AAA). So the link is navy
       at rest, ocean on hover with no pill, and navy again on hover with one —
       which looks inconsistent written down and is the only combination where
       every state passes on the ground it actually sits on. */
    .site-nav > ul li a:hover { background: var(--aq-tint); color: var(--aq-ink); }
    .site-social { padding-top: 0; border-left: 1px solid rgba(var(--aq-ink-rgb),.18); padding-left: .6rem; }
}

/* The icons only join the inline nav row once there is room for them.
   Measured against PRODUCTION's six-item menu — staging carries only Home+About,
   so measuring there would have passed this and shipped the regression. At 900px
   the six items plus three icons wrapped .site-nav onto a second line and the
   header went 71 -> 125px; at 1024 it fits. Below 800 they live in the collapsed
   menu, which has room, so only this middle band is excluded.
   Separately and NOT caused by this: the live header ALREADY wraps to 125px at
   820px with six items and no icons. Pre-existing, left alone here. */
@media (min-width: 800px) and (max-width: 1023px) {
    .site-nav .site-social { display: none; }
}

/* --- hero — REMOVED 2026-08-05 ------------------------------------------
   .hero, .hero-title, .hero-sub and the `.hero + .sections { margin-top: 0 }`
   adjacency rule are all gone, by request. index.hbs no longer emits the
   section, so every one of those rules was dead weight on the critical path.
   The homepage now opens on the category strip.
   The strip's own top margin is cancelled on the homepage below, where it is
   the first thing under the header — see .home-template .sections.
   ------------------------------------------------------------------------ */

/* Visually hidden, still announced. Carries the homepage <h1> that the hero
   used to hold. clip-path does the work in every current browser; the legacy
   `clip` stays for anything that predates it. white-space:nowrap stops a
   1px-wide box wrapping the title into a tall invisible column, which is the
   classic way this pattern still ends up affecting layout. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- grid of quote cards ------------------------------------------------ */
/* CARD GRID — informativequotes.com's treatment, adopted 2026-08-05.
   auto-fill/minmax replaces the old 1 / 2 / 3 breakpoint ladder. The ladder
   stepped at 560px and 960px regardless of how much room the cards actually
   had, so between breakpoints they stretched. minmax(240px, 1fr) lets the
   count follow the available width instead, which is why IQ's grid holds up
   at widths the ladder never anticipated. */
.quote-grid {
    display: grid;
    /* FOUR ACROSS ON DESKTOP, explicitly.
       auto-fill alone will not do this: it fits as many columns as the width
       allows, so the count swings with the viewport. At a 240px minimum a
       1024px laptop dropped to 3; lowering it to 220 fixed that but then let a
       FIFTH column in at 1280px. There is no single minimum that yields exactly
       four at every desktop width — the constraint is a count, so it is stated
       as a count below. auto-fill still governs the fluid range under 1000px,
       where stepping 3 -> 2 -> 1 is the right behaviour. */
    grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
    gap: 1.25rem;
    /* align-items:start REMOVED to match informativequotes.com, whose cards
       stretch so a row's bottom edges line up. With it, a two-line title made
       one card taller than its neighbours and the row's borders stopped
       aligning — the single most visible difference against IQ's grid. */
    padding-block: clamp(1.5rem, 4vw, 2.75rem);
}
/* The desktop cap. 1000px is where four 220px columns plus their gaps first
   fit (940px of track + 60px of gap), so this never squeezes them narrower
   than the fluid rule would have. */
@media (min-width: 1000px) {
    .quote-grid { grid-template-columns: repeat(4, 1fr); }
}

/* CARD — informativequotes.com is FLAT: a hairline border and no resting
   shadow. MOTION — enlighteningquotes.com's lift, kept exactly.
   The two combine well: with no shadow at rest the hover shadow has somewhere
   to travel from, so the lift reads more clearly here than it does on EQ,
   where the card already carries shadow-sm. */
.quote-card {
    background: var(--aq-white);
    border: 1px solid rgba(var(--aq-ink-rgb),.10);
    border-radius: var(--radius);
    overflow: hidden;
    display: flex; flex-direction: column;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.quote-card:hover,
.quote-card:focus-within {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: rgba(var(--aq-ink-rgb),.20);
}

.quote-card-link { text-decoration: none; color: inherit; display: block; }
/* CARD IMAGES — REBUILT 2026-08-05 after measuring the real artwork.

   This was `aspect-ratio: 1/1` with `object-fit: cover`, and it was cropping
   every card. Eight consecutive homepage images, measured at the 600w
   derivative actually served:

     600x450  1.33      600x486  1.23      600x400  1.50
     598x298  2.01      600x384  1.56      600x392  1.53
     584x438  1.33      600x389  1.54

   NOT ONE IS SQUARE. All landscape, median ~1.5. `cover` on a square box was
   therefore discarding the left and right of every single one — on the 2.01
   image, about half its width. And this site's artwork is QUOTE GRAPHICS with
   the words baked into the picture, so what `cover` threw away was the start
   and end of the sentence. That is why cards read "rn something / everyone who
   / through our".

   THE FIX IS THE BOX, NOT THE FIT MODE. aspect-ratio moved 1/1 -> 3/2, the
   median of the real library rather than a square nothing in it actually is.
   `cover` stays, so the well is always completely filled with no letterbox
   bars — but it now crops against a box the artwork nearly matches, and that
   changes the cost by an order of magnitude. Measured per sample:

     ratio    cropped at 1/1      cropped at 3/2
     1.50        33.3%               0%      exact fit
     1.53        34.6%               2.0%
     1.54        35.1%               2.6%
     1.56        35.9%               3.8%
     1.33        24.8% (sides)      11.3%   (top/bottom)
     1.23        18.7% (sides)      18.0%   (top/bottom)
     2.01        50.2%              25.4%
     ------------------------------------------------
     mean        ~33%                ~9%

   So the average card loses 9% of an edge instead of a third of its width, and
   four of the eight are within 4% of untouched. The two survivors — the 1.23
   portrait and the 2.01 panorama — are genuinely the wrong shape for any single
   grid and are the only ones that still lose a meaningful edge.

   `contain` was tried first and rejected: it truncates nothing, but it leaves
   bars on most cards, and a grid of quote graphics floating in coloured
   rectangles reads as broken rather than careful.

   object-position centre: these graphics set their type centred, so a centre
   crop takes margin off both sides rather than eating one edge of a sentence. */
/* 1/1 + cover, and it crops NOTHING on this site: all twenty feature images
   sampled measured exactly 600x600. The master's 3/2 box was inherited from a
   library that is 1.23-2.01 wide; applied here it was slicing the top and
   bottom off square artwork for no reason. */
.quote-card-media { aspect-ratio: 1 / 1; background: var(--aq-surface); }
/* the picture must fill the aspect-ratio box, or the img's height:100% has no
   definite height to resolve against and the card collapses */
.quote-card-media picture { width: 100%; height: 100%; }
.quote-card-img {
    width: 100%; height: 100%;
    object-fit: contain;
    object-position: center;
}

/* COVER + FIT — 2026-08-07.
   The well showed a band of surface colour above and below any image that is
   not the box's own ratio, and plain `object-fit: cover` is NOT the fix here:
   this artwork is quote GRAPHICS with the sentence baked into the picture, so a
   cover crop truncates the words, not just the margins. Measured on
   mesmerizingquotes.com's homepage — 14 of its 16 cards are landscape in a 1/1
   box — a cover crop took 10–18% off EACH side and rendered "Never waste your"
   as "ver waste your" and "Don't ever use someone's past" as "on't ever use
   someone's pa". Rendered side by side before choosing; see the harness shot.

   So the well is filled by a blurred, scaled copy of the SAME image, and the
   real picture sits `contain`ed and whole on top. Nothing is cropped and no
   flat band is ever visible.

   IT COSTS NO EXTRA REQUEST. The backdrop carries the foreground's exact
   <source>/srcset/sizes, so responsive selection lands on the identical
   candidate URL and the browser serves both layers from one cached response.
   That is also why the backdrop must stay a full <picture> clone: a bare <img>
   would miss the AVIF <source> and pull a second, JPEG copy.

   Where the artwork already matches the box — the square back catalogue, which
   is 100% of the sampled library on nine of the twelve sites — the foreground
   covers the backdrop completely and it is never seen. This is a no-op there. */
.quote-card-media { position: relative; overflow: hidden; }
.quote-card-media > picture { position: relative; z-index: 1; }
.quote-card-fill {
    position: absolute; inset: 0; z-index: 0;
    /* Scale BEFORE blurring. A blur samples beyond the element's own edge, so an
       unscaled layer pulls transparency in around the rim and the surface colour
       reappears as a soft halo — the exact band this is meant to remove. */
    transform: scale(1.18);
    filter: blur(16px) saturate(1.3);
}
.quote-card-fill picture { display: block; width: 100%; height: 100%; }
.quote-card-fill-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* For readers who ask for reduced transparency, push the blur further so the
   backdrop reads as a flat colour wash rather than a discernible second copy of
   the image sitting behind the first. Stronger blur, not weaker — the goal is
   to remove the impression of a layered image, not to sharpen it. */
@media (prefers-reduced-transparency: reduce) {
    .quote-card-fill { filter: blur(32px) saturate(1.1); }
}


/* CARD BODY — informativequotes.com's .card-body: the padding lives here now,
   not on the title, because the body holds three stacked things (pill, title,
   date) rather than a title alone. */
.quote-card-body { padding: .85rem .9rem 1rem; }

/* TOPIC PILL — informativequotes.com's .topic-badge, sitting ABOVE the title.
   Amethyst on the sky surface measures 6.61:1 — AA. The old treatment was a
   bare uppercase link UNDER the title in the soft ink. */
.quote-card-badge {
    display: inline-block;
    font-size: .72rem; font-weight: 700; letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--aq-accent);
    background: var(--aq-surface);
    padding: .2rem .5rem;
    border-radius: 4px;
}

/* Title to informativequotes.com's .card-title: 1rem, tight margins, set in the
   heading face. Poppins at 1rem reads larger than the old Lora 1.02rem, so this
   is not a reduction in practice. */
.quote-card-title {
    font-size: 1rem; line-height: 1.4;
    margin: .35rem 0 .4rem;
    color: var(--aq-title); font-family: var(--font-head); font-weight: 700;
    transition: color .18s ease;
}
.quote-card-link:hover .quote-card-title,
.quote-card-link:focus-visible .quote-card-title { color: var(--aq-accent); }

/* Date line — informativequotes.com's .card-meta. This site's cards carried no
   date at all before. */
.quote-card-meta { color: var(--aq-muted); font-size: .8rem; }

/* --- archive heads ------------------------------------------------------ */
.archive-head {
    background: var(--aq-surface);
    padding-block: clamp(1.75rem, 5vw, 2.75rem);
    border-bottom: 1px solid rgba(var(--aq-ink-rgb),.12);
    text-align: center;
}
.archive-kicker,
.post-kicker {
    display: inline-block;
    font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
    font-weight: 700; color: var(--aq-muted); text-decoration: none;
    margin-bottom: .4rem;
}
.post-kicker { min-height: 28px; }
.archive-title { font-size: clamp(1.7rem, 4.5vw, 2.5rem); color: var(--aq-title); }
.archive-desc { max-width: 55ch; margin-inline: auto; color: var(--aq-muted); }
.archive-count { font-size: .9rem; color: var(--aq-muted); margin: .25rem 0 0; }

/* --- single post -------------------------------------------------------- */
/* NB: must NOT be `.post` — Ghost's {{post_class}} stamps `post` onto every
   card in the grid, so a `.post` rule leaks padding into every card. */
.single { padding-block: clamp(1.75rem, 5vw, 3rem); }
.post-head { text-align: center; margin-bottom: 1.75rem; }
.post-title { font-size: clamp(1.6rem, 4.5vw, 2.4rem); color: var(--aq-title); }
.post-meta { color: var(--aq-muted); font-size: .9rem; margin: 0; }

.post-media { margin: 0 0 1.75rem; }
.post-media img {
    margin-inline: auto; border-radius: var(--radius);
    box-shadow: var(--shadow-md); background: var(--aq-surface);
}
.post-media figcaption {
    text-align: center; font-size: .85rem; color: var(--aq-muted); margin-top: .6rem;
}

.post-content { font-size: 1.09rem; }
/* Reset via the child combinator only. A plain `.post-content p { margin: 0 }`
   out-specifies `> * + *` and silently removes every paragraph gap. */
.post-content > * { margin: 0; }
.post-content > * + * { margin-top: 1.15em; }
/* The imported WordPress content wraps whole paragraphs in <strong>, so this
   must NOT recolour — tinting it turned every post body into bold brown. */
.post-content strong { color: inherit; }
.post-content h2, .post-content h3 { margin-top: 1.8em; color: var(--aq-accent); }
.post-content img { border-radius: var(--radius); margin-inline: auto; }
.post-content blockquote {
    margin: 1.6em 0; padding: .6em 0 .6em 1.25em;
    border-left: 4px solid var(--aq-tint);   /* decorative use of gold — not text */
    color: var(--aq-ink); font-style: italic;
}
.post-content a { color: var(--aq-accent); }
.post-content ul, .post-content ol { padding-left: 1.4em; }
.post-content hr { border: 0; border-top: 1px solid var(--aq-surface); margin: 2em 0; }

/* --- Koenig editor cards ------------------------------------------------ */
/* Ghost's editor emits these widths; they must be styled or content breaks
   out of, or is trapped inside, the narrow column. */
.post-content .kg-card { margin-block: 1.6em; }

.post-content .kg-width-wide {
    width: min(100vw - 2rem, 1000px);
    max-width: none;
    margin-inline: calc(50% - min(50vw - 1rem, 500px));
}
.post-content .kg-width-full {
    width: 100vw;
    max-width: none;
    margin-inline: calc(50% - 50vw);
}
.post-content .kg-width-full img,
.post-content .kg-width-wide img { width: 100%; border-radius: 0; }
.post-content .kg-width-wide img { border-radius: var(--radius); }

.post-content .kg-image-card figcaption,
.post-content .kg-embed-card figcaption {
    text-align: center; font-size: .85rem; color: var(--aq-muted); margin-top: .6rem;
}
.post-content .kg-embed-card { display: flex; flex-direction: column; align-items: center; }
.post-content .kg-gallery-row { display: flex; gap: .6rem; }
.post-content .kg-gallery-image img { width: 100%; }
.post-content .kg-bookmark-card a {
    display: flex; flex-direction: column; border: 1px solid var(--aq-surface);
    border-radius: var(--radius); overflow: hidden; text-decoration: none; color: inherit;
}
.post-content .kg-bookmark-content { padding: 1rem; }
.post-content .kg-bookmark-title { font-weight: 700; color: var(--aq-accent); }
.post-content .kg-bookmark-description { color: var(--aq-muted); font-size: .92rem; }

/* The seven classes below are what gscan reported as ERRORS on wisdom-quotes-4u
   from v1.4.1 onward, and that theme still ships with them. They are a consequence
   of card_assets:false: with Ghost's own cards.min.css suppressed, the theme owes
   a style for every Koenig class, including cards this site will never use.
   wq4u's position was that Ghost activates the theme anyway because a gscan error
   is not fatal. That is true and it is still the wrong trade — a theme carrying
   seven permanent "known-ignorable" errors teaches you to skim the next scan, and
   the next scan is where a real regression shows up.
   Styled properly rather than stubbed: this site has 0 gallery cards and 0 bookmark
   cards today, but if one is ever added it should look deliberate instead of
   unstyled. Costs ~20 lines and makes the scan mean something. */
.post-content .kg-gallery-container { display: flex; flex-direction: column; gap: .6rem; }
.post-content .kg-bookmark-container { display: flex; flex-direction: column; }
.post-content .kg-bookmark-metadata {
    display: flex; align-items: center; flex-wrap: wrap; gap: .4rem;
    margin-top: .6rem; font-size: .85rem; color: var(--aq-muted);
}
.post-content .kg-bookmark-icon { width: 20px; height: 20px; margin-right: .25rem; }
.post-content .kg-bookmark-author { font-weight: 600; color: var(--aq-ink); }
.post-content .kg-bookmark-publisher { color: var(--aq-muted); }
.post-content .kg-bookmark-publisher::before { content: "•"; margin-right: .4rem; }
.post-content .kg-bookmark-thumbnail { flex-shrink: 0; }
.post-content .kg-bookmark-thumbnail img {
    width: 100%; height: 100%; object-fit: cover; border-radius: 0;
}
.post-content .kg-button-card { display: flex; justify-content: center; }
.post-content .kg-btn {
    display: inline-flex; align-items: center; min-height: var(--tap);
    padding: 0 1.5rem; background: var(--aq-accent); color: var(--aq-white);
    border-radius: 999px; text-decoration: none; font-weight: 600;
}

.post-tags { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: .5rem; }

.tag-pill {
    display: inline-flex; align-items: center;
    /* 30px, down from 36, by request. Used by the footer category cloud and by
       .post-tags under a post. Still clears WCAG 2.5.8 AA, which asks 24x24 —
       checked, because this is a tap target and shrinking one is the direction
       that breaks it. It is below the 44px this theme uses elsewhere, so it is
       now the smallest target on the site. */
    min-height: 30px; padding: 0 .85rem;
    background: var(--aq-surface); color: var(--aq-accent);
    border-radius: 999px; text-decoration: none;
    font-size: .85rem; font-weight: 600;
}
.tag-pill:hover { background: var(--aq-accent); color: var(--aq-white); }

/* --- share -------------------------------------------------------------- */
/* Plain links to each network's share endpoint — no vendor JavaScript. A share
   widget would add third-party script to a page that already carries AdSense,
   and INP is the metric ad scripts damage most.
   Buttons are 44px, well clear of the WCAG 2.5.8 AA floor of 24x24. */
.share {
    margin-top: 2.25rem; padding-top: 1.5rem;
    border-top: 1px solid var(--aq-surface);
    display: flex; align-items: center; flex-wrap: wrap; gap: .75rem 1rem;
}
.share-label {
    font-weight: 700; font-size: .9rem; color: var(--aq-muted);
    text-transform: uppercase; letter-spacing: .04em;
}
.share-list { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; }
.share-list li { list-style: none; }
.share-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    width: var(--tap); height: var(--tap); padding: 0;
    background: var(--aq-surface); color: var(--aq-accent);
    border: 0; border-radius: 999px; cursor: pointer;
    text-decoration: none; font: inherit;
}
.share-btn svg { width: 20px; height: 20px; display: block; }
/* Brand colours on hover only. Each is at least 3:1 against white, which is the
   non-text contrast requirement for an icon. */
.share-whatsapp:hover  { background: #128C7E; color: var(--aq-white); }
.share-facebook:hover  { background: #1877F2; color: var(--aq-white); }
.share-x:hover         { background: #000000; color: var(--aq-white); }
.share-pinterest:hover { background: #BD081C; color: var(--aq-white); }
/* Added 2026-08-05. White glyph on each brand fill measures 5.69:1 (LinkedIn)
   and 5.11:1 (Instagram) — both well past the 3:1 WCAG 1.4.11 asks of a
   non-text indicator. Instagram's real mark is a gradient; a flat #C13584 is
   used here for the same reason the footer does, so the hover states stay one
   consistent shape rather than one of them carrying a gradient. */
.share-linkedin:hover  { background: #0A66C2; color: var(--aq-white); }
.share-instagram:hover { background: #C13584; color: var(--aq-white); }
/* .share-copy, .share-copy.is-copied, .share-copied and
   .share-copy .share-copied:empty removed 2026-08-06 with the button itself.
   Four dead rules left behind is how a stylesheet ends up with selectors nobody
   can find the markup for; they go out with the element in the same change.
   .share-btn keeps `border: 0`, `cursor: pointer` and `font: inherit` even
   though every remaining item is an <a>. Those three exist to normalise a
   <button> and are now inert — left in place because this partial is the fleet
   template and the other eleven themes still carry the button. */

/* --- comments ----------------------------------------------------------- */
/* Ghost's native comments, added 2026-08-06. The UI itself is a web component
   Ghost injects and mounts here; almost none of its internals are stylable from
   this file, so what follows styles the CONTAINER and the surrounding copy only.
   Do not add rules targeting the component's internal classes — they are
   generated by a bundled build and rename between Ghost releases, so such rules
   look fine for a while and then silently stop applying.

   The one hook Ghost does honour is the site's accent colour, which the comments
   UI reads for its buttons and links. That comes from the accent_color setting,
   not from this stylesheet.

   Width matches the post body: this sits inside .wrap-narrow, so it inherits the
   720px measure and lines up with the paragraphs above rather than running the
   full page width like the related-posts grid below it. */
.post-comments {
    /* 2.5rem -> 1.75rem, 2026-08-06 by request: the gap above Comments and
       above More like this was wider than the space between paragraphs inside
       them, which made each section look detached from the post it belongs to.
       Trimmed on both so the two keep matching. */
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--aq-surface);
}
/* The section heading reuses .section-title so it matches "More like this"
   directly beneath it — two headings of the same rank should not be two
   different sizes. Margin is tightened because the note sits under it. */
.post-comments .section-title { margin-bottom: .35rem; }
/* Explains the sign-in step BEFORE the reader hits it. Ghost's own empty state
   just shows a "Sign in" button with no indication that it is passwordless, and
   on a site with no membership offering that button reads like a paywall. --aq-muted
   is 5.39:1 on the page, AA at this size. */
.post-comments-note {
    margin: 0 0 1.25rem;
    color: var(--aq-muted);
    font-size: .92rem;
    line-height: 1.55;
}

/* FACEBOOK COMMENTS WILL NOT BE FULL WIDTH WITHOUT THIS, AND data-width="100%"
   IS NOT ENOUGH ON ITS OWN. The SDK renders into an <iframe> and writes an
   INLINE width in px onto both the iframe and its wrapping <span>, computed once
   from the container at first paint. Inline styles beat every class rule, so the
   override has to carry !important, and it has to name the span as well as the
   iframe or the iframe is 100% of a span that is still 550px.
   The consequence of leaving it: the thread renders at a fixed width and never
   reflows, so it is correct at exactly one viewport and wrong at every other —
   including after a phone rotates. */
/* The Facebook width-override rules that used to sit here are GONE with the
   plugin — they existed only to fight the inline px width Meta's SDK writes onto
   its own iframe, and Comentario renders in the light DOM at natural width. */

/* The SDK injects nothing until it loads, so the section would otherwise jump
   from zero height to the full thread — layout shift on every post page, on the
   metric ad and social embeds damage most. A min-height reserves roughly the
   height of the login prompt / empty composer, which is what most readers see.

   THE BORDER IS OURS, NOT FACEBOOK'S — 2026-08-06, by request. The plugin runs
   inside a cross-origin iframe, so nothing inside it can be styled from here;
   the frame is what gets the box. Same hairline and radius as .quote-card so the
   comment area reads as part of this theme rather than a pasted-in widget.
   Background is --aq-surface, not white: Facebook renders its own thread on
   white, so a tinted well keeps the two visually separate once content loads. */
/* HIDE THE SIGN-IN BAR — it is a dead control on this domain.
   The domain runs auth_anonymous=1 with auth_local, auth_sso and every federated
   provider OFF, so the button opens a dialogue offering nothing. A control that
   leads nowhere is worse than no control, and "no sign-in" was the requirement.

   TARGETING `.comentario-profile-bar`, NOT `.comentario-btn-primary` — the
   submit button carries that same class, so hiding by button style would have
   removed the ONE control that posts a comment. Checked the parent chain in the
   live DOM before writing this rather than guessing from the class name.

   Comentario renders in the LIGHT DOM (verified: no shadowRoot), which is the
   only reason this rule can reach inside the widget at all. If a future version
   moves to shadow DOM this stops applying — and the sign-in button reappearing
   is the symptom to watch for.

   A MALFORMED COMMENT SILENTLY ATE THIS RULE FOR THREE DEPLOYS, and the second
   cause was writing about the first. CSS COMMENTS HAVE NO ESCAPE SEQUENCE: the
   two characters star-slash end a comment wherever they appear, including inside
   backticks. My explanation of the bug literally contained them, so the comment
   closed on the line describing the problem and the prose after it became
   invalid CSS — and the parser discards the next rule along with it. The
   symptom was maddening — the rule was in the served file, the selector matched
   the element in the live DOM, sibling rules from the SAME file applied, and
   computed display stayed `flex`. I misread that as Comentario's runtime
   stylesheet winning on source order. It was not: its rule is
   `.comentario-toolbar{display:flex}`, (0,1,0) and no !important, so this
   (0,2,0) selector outranks it with or without one.
   **When a rule does not apply but its neighbours do, suspect the comment above
   it before you suspect the cascade.** !important is kept only as cheap
   insurance against a future runtime sheet, not because it is needed today. */
.post-comments .comentario-profile-bar { display: none !important; }

/* NO OUTER WELL — 2026-08-06, by request. The widget host is a plain block; the
   only bordered thing is the comment box itself, styled below. min-height stays
   because the widget is client-rendered and the section would otherwise jump
   from 0 to full height on every post page. */
.post-comments comentario-comments {
    display: block;
    min-height: 140px;
    border: 0;
    background: none;
    padding: 0;
}

/* THE COMMENT BOX — this is the one element that carries a border now. Same
   hairline, radius and surface tint as .quote-card so it reads as part of the
   theme rather than a pasted-in widget. */
/* THE HOST IS THE "OUTER BOX" THE EYE SEES, not the widget root. Comentario puts
   a 1px border and a white fill on .comentario-add-comment-host and nests the
   real placeholder inside it, so stripping the widget root alone still left a
   visible frame. Measured in the live DOM, not guessed. */
.post-comments .comentario-add-comment-host {
    border: 0 !important;
    background: none !important;
    padding: 0 !important;
}
.post-comments .comentario-add-comment-placeholder {
    /* The host is display:flex, so the placeholder shrink-wrapped its own text
       and came out 198px wide inside a 720px column. flex-basis is what fixes
       that — width:100% alone loses to flex sizing. */
    flex: 1 1 100%;
    width: 100%;
    box-sizing: border-box;
    border: 1px solid rgba(var(--aq-ink-rgb),.18) !important;
    border-radius: var(--radius);
    background: var(--aq-surface);
    padding: .9rem 1rem;
    min-height: 84px;
    cursor: text;
}
.post-comments .comentario-add-comment-placeholder:hover {
    border-color: var(--aq-accent) !important;
}

/* PLACEHOLDER TEXT REPLACED WITHOUT JAVASCRIPT. The element is a <div> whose
   text node reads "Add a comment", so there is no `placeholder` attribute to
   set and no way to edit the string from CSS directly. Collapsing the div's own
   font to 0 hides the original text, and ::before supplies ours at normal size.
   The alternative was a MutationObserver re-writing the node after every render
   — more code, and it would flash the old wording first.
   IF THE WIDGET EVER RENDERS AN EMPTY BOX, this is the rule to suspect: a future
   Comentario version that nests the text in a child element would have that
   child inherit font-size:0. */
.post-comments .comentario-add-comment-placeholder { font-size: 0 !important; }
.post-comments .comentario-add-comment-placeholder::before {
    content: "Share your thoughts...";
    font-size: 1rem;
    font-family: var(--font-body);
    color: var(--aq-muted);
}

/* "POWERED BY COMENTARIO" REMOVED — asked for, and checked against the licence
   first rather than just hidden. Comentario is MIT: the licence obliges us to
   keep the copyright notice in copies of the SOURCE, which we do — the container
   runs the unmodified official image and its LICENSE file is untouched. MIT does
   not require a visible badge in a deployed UI, so hiding it is permitted.
   No supported config toggle exists (checked every key in /api/config for
   powered / branding / footer / logo — none), so CSS is the only route. */
.post-comments .comentario-footer { display: none !important; }

/* SUBMIT BUTTON RELABELLED "Add Comment" to "Post Comment" — asked for.
   Same font-size-zero plus pseudo-element technique as the placeholder above,
   because the label is a text node with no attribute to rewrite.
   SCOPED TO THE EDITOR FOOTER, not to .comentario-btn-primary on its own: that
   class is also worn by the Sign in button, so an unscoped rule would relabel a
   second control. ::after rather than ::before so the text lands after the
   button's submit icon rather than in front of it. The icon is an SVG child and
   is unaffected by font-size zero. */
.post-comments .comentario-comment-editor-footer .comentario-btn-primary {
    font-size: 0 !important;
}
.post-comments .comentario-comment-editor-footer .comentario-btn-primary::after {
    content: "Post Comment";
    font-size: .9rem;
    font-family: var(--font-head);
    font-weight: 700;
}

/* RSS BUTTON REMOVED — asked for. Targeting the WRAPPER, not the button:
   `.comentario-thread-buttons` was measured in the live DOM and contains exactly
   one child, the RSS button. The sibling `.comentario-sort-buttons` holds
   Votes/Oldest/Newest and is untouched, so sorting still works if it is ever
   un-hidden. Hiding by `.comentario-btn-link` would have taken those too. */
.post-comments .comentario-thread-buttons { display: none !important; }

/* --- ads ---------------------------------------------------------------- */

/* --- related / sections ------------------------------------------------- */
.related { background: var(--aq-surface); border-top: 1px solid rgba(var(--aq-ink-rgb),.10); }
/* --aq-ink, NOT --aq-brown. This heading sits on the .sections band
   (--aq-cream #E3E8E4), where the page accent --aq-brown (--heart-ink) is
   only ~3.80:1 and fails AA — while being a correct ~4.8:1 twenty pixels above
   it on the white page. Fourth fleet site to hit this, with different colours
   every time, which is why the constraint is written on the token. */
/* .feed-title shares this exactly — the homepage's "Latest Posts" and "Top
   Stories" headings are the same rank and the same treatment as the category
   strip's title, and giving them their own near-identical rule is how two
   headings that should match drift apart six months later. */
/* These two SHED the heading face, 2026-08-05 by request: "font family like menu
   font". The menu sets no font-family at all — .site-nav > ul li a only sets
   weight — so it inherits --font-body, i.e. Lora, the serif. Checked rather than
   assumed, because the obvious guess is that a nav uses the heading face.
   So these headings now run in the BODY face while every other h1-h4 on the site
   stays Poppins. That is the intent, not an oversight.
   Weight 700 as asked, up from 500 (unitless — CSS font-weight takes no px).
   Lora ships here as the VARIABLE release covering 400..700, so 700 is the top
   of its real range: a genuine bold instance, not a browser-synthesised fake,
   and not clamped. Anything above 700 WOULD be synthesised on this face. */
.section-title,
.feed-title {
    font-size: clamp(1.3rem, 3vw, 1.7rem); color: var(--aq-title);
    font-family: var(--font-body); font-weight: 700;
    text-align: center; padding-top: clamp(1.5rem, 4vw, 2.25rem); margin-bottom: 0;
}

/* The second homepage grid. A hairline separates it from the pagination that
   ends the Latest Posts collection above — without it the two grids read as one
   long feed interrupted by a stray pair of buttons. */
.feed-section { border-top: 1px solid rgba(var(--aq-ink-rgb),.10); }
/* .feed-more is GONE, not left behind: the "See all stories" text link it styled
   was replaced by a .pagination button, which carries its own spacing. A rule
   for markup that no longer exists is the kind of thing that survives three more
   redesigns and then confuses someone. */

/* Section navigation. Ghost tags are flat, so a "section" is just a tag worth
   promoting. Counts are shown because they are the honest signal of where the
   archive actually is — and because they make the strip useful rather than
   decorative. Chips are 44px tall for the same tap-target reason as .share-btn. */
/* The one Morning Mist surface. It was --aq-surface, the same tone as .related,
   .archive-head, the card media wells and the tag pills — so the strip had no
   identity of its own. Mist separates it from all of those, and it is the only
   place in the theme that carries the cool half of the badge.
   Renders on index.hbs and tag.hbs only, so a post page still has exactly one
   band (.related, cream) and the home and tag pages have exactly one each. */
/* REPAINTED 2026-08-05: the band was --aq-apricot #FFCD9C and is now WHITE, by
   request. Consequences worth stating rather than discovering:

   * THE BAND TRAP NO LONGER APPLIES HERE. Every warning in the palette block
     above about --aq-ink-soft / --aq-rose / --aq-ocean-ink failing AA on the
     apricot was about THIS element — it was the only apricot surface in the
     theme. On white they measure 5.39, 5.68 and 5.36 and all pass. The token
     stays declared: it is still the documented brand fill, the deploy script
     asserts it, and the note above is the record of why it is not used here.
   * The strip is now the same colour as the page, so the two hairlines below
     are the ONLY thing separating it from the grid. They are load-bearing now,
     not decoration — do not remove them along with the background.
   * .section-chip is white on white as a result, and reads purely by its own
     hairline border, exactly like a .quote-card does on the same ground. */
.sections {
    margin-top: 3rem;
    background: var(--aq-paper);
    border-block: 1px solid rgba(var(--aq-ink-rgb),.10);
    padding-bottom: clamp(1.5rem, 4vw, 2.25rem);
}
/* Replaces `.hero + .sections`. With the hero gone there is no adjacent sibling
   to key on, and the strip is the first thing in <main> on the homepage — 3rem
   of blank white under the header before the first heading. Keyed on Ghost's
   own body class rather than :first-child so that the invisible <h1> sitting
   above it in the markup cannot break the match. */
.home-template .sections { margin-top: 0; }
.section-list {
    list-style: none; margin: 1.25rem 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center;
}
.section-list li { list-style: none; }
.section-chip {
    display: inline-flex; align-items: center; gap: .5rem;
    min-height: var(--tap); padding: 0 .5rem 0 1rem;
    background: var(--aq-white); color: var(--aq-accent);
    border: 1px solid rgba(var(--aq-ink-rgb),.12); border-radius: 999px;
    text-decoration: none; font-weight: 600; font-size: .92rem;
}
.section-chip:hover { background: var(--aq-accent); color: var(--aq-white); border-color: var(--aq-accent); }
.section-chip-count {
    font-size: .75rem; font-weight: 700;
    background: var(--aq-surface); color: var(--aq-muted);
    border-radius: 999px; padding: .15rem .55rem;
}
.section-chip:hover .section-chip-count { background: rgba(255,255,255,.18); color: var(--aq-white); }

/* --- mobile sizing for the topic strip (2026-08-05, by request) -----------
   799px is this theme's existing mobile boundary — the width at which the nav
   collapses — so the strip changes shape at the same point everything else
   does rather than at a second, invented breakpoint.

   min-height:20px reads like a WCAG 2.5.8 failure — the AA target floor is
   24x24 — and it is NOT one. Measured on the live page at 320/360/390/412:
   the chips render 91x28. min-height is a FLOOR, not a height, and the count
   badge nested inside carries .15rem of its own vertical padding, so the box
   settles at 28px on its own. 4px of headroom, not a 4px shortfall.
   Recorded because the declaration looks alarming out of context and the next
   person to read it will otherwise "fix" a rule that is already compliant. */
@media (max-width: 799px) {
    .section-chip {
        padding: 0 .5rem 0 .5rem;
        min-height: 20px;
        font-size: 14px;
    }
    .section-chip-count { font-size: 13px; }
}

/* --- pagination --------------------------------------------------------- */
.pagination {
    display: flex; align-items: center; justify-content: center; gap: 1rem;
    padding-block: 2rem 3rem; font-size: .95rem;
}
.pagination a {
    display: inline-flex; align-items: center; min-height: var(--tap);
    /* The arrow is its own <span> and this is a FLEX container, so the plain
       space between it and the label in the markup is DISCARDED — flex turns
       each text run into an anonymous item and drops the whitespace between
       them. The buttons rendered "<-Previous Page" jammed together. A gap, not
       an &nbsp;, because the arrow span is aria-hidden and a hard space living
       inside hidden content is not one the visible label can depend on. */
    gap: .4rem;
    padding: 0 1.1rem; background: var(--aq-white);
    border: 1px solid var(--aq-accent); border-radius: 999px;
    color: var(--aq-accent); text-decoration: none; font-weight: 600;
}
.pagination a:hover { background: var(--aq-accent); color: var(--aq-white); }
.page-number { color: var(--aq-muted); }

.btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: var(--tap); padding: 0 1.5rem;
    background: var(--aq-accent); color: var(--aq-white);
    border-radius: 999px; text-decoration: none; font-weight: 600;
}
.btn:hover { background: var(--aq-ink); color: var(--aq-white); }

/* --- error -------------------------------------------------------------- */
.error-page { text-align: center; padding-block: clamp(2.5rem, 8vw, 5rem); }
.error-code { font-family: var(--font-head); font-size: 4rem; color: var(--aq-accent); margin: 0; }
.error-title { font-size: clamp(1.4rem, 4vw, 2rem); color: var(--aq-title); }
.error-help { color: var(--aq-muted); }

/* --- footer ------------------------------------------------------------- */
/* FOOTER GROUND CHANGED 2026-08-05: was var(--aq-ink) #022A5C, the silhouette
   navy, now #300050 by request — a deep violet.

   Set as its OWN token on .site-foot rather than by repointing --aq-ink, which
   would have been the quick way to do it and would have repainted the body text,
   every heading, the skip link and the .btn hover state along with it. The
   footer is the only surface that moves.

   NOT a measured brand colour — every other value in this file came out of the
   master badge, this one was specified directly. Its nearest relative in the
   kit is --aq-plum #4C1656; it is darker than that and darker than the navy it
   replaces (relative luminance 0.0121 vs 0.0244), which is why every ratio
   below IMPROVED rather than needing a rework:

     #E8DED8  body copy   10.67 -> 12.78:1
     #F0E4D2  links       11.24 -> 13.48:1
     #C9BAB2  copyright    7.49 ->  8.98:1
     #FFFFFF  headings    14.11 -> 16.92:1
     #F3E9DD  on the .10 white wash used by the pills and icon discs, 11.16:1

   Re-measured, not assumed — a darker ground is only safe for TEXT, and this
   file has been wrong about inherited contrast numbers twice before. */
/* FOOTER GROUND 2026-08-06, by request: #300060 -> --aq-navy-true #022A5C.
   Same reasoning as the header the same day. #300060 was specified by hand and
   appears nowhere in the artwork; #022A5C IS the artwork — it is the tree-and-
   figure silhouette and the arced wordmark, 6.13% of the mark by area and the
   largest non-white share in it. The palette doc names it as one of the two
   canonical dark GROUNDS and says outright that "dark mode is the badge,
   enlarged": every light colour in the logo already sits on this navy inside the
   logo, and each clears AAA against it (8.23-11.65).

   THE TEXT ALL SURVIVES, CHECKED RATHER THAN ASSUMED. Everything in this footer
   is --aq-white, which was 16.22:1 on the violet and is 14.11:1 here. Lower, and
   still AAA at every size in this region, so not one ink needed moving.

   ONE THING DID NOT SURVIVE, AND IT IS NOT TEXT. The global focus ring is
   --aq-ocean-ink, which measures 5.36:1 on the white page and 3.03:1 on the old
   violet — and only 2.64:1 on this navy, under the 3:1 WCAG 1.4.11 requires of a
   non-text indicator. So a keyboard user tabbing into the footer would have lost
   the ring at the exact moment they needed it. The kit predicts this precisely:
   the ocean is the single colour in the palette that fails against the navy, and
   it ships a lifted variant for it. Overridden below, scoped to this region only.

   That is the third time on this site a ground change has turned out to be a
   PAIR. Header v1.7.1 (light inks -> dark bar), header v2.5.0 (dark inks -> white
   bar), and now the footer, where the casualty was the one element nobody looks
   at until they are navigating by keyboard. */
.site-foot {
    --aq-foot: var(--aq-ink-strong);
    background: var(--aq-foot); color: var(--aq-white);
    margin-top: 3rem; padding-block: clamp(2rem, 5vw, 3rem);
}
/* See above. Scoped to the footer: on the white page and the white header
   --aq-ocean-ink is 5.36:1 and is the better ring, so this must not be global.
   outline-color alone, so the 3px width and 2px offset stay in one place. */
.site-foot :focus-visible { outline-color: var(--aq-foot-focus); }
.site-foot a { color: var(--aq-white); }
.foot-heading { color: var(--aq-white); font-size: 1.05rem; margin-bottom: .9rem; }

/* --- footer widgets (added 2026-08-05) ---------------------------------- */
/* Three widgets: about + social, recent posts, category list.
   One column on a phone, two in the middle band, three on desktop. The about
   column is given slightly more track because it holds a paragraph while the
   other two hold lists — at an even 1fr the prose column set to ~28 characters
   and read as a ragged strip. */
.foot-widgets {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    padding-bottom: 2rem;
}
@media (min-width: 640px) {
    .foot-widgets { grid-template-columns: repeat(2, 1fr); gap: 2rem 2.5rem; }
    /* The category cloud is the widest of the three and the only one that wraps
       freely, so at two columns it takes the full second row rather than being
       squeezed into a half-width well beside nothing. */
    .foot-widget-tags { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
    .foot-widgets { grid-template-columns: 1.15fr 1fr 1.1fr; gap: 2.5rem; }
    .foot-widget-tags { grid-column: auto; }
}

/* Brand lockup at the top of widget 1 — badge + site name, mirroring the header
   so the footer closes with the same mark the page opened on. */
.foot-brand {
    display: inline-flex; align-items: center; gap: .7rem;
    text-decoration: none;
    margin-bottom: .9rem;
    min-height: var(--tap);
}
.foot-brand-logo {
    width: 46px; height: 46px;
    border-radius: 50%; object-fit: contain; flex: none;
    /* The badge is a full-bleed illustration with its own ground, so this well
       never shows through it — it is here for the {{else}} branch's bundled
       logo.png, which is transparent and would otherwise dissolve into the navy
       footer. Same reason .foot-post-media carries one. */
    background: rgba(255,255,255,.10);
}
/* Stacks the name over the tagline, mirroring .site-brand-text in the header. */
.foot-brand-text { display: flex; flex-direction: column; }
.foot-brand-name {
    /* An explicit colour on the span, not on the anchor: `.site-foot a` is
       (0,1,1) and out-specifies a bare `.foot-brand`, so setting it there would
       silently lose. A declaration on the child beats an inherited value
       whatever the specificity. */
    font-family: var(--font-head); font-weight: 700;
    font-size: 1.05rem; line-height: 1.2;
    color: var(--aq-white);
}
/* Same size and role as .site-tagline in the header, in the footer's muted tone
   — #C9BAB2 measures 7.49:1 on the navy, so it stays AAA even at .78rem. No
   font-family: it inherits the body face, exactly as the header tagline does. */
.foot-brand-tagline {
    font-size: .78rem; line-height: 1.25;
    color: var(--aq-white);
}
/* Underline the NAME only. The tagline is a descriptor, not the link's subject,
   and underlining both makes the lockup read as one long link on hover. */
.foot-brand:hover .foot-brand-name { text-decoration: underline; }

/* Sub-heading inside a widget — smaller than .foot-heading so the widget keeps
   one dominant title ("About Us") and this reads as a level below it, which is
   also what the h2/h3 nesting says. */
.foot-subheading {
    font-family: var(--font-head);
    color: var(--aq-white);
    font-size: .92rem; font-weight: 600;
    margin: 1.25rem 0 .6rem;
}

.foot-about-text {
    margin: 0;
    color: var(--aq-white);   /* 16.22:1 on the #300060 footer */
    font-size: .95rem;
    line-height: 1.7;
    max-width: 42ch;
}

/* RECENT POSTS. Two class selectors on the link colour deliberately: the
   `.site-foot a` rule above is (0,1,1) and would otherwise out-specify a bare
   `.foot-post-link`. Same trap the .foot-social comment records. */
.foot-posts {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: .85rem;
}
.foot-posts li { list-style: none; }
.site-foot .foot-post-link {
    display: flex; align-items: center; gap: .75rem;
    text-decoration: none; color: var(--aq-white);
    /* the 50px circle still clears WCAG 2.5.8's 24x24; this holds the row height
       for a post whose title is a single short line */
    min-height: 50px;
}
/* 50px, down from 56, by request. THREE places carry this number and all three
   must move together: this box, the <img> inside it, and the width/height
   ATTRIBUTES in default.hbs. Changing the width alone turns the circle into an
   oval, because height is a separate declaration and border-radius:50% follows
   whatever box it is given. The HTML attributes matter too — they are what
   reserves the space before the image arrives, and leaving them at 56 would
   reintroduce the layout shift they exist to prevent.
   size="xs" is still right: 150w over a 50px circle is 3x, ample on any screen. */
.foot-post-media {
    display: block; flex: none;
    width: 50px; height: 50px;
    border-radius: 50%; overflow: hidden;
    /* the well shows through for a post with no feature image, so the row keeps
       its shape instead of collapsing to a bare title */
    background: rgba(255,255,255,.10);
}
.foot-post-media img {
    width: 50px; height: 50px;      /* explicit: the global `img { height:auto }`
                                       would otherwise letterbox a non-square
                                       source inside the circle */
    object-fit: cover; border-radius: 50%;
}
.foot-post-title {
    font-family: var(--font-head); font-weight: 600;
    font-size: .92rem; line-height: 1.35;
    /* Titles on this site run long — several exceed 90 characters. Unclamped,
       one of them turns a 56px row into a 5-line block and the five circles
       stop reading as a list. Two lines, then ellipsis. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.site-foot .foot-post-link:hover .foot-post-title,
.site-foot .foot-post-link:focus-visible .foot-post-title {
    color: var(--aq-white); text-decoration: underline;
}
.site-foot .foot-post-link:hover .foot-post-media { background: rgba(255,255,255,.20); }

/* margin-bottom was 2rem, spacing the cloud off the social row that used to sit
   under it. The widget grid owns that spacing now. */
.tag-cloud { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.site-foot .tag-pill {
    background: rgba(255,255,255,.10); color: var(--aq-white);
}
/* Hover fill moved to the brand palette 2026-08-06: #FFA744 -> --aq-apricot
   #FFCD9C. The amber was picked by eye on 2026-08-05 and was the last hand-
   chosen hex left in the stylesheet after the accent and title repaint.
   APRICOT IS THE RIGHT BRAND ANSWER RATHER THAN MERELY A NEARBY ONE: it is the
   sunset band in the badge, 3.27% of the artwork by area, and it is the same
   warm family the amber was reaching for — so this keeps the look that was asked
   for while making it a measured colour instead of an invented one.
   THE PAIR STILL HOLDS, AND IT IS WHY THIS RULE SETS BOTH PROPERTIES. Apricot is
   a light fill (1.45:1 on white — the palette marks it FILL ONLY), so the label
   must stay dark. --aq-ink on apricot is 9.72:1 straight off the kit's contrast
   matrix, up from 8.76:1 on the amber. Leave the colour off and the label would
   inherit the footer's white and sit at ~1.4:1 — invisible at the exact moment
   of interaction, which is the failure this rule has already been fixed for once. */
.site-foot .tag-pill:hover { background: var(--aq-pillhover); color: var(--aq-ink); }
/* SPLIT ROW 2026-08-06, by request: legal links LEFT, copyright RIGHT.
   This undoes the centring of 2026-08-05, which was itself put in because the
   copyright was a lone line of type pinned to one corner with nothing opposite
   it. There is something opposite it now, so a split row is what it wanted all
   along.
   The v1.4.0 comment warned that `justify-content` on a row would centre a nav
   and the copyright as a GROUP, leaving the copyright off-centre. The same trap
   applies to space-between: with three children the copyright lands in the
   MIDDLE, not the right. That is why default.hbs wraps the legal nav and any
   future secondary nav in .foot-meta-left — this row has exactly two children by
   construction, so the split cannot drift with content. */
.foot-meta {
    border-top: 1px solid rgba(255,255,255,.14); padding-top: 1.25rem;
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between;
    gap: .75rem 1.5rem;
    text-align: left;
}
.foot-meta-left { display: flex; flex-direction: column; gap: .5rem; }
.foot-nav ul { list-style: none; display: flex; flex-wrap: wrap; gap: .25rem 1rem; margin: 0; padding: 0; }
.foot-nav li { list-style: none; }
.foot-nav li a { display: inline-flex; align-items: center; min-height: 36px; }
/* Same shape as .foot-nav — this is the hardcoded sibling of it, so the two must
   look identical whether the links come from the theme or from Ghost's secondary
   navigation. Colour is inherited from `.site-foot a` (white, 16.22:1 on the
   #300060 footer) and is deliberately not restated: one declaration, not two
   that drift.
   1.25rem of column gap rather than .foot-nav's 1rem: four long labels sit
   closer to each other than three short ones read as. 36px rows keep each label
   clear of the WCAG 2.5.8 24x24 floor when they wrap to two lines on a phone. */
.foot-legal ul { list-style: none; display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; margin: 0; padding: 0; }
.foot-legal li { list-style: none; }
.foot-legal a { display: inline-flex; align-items: center; min-height: 36px; font-size: .88rem; }
.foot-copy { margin: 0; font-size: .88rem; color: var(--aq-white); }

/* Below 640px the two halves stack, and a left-aligned block over a
   right-aligned one reads as a mistake rather than a layout. So the split only
   exists where there is room for it and everything re-centres underneath.
   640px is the same breakpoint .foot-widgets uses to go from one column to two,
   so the footer changes shape once rather than twice. */
@media (max-width: 639px) {
    .foot-meta { flex-direction: column; align-items: center; text-align: center; }
    .foot-meta-left { align-items: center; }
    .foot-legal ul { justify-content: center; }
}

/* --- social icons ------------------------------------------------------- */
/* One partial serves both places: a compact three in the header nav and the full
   set in the footer. Ported from wisdom-life-quotes v1.2.1. Class names match that
   theme deliberately, so the fleet has one vocabulary for this component. */
.social-icons {
    display: flex; flex-wrap: wrap; gap: .25rem;
    list-style: none; margin: 0; padding: 0;
}
.social-icons li { list-style: none; }
.social-icon {
    display: inline-flex; align-items: center; justify-content: center;
    /* WCAG 2.5.8 is AA at 24x24. 38 clears it with margin without making the
       header taller than the 46px logo. The footer set gets --tap below. */
    width: 38px; height: 38px;
    border-radius: 50%;
    color: inherit; text-decoration: none;
}
.social-icon svg { width: 19px; height: 19px; display: block; }

/* Header: the bar is WHITE again as of 2026-08-06, so these go back to the nav's
   ink — --aq-ink #022A5C, 14.11:1 — after a spell at white for the violet bar.
   THE HOVER HAD TO BE REBUILT, NOT JUST RE-INKED. It was "invert to a white disc
   with the accent as the glyph", which is a real inversion on a dark bar and is
   NO CHANGE AT ALL on a white one — a white disc on white, and the only visible
   difference would have been the glyph shifting navy to amethyst. So the disc
   takes --aq-sky, matching the nav's hover pill exactly, and the glyph stays
   navy at 11.14:1. One hover treatment for both halves of the nav row.
   FOUR icons here now, not three — Pinterest joined the compact set. They sit in
   a --tap-tall flex row inside .site-nav, which has no fixed count, so the extra
   circle needs no rule; but see the 800-1023px block below, which hides this row
   entirely because six nav items plus icons wrapped the bar. That measurement
   was taken with three icons and the fourth only widens the case for hiding
   them, so the breakpoint still holds. */
.site-social .social-icon { color: var(--aq-ink); }
.site-social .social-icon:hover { background: var(--aq-tint); color: var(--aq-ink); }

/* Footer: two class selectors, so this beats the .site-foot a colour rule above. */
/* The row now sits INSIDE widget 1, under the about paragraph, rather than as a
   standalone block above .foot-meta. It carried margin-top:1.1rem to open that
   gap; the "Join Our Community" heading now sits between the two and owns the
   spacing on both sides. Left at 1.1rem this would COLLAPSE with the heading's
   .6rem bottom margin to 1.1rem — adjacent siblings collapse to the larger — and
   push the icons away from the heading that labels them. */
.foot-social { margin-top: 0; }

/* EIGHT ICONS IN A COLUMN THAT IS NO LONGER FULL WIDTH.
   As a wrapping flex row this broke 7 + 1 at every desktop and tablet width
   measured — 1440, 1024 and 800 — because eight 44px targets plus their gaps
   need 408px and the about track is 284-389px across that range. One icon
   stranded on its own line reads as a bug rather than a layout.
   There is no width that fixes it: shrinking the icons to 38px still overflows
   at 1024, and widening the track starves the category cloud. So the count is
   stated instead of left to the container — a fixed 4x2 block, which needs
   200px and therefore fits every column this grid can produce, down to a 320px
   phone. Targets stay at 44px, well clear of the 24x24 WCAG 2.5.8 AA floor.
   max-content, not 1fr: 1fr would stretch each cell to fill the track and space
   the circles apart differently in every column width. */
.foot-widget-about .social-icons {
    display: grid;
    grid-template-columns: repeat(4, max-content);
    /* 15px — 8 -> 10 -> 20 -> 15 by request. Stated in px rather than rem
       because the ask was in px and because this is the space between two
       fixed-size circles, not type; it should not scale with the root font size.
       Applies on BOTH axes, so the two rows separate by the same 15px.
       Fits comfortably: a 4x2 block of 44px targets is 4*15 + ... i.e.
       4*44 + 3*15 = 221px, and the narrowest column this grid produces is
       ~284px.
       THIS IS THE ONLY GAP FOR THIS ROW. `.foot-social .social-icons` below used
       to set one too; both selectors are (0,2,0) and both match, so the value
       was decided purely by source order — the kind of pair that gets edited in
       the wrong place six months later. Its declaration was removed. */
    gap: 15px;
    justify-content: start;
}
/* gap deliberately NOT set here — see .foot-widget-about .social-icons, which is
   the single source of truth for this row's spacing. Two equal-specificity rules
   both setting it meant source order silently decided the winner. */
.site-foot .social-icon {
    width: var(--tap); height: var(--tap);
    background: rgba(255,255,255,.10); color: var(--aq-white);
}
.site-foot .social-icon svg { width: 20px; height: 20px; }
/* Hover inverts to a white disc with the brand colour as the glyph, rather than
   the brand-coloured disc wisdom-life-quotes uses. That theme's footer is a light
   surface; this one is near-black, where X's #000 and Tumblr's #36465D as
   backgrounds read as a hole punched in the page. Same pattern, different ground. */
.site-foot .social-icon:hover      { background: var(--aq-white); }
.site-foot .social-facebook:hover  { color: #1877F2; }
.site-foot .social-instagram:hover { color: #C13584; }
.site-foot .social-x:hover         { color: #000000; }
.site-foot .social-pinterest:hover { color: #BD081C; }
.site-foot .social-youtube:hover   { color: #FF0000; }
.site-foot .social-tumblr:hover    { color: #36465D; }
/* Flickr is new in this theme — wisdom-quotes-4u has no Flickr account, so the
   partial it was forked from had no icon and this file had no rule. #FF0084 is
   Flickr's pink; it sits on the WHITE hover disc, not on the navy footer, so the
   comparison that matters is 3.76:1 on white — clear of the 3:1 WCAG 1.4.11 asks
   of a non-text indicator, and the tightest margin of any icon in this row.
   Measured, not estimated: against --aq-ink it would read 4.48:1, which is the
   more flattering number and the wrong one. Do not quote it. */
.site-foot .social-flickr:hover    { color: #FF0084; }
.site-foot .social-email:hover     { color: var(--aq-accent); }

/* --- motion ------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
    /* :focus-within added alongside :hover — the card now lifts on keyboard focus
       too, and killing only the hover transform would leave keyboard users with
       the motion this query exists to suppress. */
    .quote-card:hover,
    .quote-card:focus-within { transform: none; }
}

/* --- single-post sidebar ------------------------------------------------ */
/* Added 2026-08-06 by request: a right sidebar on single posts only, carrying
   Facebook follow, subscribe, categories and archives.

   THE ARTICLE MEASURE IS NOT TOUCHED. The left track is capped at
   --wrap-narrow, the same 720px the post body has always used, so line length
   is identical to before at every width. The sidebar is added beside the
   article inside the wider --wrap, not carved out of it.

   Everything below inherits the existing tokens - no new colours are introduced
   and no contrast pair here is new. The pairs in use are --aq-text and
   --aq-title on --aq-paper, and --aq-accent on --aq-surface, all of which
   are measured further up this file.                                          */

.post-layout {
    --side-w: 400px;   /* sized to the Facebook frame; see widget-facebook.hbs */
    --side-gap: 2.5rem;
}

/* STACKED IS THE DEFAULT, and the wide layout is the override. Written this way
   round because the stacked case is the one most of this site's readers get -
   the traffic is overwhelmingly mobile - so it is the case that should need no
   media query to be correct. */
/* A FLEX COLUMN, PURELY SO THE STACKED ORDER CAN BE SET INDEPENDENTLY OF THE DOM.
   Changed 2026-08-06 by request: on a phone the comments must come DIRECTLY under
   the post, before the sidebar starts.

   The DOM order is main, sidebar, extra — and it has to stay that way, because on
   the wide layout the sidebar is a grid item spanning both rows and reordering the
   source would put it after the comments it is supposed to run alongside. `order`
   changes the visual sequence without touching the source, which is exactly the
   case it exists for.

   Source order still degrades sensibly: with CSS off, a reader gets post, sidebar,
   comments — all present, none trapped. And because `order` does not affect the
   accessibility tree, the tab sequence follows the DOM; that is the known cost of
   this technique, and it is acceptable here because all three regions are landmarked
   and reachable, rather than a control being separated from what it controls. */
.post-layout { display: flex; flex-direction: column; }
.post-main    { order: 1; }
.post-extra   { order: 2; }   /* comments — directly under the article on a phone */
.post-sidebar { order: 3; }

.post-main,
.post-extra,
.post-sidebar {
    width: min(100%, var(--wrap-narrow));
    margin-inline: auto;
}
.post-sidebar { margin-top: 2.75rem; }

/* 1200px = 720 article + 40 gap + 400 sidebar + the 2rem .wrap gutter, rounded
   up. Below it the grid does not apply at all and the three children are plain
   stacked blocks in DOM order: article, sidebar, comments. */
@media (min-width: 1200px) {
    .post-layout {
        display: grid;
        grid-template-columns: minmax(0, var(--wrap-narrow)) var(--side-w);
        column-gap: var(--side-gap);
        /* The pair is 1160px inside an 1180px wrap, so it needs centring.
           justify-content on the GRID, not margin auto on the items - auto
           margins are consumed before the tracks are placed. */
        justify-content: center;
        align-items: start;
    }
    /* Explicit placement, because the sidebar has to span both rows: the
       comments sit under the article in column 1 while the sidebar continues
       past them. Implicit placement would put the comments beside the sidebar.
       These also make the `order` values above irrelevant here — explicit
       placement wins over order — so the wide layout is unaffected by the
       phone-only reordering. */
    .post-main    { grid-column: 1; grid-row: 1; }
    .post-sidebar { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; }
    .post-extra   { grid-column: 1; grid-row: 2; }

    .post-main,
    .post-extra,
    .post-sidebar { width: auto; margin-inline: 0; }
}

/* STICKY SIDEBAR, PINNED BY ITS BOTTOM EDGE — 2026-08-06, chosen by request
   after the alternatives were measured.

   THE PROBLEM THIS SOLVES: the column is 909px and the viewport is 895px. A
   top-pinned sticky element that is TALLER than the viewport hangs its lower
   part off the bottom of the screen and scrolling can never bring it back —
   measured overflowing by 120px, with the archives dropdown simply unreachable.
   Two other fixes were tried and rejected: an inner `max-height` + `overflow-y`
   worked but put a second scrollbar inside the column (removed by request), and
   shrinking the sidebar to fit worked but cost the Facebook timeline (restored
   by request).

   WHY `bottom` FIXES IT. With `bottom: 1rem` the column scrolls with the page
   until its BOTTOM edge reaches 1rem above the viewport floor, and pins there.
   So reading down the page walks the reader through the whole column — the
   widgets below the fold arrive as you scroll rather than being stranded — and
   from then on it holds position. Everything stays reachable at any viewport
   height, with no inner scrollbar and no height cap. The cost, stated: once
   pinned, the TOP of the column (the Facebook widget) sits above the viewport,
   so it is the bottom widgets that stay on screen. Scrolling back up returns it.

   `top: auto` is REQUIRED, not tidiness — it undoes the previous top offset.
   Sticky honours BOTH edges if both are set, and a box with `top` and `bottom`
   on an element taller than the gap between them stays stuck to `top`, which
   would have silently reproduced the exact bug this replaces.

   No `align-self` is needed: the grid already sets `align-items: start`, so the
   column begins at the top of its area and only leaves it on scroll.

   Desktop only — inside the min-width:1200px block, because on a phone the
   sidebar is a stacked block and pinning it would mean nothing. */
@media (min-width: 1200px) {
    /* The aside stretches to fill its whole grid area — article + comments +
       related — purely to give the sticky child room to travel. `align-items:
       start` on the grid would otherwise size it to its content and there would
       be nothing to stick inside; that was measured failing to pin at all. */
    .post-sidebar { align-self: stretch; }
    .post-sidebar-inner {
        /* MEASURED HEIGHT OF THE COLUMN. It is a hardcoded approximation and the
           one fragile number in this rule: if a widget is added, removed or
           resized, re-measure and update it. Being wrong is not fatal — too
           small leaves a gap under the pinned column, too large hides a little
           of its bottom — but it will drift. Re-measured 2026-08-06 after the
           timeline was removed: 945 -> 700. THE STALE 945 WAS A LIVE BUG for one
           deploy — with the column at 698 the min() still resolved to the short-
           viewport branch (-66px), so it pinned ABOVE the header instead of under
           it, on a screen it now fits comfortably. Exactly the drift predicted
           two lines up. UPDATE THIS WHENEVER A WIDGET CHANGES. */
        --side-h: 899px;

        position: sticky;
        /* THE OFFSET-TOP TRICK, and why `bottom` is NOT used here.
           `bottom` on a sticky box engages while scrolling UP — it stops the box
           falling below the scrollport floor. It does nothing on the way DOWN,
           which is the direction that matters for a sidebar. Setting
           `bottom: 1rem` was tried and measured never pinning once, at any
           scroll position, and it still did not pin when the column was
           temporarily shrunk below the viewport height — which ruled out height
           as the cause and identified the semantics as the cause.

           min() of two offsets gives the right behaviour at both extremes with
           no JavaScript:
             - TALL viewport, where the column fits: the first term wins and this
               is ordinary top-sticky, pinned under the 90px site header.
             - SHORT viewport, where the column is taller than the screen: the
               second term is smaller (often negative), so the column scrolls up
               with the page until its BOTTOM sits 1rem above the viewport floor,
               and pins there. The reader walks down through the whole column on
               the way, so nothing is stranded — which was the entire problem. */
        top: min(calc(90px + 1rem), calc(100vh - var(--side-h) - 1rem));
    }
    /* THE INNER SCROLL WAS REMOVED 2026-08-06 BY REQUEST — plain sticky, no
       max-height, no overflow. Stating the consequence once rather than
       rediscovering it later: this column runs to roughly 1,100px and a laptop
       viewport is ~800-900px, so on a short screen the bottom of the sidebar
       (the archives dropdown) sits below the fold and STAYS there — a sticky
       element taller than the viewport pins its top, so scrolling the page no
       longer brings its lower part into view. That is the trade for having no
       scrollbar inside the column, and it was chosen deliberately. It is not
       visible on a tall monitor, where the whole column fits.
       If it becomes a problem, the fix is `align-self: end` with `top: auto;
       bottom: 1rem`, which pins the BOTTOM instead — everything stays reachable
       and there is still no inner scrollbar, at the cost of the Facebook widget
       scrolling out of view. */
}

/* 2rem -> 3.25rem by request, 2026-08-06. The four widgets are visually
   distinct things (a Facebook frame, a form, and two dropdowns) and at 2rem the
   accent rule under each heading read as though it belonged to the widget
   ABOVE it rather than the one below. The gap is now clearly larger than any
   space inside a widget, which is what makes the grouping unambiguous.
   :last-child keeps the column from ending in dead space. */
.side-widget { margin-bottom: 1.75rem; }
.side-widget:last-child { margin-bottom: 0; }

.side-heading {
    position: relative;
    font-family: var(--font-head);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--aq-title);
    margin: 0 0 .6rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid rgba(var(--aq-ink-rgb),.10);
}
/* A short accent rule sitting on the hairline. Decorative only - it carries no
   information, so its contrast is comfort rather than a requirement. */
.side-heading::after {
    content: "";
    position: absolute;
    left: 0; bottom: -1px;
    width: 44px; height: 2px;
    background: var(--aq-accent);
}

/* --- sidebar: facebook --- */
/* One card holding OUR header and Facebook's cropped frame, so the two read as a
   single widget rather than as a heading with an embed stuck under it. The
   border and radius live here; the frame inside carries neither. */
.fb-card {
    border: 1px solid rgba(var(--aq-ink-rgb),.14);
    border-radius: var(--radius);
    background: var(--aq-white);
    overflow: hidden;
}
/* The cover. object-fit:cover with a fixed box means the visible slice can be
   re-tuned here without re-encoding the asset — the file is the full 16:9 frame.
   object-position sits slightly below centre because the artwork's subject (the
   tree, the figure and the wordmark) is in the lower two thirds and the top is
   mostly empty sky. */
.fb-card-cover {
    display: block;
    width: 100%;
    height: 100px;
    object-fit: cover;
    object-position: center 50%;
    background: var(--aq-surface);
}
.fb-card-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .7rem;
    border-bottom: 1px solid rgba(var(--aq-ink-rgb),.10);
}
.fb-card-avatar {
    flex: 0 0 auto;
    width: 42px; height: 42px;
    border-radius: 50%;
    background: var(--aq-surface);
}
/* min-width:0 so a long site title wraps instead of forcing the row wider than
   the card — the same flex default that bit the archive rows. */
.fb-card-text { min-width: 0; }
.fb-card-name {
    display: block;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: .95rem;
    line-height: 1.25;
    color: #022A5C;
    text-decoration: none;
}
.fb-card-name:hover { color: #0072A1; text-decoration: underline; }
/* This is the line Facebook could not render legibly. --aq-muted is 5.39:1 on
   white, AA at this size. */
.fb-card-followers {
    margin: .15rem 0 0;
    font-family: var(--font-head);
    font-size: .83rem;
    color: var(--aq-muted);
}
/* Replaces Facebook's own Follow + Share bar, which the crop removed. Its own
   row on the surface tint, mirroring the bar Facebook drew there. */
.fb-card-actions {
    display: flex;
    gap: .5rem;
    padding: .45rem .7rem;
    background: var(--aq-surface);
    border-bottom: 1px solid rgba(var(--aq-ink-rgb),.10);
}
.fb-card-btn {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    padding: 0 .8rem;
    border: 1px solid #0072A1;
    border-radius: 6px;
    background: #FFFFFF;
    color: #0072A1;
    font-family: var(--font-head);
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
}
.fb-card-btn:hover { background: #0072A1; color: #FFFFFF; }

/* Share, as a square icon button beside Follow. flex:0 0 auto with a matching
   36px min-height keeps it square and stops it stretching to share the row —
   Follow takes the remaining width. 36px clears WCAG 2.5.8's 24x24 comfortably;
   it is the same height as the button it sits next to, so the row reads as one
   control group rather than two sizes. */
.fb-card-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    min-height: 34px;
    border: 1px solid #0072A1;
    border-radius: 6px;
    background: #FFFFFF;
    color: #0072A1;
    text-decoration: none;
}
.fb-card-icon:hover { background: #0072A1; color: #FFFFFF; }
.fb-card-icon svg { display: block; }
/* Follow is the action being asked for, so it carries the fill and Share is the
   outline — same primary/secondary pairing as the subscribe buttons, so the two
   widgets teach the reader one visual language rather than two. */
.fb-card-btn-primary {
    background: #0072A1;
    color: #FFFFFF;
}
.fb-card-btn-primary:hover { background: #022A5C; border-color: #022A5C; }

/* THE CROP. The frame is requested 490px tall and pulled up by 130px inside a
   360px window, so Facebook's broken 130px header is clipped off and the
   timeline begins at the top of the box: 280 - 130 = 150 visible.
   line-height:0 kills the inline-descender gap an iframe would otherwise leave.
   The three numbers are load-bearing together — changing the visible height
   means changing the requested height by the same amount, or the last post gets
   cut mid-card. */
.fb-embed-clip {
    height: 150px;
    overflow: hidden;
    line-height: 0;
    background: var(--aq-surface);
}
.fb-embed-frame {
    display: block;
    border: 0;
    width: 400px;
    height: 280px;
    max-width: 100%;
    margin-top: -130px;   /* clips Facebook's own header — see widget-facebook.hbs */
}

/* --- sidebar: subscribe --- */
.side-sub-intro {
    margin: 0 0 .85rem;
    font-size: .93rem;
    line-height: 1.55;
    color: var(--aq-muted);
}
.side-sub-form { display: flex; flex-direction: column; gap: .6rem; }
.side-sub-input {
    width: 100%;
    min-height: 44px;
    padding: .55rem .8rem;
    font: inherit;
    font-size: .95rem;
    color: var(--aq-text);
    background: var(--aq-white);
    border: 1px solid rgba(var(--aq-ink-rgb),.22);
    border-radius: var(--radius);
}
.side-sub-input::placeholder { color: var(--aq-muted); opacity: 1; }
/* Two actions side by side. They are NOT equal weight: Subscribe is the primary
   filled button and takes the larger share, Unsubscribe is a quiet outline. A
   destructive-ish action drawn as loudly as the one you want people to take is
   how you get accidental clicks, and this pair sits under a single shared field
   where the only thing distinguishing them is their appearance.
   flex-wrap plus a sensible basis means they stack rather than squeeze on the
   narrowest phones, where 2 x 44px targets do not fit one row. */
.side-sub-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.side-sub-btn {
    flex: 1 1 auto;
    min-width: 8.5rem;
    min-height: 44px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--aq-accent);
    color: var(--aq-white);
    font-family: var(--font-head);
    font-size: .95rem;
    font-weight: 600;
    cursor: pointer;
}
.side-sub-btn:hover { background: var(--aq-ink-strong); }
.side-sub-btn[disabled] { opacity: .6; cursor: default; }

/* --aq-accent on white is 5.36:1, so the outline treatment keeps AA for the
   label and clears the 3:1 that WCAG 1.4.11 asks of the border as a boundary.
   Hover fills it rather than shifting the text colour, so the two buttons meet
   at the same visual weight only at the moment of intent. */
.side-sub-btn-secondary {
    flex: 0 1 auto;
    background: transparent;
    color: var(--aq-accent);
    border-color: var(--aq-accent);
}
.side-sub-btn-secondary:hover {
    background: var(--aq-accent);
    color: var(--aq-white);
}

/* THE HONEYPOT MUST NOT USE display:none. Some bots specifically skip fields
   that are display:none, which defeats the point; but a field merely moved
   offscreen stays in the tab order, so the markup ALSO carries tabindex="-1"
   and aria-hidden. Both halves are needed - this rule alone would leave a
   keyboard trap, the attributes alone would leave a visible box. */
.side-sub-hp {
    position: absolute;
    left: -9999px;
    width: 1px; height: 1px;
    overflow: hidden;
}

/* Empty at rest, so it occupies no space and cannot shift the layout when a
   message arrives - :empty is what makes that true without JavaScript having to
   toggle a class for it. */
.side-sub-msg {
    margin: 0;
    font-size: .88rem;
    line-height: 1.5;
    color: var(--aq-muted);
}
.side-sub-msg:empty { display: none; }
.side-sub-form.is-error .side-sub-msg { color: var(--aq-accent-alt); }
.side-sub-form.is-success .side-sub-msg { color: var(--aq-ink-strong); font-weight: 600; }

/* --- sidebar: the two dropdowns --- */
/* Shared by categories and archives so the pair reads as one control type. */
.side-drop {
    border: 1px solid rgba(var(--aq-ink-rgb),.14);
    border-radius: var(--radius);
    background: var(--aq-white);
}
.side-drop-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 44px;
    padding: .55rem .85rem;
    cursor: pointer;
    font-family: var(--font-head);
    font-size: .93rem;
    font-weight: 600;
    color: var(--aq-title);
    list-style: none;
}
/* Removes the default triangle in both engines. The custom chevron below
   replaces it and, unlike the native marker, can be rotated on open. */
.side-drop-toggle::-webkit-details-marker { display: none; }
.side-drop-toggle::marker { content: ""; }

.side-drop-chevron {
    flex: 0 0 auto;
    width: 8px; height: 8px;
    border-right: 2px solid var(--aq-accent);
    border-bottom: 2px solid var(--aq-accent);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .15s ease;
}
.side-drop[open] > .side-drop-toggle .side-drop-chevron {
    transform: rotate(225deg) translate(-2px, -2px);
}

/* A HEIGHT CAP IS MANDATORY ON THESE TWO, not a nicety: the categories panel is
   28 rows and the archives panel is 7 years of up to 12 months. Uncapped, an
   open dropdown would be several screens tall and would push the comments far
   down the page on a phone. Capped and scrollable, it behaves like the control
   it is drawn as. */
.side-drop-panel {
    max-height: 320px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-top: 1px solid rgba(var(--aq-ink-rgb),.14);
    padding: .35rem;
}

.side-drop-panel ul { list-style: none; margin: 0; padding: 0; }

.side-cat-name, .side-month-link > span:first-child { min-width: 0; }

.side-cat-link,
.side-month-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    min-height: 36px;
    padding: .3rem .55rem;
    border-radius: 6px;
    text-decoration: none;
    font-size: .9rem;
    color: var(--aq-text);
}
.side-cat-link:hover,
.side-month-link:hover {
    background: var(--aq-surface);
    color: var(--aq-accent);
}

/* The count badge. --aq-muted is 5.39:1 on the page and on the card surface,
   so it is AA at this size; it is deliberately quieter than the label beside
   it, which is the thing being chosen. */
.side-count {
    flex: 0 0 auto;
    font-family: var(--font-head);
    font-size: .78rem;
    font-weight: 600;
    color: var(--aq-muted);
    background: var(--aq-surface);
    border-radius: 999px;
    padding: .1rem .5rem;
}

/* --- sidebar: archives, the nested year level --- */
.side-year-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 38px;
    padding: .3rem .55rem;
    border-radius: 6px;
    cursor: pointer;
    font-family: var(--font-head);
    font-size: .92rem;
    font-weight: 700;
    color: var(--aq-title);
    list-style: none;
}
.side-year-toggle::-webkit-details-marker { display: none; }
.side-year-toggle::marker { content: ""; }
.side-year-toggle:hover { background: var(--aq-surface); }
.side-months { padding-left: .5rem; margin-bottom: .35rem; }
.side-month-all { font-weight: 600; color: var(--aq-accent); }

/* --- archive pages ------------------------------------------------------ */
.archive-page { padding-block: clamp(1.75rem, 5vw, 3rem); }
.archive-head { text-align: center; margin-bottom: 1.75rem; }
.archive-kicker {
    margin: 0 0 .35rem;
    font-family: var(--font-head);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--aq-accent);
}
.archive-title { font-size: clamp(1.6rem, 4.5vw, 2.4rem); color: var(--aq-title); margin: 0 0 .35rem; }
.archive-count { margin: 0; color: var(--aq-muted); font-size: .92rem; }
.archive-up { font-weight: 600; }

.archive-list { list-style: none; margin: 0; padding: 0; }
.archive-item + .archive-item { border-top: 1px solid rgba(var(--aq-ink-rgb),.10); }
.archive-link {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    min-height: 44px;
    padding: .7rem .5rem;
    text-decoration: none;
    color: var(--aq-text);
}
.archive-link:hover { background: var(--aq-surface); color: var(--aq-accent); }
/* min-width:0 is load-bearing, not tidiness. A flex item defaults to
   min-width:auto, which refuses to shrink below its content, so a long post
   title beside a fixed-width date would push the row wider than the page on a
   phone. Titles here run to 60+ characters, so this is the common case rather
   than an edge one. The same reason applies to .side-cat-name below. */
.archive-item-title { font-weight: 600; min-width: 0; }
/* The date must never wrap or shrink - it is the column the eye scans down. */
.archive-item-date {
    flex: 0 0 auto;
    font-family: var(--font-head);
    font-size: .82rem;
    color: var(--aq-muted);
    white-space: nowrap;
}
.archive-empty { text-align: center; color: var(--aq-muted); }

/* --- "More like this" — 3 smaller cards ---------------------------------- */
/* Changed 2026-08-06 by request: three posts instead of four, with smaller
   artwork.

   THE IMAGES ARE MADE SMALLER BY NARROWING THE GRID, NOT BY CROPPING HARDER.
   Dropping to three cards in the full 1180px wrap would have made each card
   WIDER and the images BIGGER — the opposite of what was asked. Shrinking
   .quote-card-media's aspect-ratio instead would have cropped more off each
   image, and this site's artwork is quote graphics with the words baked into
   the picture, so a taller crop eats the start and end of the sentence. That
   exact defect is recorded against this theme already.

   So the grid is capped to the 720px article measure and centred. Three cards
   at ~226px are meaningfully smaller than four at ~277px, nothing is cropped
   any harder than before, and the section now lines up with the column of text
   above it instead of running wider than the article it belongs to. */
@media (min-width: 700px) {
    .related .quote-grid { grid-template-columns: repeat(3, 1fr); }
}

/* IT LIVES INSIDE THE ARTICLE COLUMN NOW, so the full-bleed treatment has to go.
   `.related` above still carries `background: var(--aq-surface)` and a top
   border from when it was a page-width band below everything; left alone, that
   band would now be a tinted rectangle floating inside a 720px column with the
   page white on either side of it.

   Reset to match .post-comments directly above it instead — a hairline rule and
   space, nothing else. The two sections under the article are then the same
   shape as each other, which is the point of moving this one up here.

   The full-width band rule is not deleted: `.related` is a shared class and
   removing its background would change any future page that still uses it
   full-bleed. Overridden in place, scoped to this context. */
.post-extra .related {
    background: none;
    border-top: 1px solid var(--aq-surface);
    margin-top: 1.75rem;
    padding-top: 1.5rem;
}
/* The max-width caps that centred this on the 720px measure are GONE — the
   column IS 720px now, so they were a no-op at best and would fight any future
   change to the article measure. */

/* ==========================================================================
   ADSENSE — GENERATED by output/ghost-fleet-port-v3/gen/ads.js

   Two units on a post (in-article + a desktop-only sidebar unit), four
   positions on an archive (in-feed x2, display mid-grid, display above the
   pagination). Reasoning for that split is in ads.js.

   EVERY SLOT RESERVES ITS HEIGHT. An unfilled unit leaves a stable gap rather
   than collapsing — a collapse is a layout shift on every page where the
   auction does not fill, which is a Core Web Vitals cost paid for zero revenue.
   ========================================================================== */
.ad-slot {
    display: block;
    margin: 1.75rem 0;
    /* The label is not decoration — AdSense requires ad units to be
       distinguishable from content, and an unlabelled block that looks like a
       card is how accidental clicks (and therefore invalid traffic) happen. */
    position: relative;
    background: var(--aq-surface);
    border-radius: var(--radius);
    overflow: hidden;
}
.ad-slot::before {
    content: "Advertisement";
    display: block;
    font-family: var(--font-head);
    font-size: .62rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--aq-muted);
    text-align: center;
    padding: .35rem 0 .1rem;
}
.ad-slot .adsbygoogle { display: block; width: 100%; }

/* RESERVED HEIGHTS. A responsive unit fills the width it is given and picks its
   own height, so these are the minimum the box holds while the auction runs. */
.ad-inarticle { min-height: 280px; }
.ad-display,
.ad-footer    { min-height: 280px; }
.ad-sidebar   { min-height: 600px; }          /* 300x600 is the sidebar's best earner */
.ad-infeed    { min-height: 200px; }          /* in-feed must keep a VARIABLE height */

/* BANNER — 2026-08-07, ported from wisdomquotes4u. Four instances: three on the
   index, one in the post sidebar, plus one above the comments standing in
   for the in-feed unit this site does not have.

   THE RESERVATION TRACKS THE FORMAT. These are data-ad-format="auto", which can
   return a 336x280 or taller, so 280px is the floor it needs; a shorter box
   would jump when the creative lands. Google collapses the box to 0 with
   min-height:0!important when the unit does not fill. */
.ad-banner    { min-height: 280px; }

@media (min-width: 700px) {
    .ad-inarticle { min-height: 280px; }
    .ad-display,
    .ad-footer    { min-height: 280px; }
}

/* ── UNITS INSIDE THE CARD GRID ───────────────────────────────────────────────

   A FULL-WIDTH CHILD STRANDS CELLS, AND IT IS VISIBLE. The first build spanned
   every in-grid unit across the whole row. On a 4-column desktop grid an ad
   after card 6 ends row 2 early and leaves two empty cells beside cards 5 and 6
   — a hole in the middle of the page. Only a screenshot showed it; every
   assertion passed.

   THE FIX IS DIFFERENT FOR THE TWO FORMATS, because they want different things:

   IN-FEED takes ONE CELL, which is what an in-feed unit is FOR — it is the
   format designed to render as one more item in your feed, so a single card-
   sized cell is its native shape and the grid stays perfectly packed at every
   column count. min-width:0 is mandatory: without it the unit's intrinsic
   minimum can force its track wider and push every card in that row out with
   it, which is how a fixed 300px unit once overflowed a 320px page by 11px
   while the measuring harness blamed the card.

   DISPLAY spans the row, and is therefore only ever placed at CARD 12 — the one
   position that divides evenly by 1, 2, 3 and 4, so it can never land mid-row
   whatever the viewport does. The grid is auto-fill below 1000px, so the column
   count genuinely is all four of those values in normal use. */
.quote-grid .ad-infeed {
    grid-column: auto;
    min-width: 0;
    margin: 0;
}
.quote-grid .ad-display { grid-column: 1 / -1; margin: .5rem 0; }

/* The unit between the last card and the pagination. */
.ad-footer { margin-top: 2rem; }

/* THE SIDEBAR UNIT IS DESKTOP-ONLY.
   Below the sidebar's own breakpoint the column stacks under the article and
   the comments; a unit there would be a third on a very short page, at the
   bottom of a screen most readers never reach. main.js only pushes it when it
   is actually laid out, so this hides an element that was never filled rather
   than burning an unviewable impression. */
.ad-sidebar { display: none; }
@media (min-width: 1200px) {
    .ad-sidebar { display: block; margin: 0 0 1.5rem; }
}

/* The in-article unit sits between two paragraphs of a quote, so it needs more
   air than the archive units and a rule above it to separate it from the copy. */
.post-content + .ad-inarticle,
.ad-inarticle { margin-block: 2rem; }

/* --- THE SIDEBAR ON EVERY TEMPLATE BUT THE HOME PAGE --------------------- */
/* Added 2026-08-07 by request. The sidebar rendered only from post.hbs; it now
   also renders from page, tag, author, archive, archive-year, archive-month
   and error. index.hbs is deliberately the one exception — the home page keeps
   its full-width layout.

   NOTHING ABOVE THIS COMMENT WAS CHANGED, and that is the design of the patch:
   those templates now emit the same .post-layout / .post-main / .post-sidebar
   structure post.hbs already emitted, so they inherit the stacked-by-default
   flex column, the 1200px grid breakpoint and the whole sticky rule verbatim.
   Reusing the primitives rather than writing a parallel set is what keeps one
   sidebar looking like one sidebar across seven templates. Only the two cases
   below need anything new.

   THE COST, STATED PLAINLY RATHER THAN DISCOVERED LATER: the Facebook iframe
   and the two {{#get}} queries behind the categories and archives dropdowns
   now run on every category, author, archive and 404 page as well as every
   post. Those pages previously loaded no third-party frame at all. That is the
   price of the request, not a bug — but it is the number to watch if listing
   pages get slower.                                                          */

/* THE LISTING VARIANT — tag, author, and the 404's recent cards.
   These carry a card GRID, not a 720px reading measure, so capping their
   column at --wrap-narrow the way a post is capped would be actively wrong: it
   would squeeze the four-across grid into 720px on every screen from 1000px
   up, which is long before the sidebar is even beside it. `--list` keeps the
   content column full-width while the layout is stacked, and hands it the
   whole remaining track once the two-column grid engages. */
.post-layout--list .post-main { width: 100%; }

@media (min-width: 1200px) {
    /* 1fr, not the capped --wrap-narrow track a post gets: a grid should use
       whatever the sidebar leaves it (1180 - 400 - 40 = 740px) rather than stop
       at 720 and strand the remaining 20. A post stops at 720 because a reading
       measure is the point; a card grid has no such reason. */
    .post-layout--list { grid-template-columns: minmax(0, 1fr) var(--side-w); }
    .post-layout--list .post-main { width: auto; }

    /* THREE ACROSS, NOT FOUR, AND ONLY HERE.
       .quote-grid pins itself to repeat(4, 1fr) from 1000px up. That is right
       for a full-width band and wrong inside a 740px column: four tracks there
       are ~185px each, narrower than the 220px minimum the fluid rule below
       1000px never goes under. Three tracks are ~246px, comfortably above it.
       Scoped to .post-main inside --list so the home page's grid, the related-
       posts grid and the section strips are all untouched. */
    .post-layout--list .post-main .quote-grid { grid-template-columns: repeat(3, 1fr); }
}
