/*
Theme Name: SP Wealth Blog
Theme URI: https://spblog.deepmindserver.com/
Author: Compassionate Capital
Description: Public commentary blog for Compassionate Capital, carrying the design system of the SP Wealth client portal. Minimal classic theme, no page builder, no framework.
Version: 1.0.0
Requires at least: 6.4
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sp-wealth-blog
*/

/* ==========================================================================
   1. Jokker, self hosted from assets/fonts/.

   CURRENTLY INSTALLED: the TRIAL builds, converted from the portal's .otf
   files to woff2 (1021K -> 305K). Trial builds are normally licensed for
   evaluation and mockups, not public production, so these must be swapped
   for licensed webfont files before the blog is indexed. The filenames are
   licence agnostic: drop licensed woff2 in under the same names and nothing
   else changes.

   Only the weights the theme actually uses are declared. Weight 300 is not
   used anywhere, so it is not shipped. The italic face exists for prose
   emphasis and is fetched only when an <em> is present on the page.
   ========================================================================== */

@font-face {
  font-family: 'Jokker';
  src: url('assets/fonts/jokker-regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Jokker';
  src: url('assets/fonts/jokker-italic.woff2') format('woff2');
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'Jokker';
  src: url('assets/fonts/jokker-medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Jokker';
  src: url('assets/fonts/jokker-semibold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Jokker';
  src: url('assets/fonts/jokker-bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ==========================================================================
   2. Design tokens, captured from the Compassionate Capital portal
   ========================================================================== */

:root {
  --bg-page: #edf0ff;
  --bg-topbar: #fff;
  --bg-card: #fff;
  --bg-card-2: #f3f5ff;
  --bg-card-3: #edf0ff;
  --bg-hover: rgba(59, 91, 255, .04);

  --txt-1: #06081e;
  --txt-2: #141c40;
  --txt-3: #283258;
  --txt-4: #3f4e74;
  --txt-5: #6374a0;

  --bdr: rgba(59, 91, 255, .08);
  --bdr-2: rgba(59, 91, 255, .14);
  --bdr-3: rgba(59, 91, 255, .22);

  /* Two blues, deliberately distinct. Do not merge. */
  --blue: #5577ff;          /* links and read affordances */
  --accent-rgb: 59, 91, 255; /* base for borders, hovers, shadows */
  --blue-deep: #2a3a90;

  --green: #059669;
  --gold: #d97706;
  --red: #dc2626;

  --font-sans: 'Jokker', 'Segoe UI', system-ui, -apple-system, sans-serif;

  --lh-tight: 1.15;
  --lh-body: 1.5;

  --nav-active-txt: #3b5bff;
  /* The nav sits on the tinted page ground rather than a white bar, so the
     portal's .04 hover and .08 active tints would all but vanish. One step up. */
  --nav-hover-bg: rgba(59, 91, 255, .06);
  --nav-active-bg: rgba(59, 91, 255, .12);

  --r-sm: 8px;
  --r-md: 12px;

  --wrap: 1312px;

  color-scheme: light;
}

/* Dark theme, currently DORMANT. The theme toggle was removed on 2026-09-17 and
   nothing sets data-theme="dark" any more, so the site is light only and these
   values never apply. They are kept because they are the portal's own dark
   ramp: restoring dark mode means restoring a switch, not re-deriving colours.
   The OS preference is deliberately not consulted. */
:root[data-theme="dark"] {
  --bg-page: #07091a;
  --bg-topbar: #0b0e1f;
  --bg-card: #111428;
  --bg-card-2: #161a32;
  --bg-card-3: #1c2040;
  --bg-hover: hsla(0, 0%, 100%, .06);

  --txt-1: #edf1ff;
  --txt-2: #c2cef0;
  --txt-3: #96a8d8;
  --txt-4: #7488be;
  --txt-5: #566094;

  --bdr: hsla(0, 0%, 100%, .06);
  --bdr-2: hsla(0, 0%, 100%, .10);
  --bdr-3: hsla(0, 0%, 100%, .15);

  --green: #10b981;
  --gold: #f59e0b;
  --red: #ef4444;

  --nav-active-txt: #edf1ff;
  --nav-hover-bg: hsla(0, 0%, 100%, .06);
  --nav-active-bg: rgba(59, 91, 255, .2);

  color-scheme: dark;
}

/* ==========================================================================
   3. Reset. :where() keeps specificity at zero so component rules always win.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

:where(body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol) {
  margin: 0;
  padding: 0;
}
:where(ul, ol) { list-style: none; }
:where(img, svg) { display: block; max-width: 100%; }
:where(a) { color: inherit; text-decoration: none; }

body {
  background: var(--bg-page);
  color: var(--txt-1);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ==========================================================================
   4. Shell
   ========================================================================== */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 20px;
}

/* Page bar. The section heading and the category nav share one row directly on
   the page ground; there is no separate top strip. The DOM order is heading,
   subline, nav, and grid areas lift the nav level with the heading. No brand
   lockup and no theme toggle: site identity lives in the page title and the
   footer, and the site is light only. */
.page-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "title nav"
    "sub   .";
  column-gap: 10px;
  align-items: center;
  padding-block: 28px 20px;
}
.page-bar__title  { grid-area: title; margin-right: 14px; }
.page-bar__sub    { grid-area: sub; }
.page-bar__nav    { grid-area: nav; }

/* On an article the section name is a link back to the index, not an h1. */
.page-bar__title a { color: inherit; transition: color .15s; }
.page-bar__title a:hover { color: var(--blue); }

.topnav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.topnav__link {
  font-size: 12px;
  font-weight: 500;
  color: var(--txt-4);
  padding: 6px 12px;
  border-radius: var(--r-sm);
  transition: background .15s, color .15s;
}
.topnav__link:hover { background: var(--nav-hover-bg); color: var(--txt-1); }
.topnav__link[aria-current] {
  background: var(--nav-active-bg);
  color: var(--nav-active-txt);
  font-weight: 600;
}

/* Top spacing comes from .page-bar now, so main starts flush beneath it. */
.site-main { padding-block: 0 48px; }

.page-head__title {
  font-size: 26px;
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -.02em;
  color: var(--txt-1);
}
.page-head__sub {
  font-size: 14px;
  color: var(--txt-4);
  margin-top: 6px;
}

/* Panel, the house card treatment */
.card {
  background: var(--bg-card);
  border: 1px solid var(--bdr);
  border-radius: var(--r-md);
  padding: 20px;
  box-shadow: 0 2px 12px rgba(var(--accent-rgb), .05);
}
.card-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}
.card-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--txt-1);
}
.card-count { font-size: 11.5px; color: var(--txt-5); white-space: nowrap; }

/* ==========================================================================
   5. Commentary grid and card. Geometry matches the portal component.
   ========================================================================== */

.commentary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.commentary-card {
  border: 1px solid var(--bdr);
  border-radius: var(--r-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  position: relative;
  transition: box-shadow .2s, border-color .2s;
}
.commentary-card:hover {
  box-shadow: 0 8px 24px rgba(var(--accent-rgb), .1);
  border-color: var(--bdr-2);
}
.commentary-card:focus-within {
  box-shadow: 0 8px 24px rgba(var(--accent-rgb), .1);
  border-color: var(--bdr-3);
}

.commentary-hero {
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.commentary-hero svg {
  width: 34px;
  height: 34px;
  stroke: rgba(255, 255, 255, .85);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- Featured image in the hero band -------------------------------------
   The photo sits under the category gradient rather than replacing it. The
   tint is the same linear-gradient the band already carries, handed over as
   --hero-grad by spw_hero_style() and multiplied over the image, so six
   unrelated photographs still read as one system and the white category pill
   keeps its contrast. Without the tint the pill lands on whatever the photo
   happens to be doing in that corner.
   -------------------------------------------------------------------------- */

.commentary-hero__img,
.article-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* `color` rather than `multiply`: it takes hue and saturation from the gradient
   but keeps the photograph's own luminance, so the category still reads at a
   glance without the darker images turning to mud. Multiply was tried first and
   crushed the low-key shots. */
.commentary-hero__tint {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--hero-grad);
  opacity: .62;
  mix-blend-mode: color;
  pointer-events: none;
}

/* A second, much softer pass from the top left only. It deepens the corner the
   pill sits in without flattening the whole photograph. */
.commentary-hero--img::after,
.article-hero--img::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(160deg, rgba(6, 8, 30, .52) 0%, rgba(6, 8, 30, .06) 62%);
  pointer-events: none;
}

/* The pill and any hero link must clear both wash layers. */
.commentary-hero .commentary-cat,
.article-hero .commentary-cat { z-index: 3; }

.article-hero--img { overflow: hidden; }

.commentary-cat {
  position: absolute;
  top: 12px;
  left: 12px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .92);
}

.commentary-body {
  padding: 16px;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.commentary-title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--txt-1);
  line-height: 1.35;
  margin-bottom: 8px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
/* One real anchor covers the card, so the title stays the accessible name. */
.commentary-title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.commentary-summary {
  font-size: 11.5px;
  color: var(--txt-3);
  line-height: 1.55;
  margin-bottom: 10px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  flex: 1;
}

.commentary-read {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--blue);
  margin-bottom: 14px;
}

.commentary-author {
  display: flex;
  align-items: center;
  gap: 8px;
  border-top: 1px solid var(--bdr);
  padding-top: 12px;
}
.commentary-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
}
.commentary-author-info { flex: 1; min-width: 0; }

/* Name stacks above role, as in the portal. These are spans, so the block
   display has to be declared explicitly. */
.commentary-author-name,
.commentary-author-title,
.article-meta__name,
.article-meta__title {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.commentary-author-name {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--txt-1);
  line-height: 1.3;
}
.commentary-author-title,
.commentary-date { font-size: 10px; color: var(--txt-4); }
.commentary-author-title { line-height: 1.3; }
.commentary-date { white-space: nowrap; }

/* ==========================================================================
   6. Single article
   ========================================================================== */

.article-hero {
  height: 220px;
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin-bottom: 20px;
}
.article-hero svg {
  width: 48px;
  height: 48px;
  stroke: rgba(255, 255, 255, .85);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.article-hero .commentary-cat { top: 16px; left: 16px; }

/* An article is a document, not a dashboard panel: narrow the whole card so
   the reading measure comes from the container instead of leaving the right
   half of a full width panel empty. */
body.single .card,
body.page .card {
  max-width: 780px;
  margin-inline: auto;
}
/* The page bar narrows with the article so the heading and nav share its left
   and right edges. The bar is itself a .wrap with 20px side padding, hence 780
   plus 40: its content box then lines up with the card's outer edges, exactly as
   it does with the full width panel on the index. */
body.single .page-bar,
body.page .page-bar {
  max-width: calc(780px + 40px);
}
body.single .article-body,
body.single .article-foot,
body.single .disclaimer-note,
body.page .article-body {
  max-width: none;
}

.article-title {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.02em;
  color: var(--txt-1);
  margin-bottom: 14px;
}

.article-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 18px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--bdr);
}
.article-meta .commentary-avatar { width: 34px; height: 34px; font-size: 11px; }
.article-meta__name { font-size: 13px; font-weight: 600; color: var(--txt-1); }
.article-meta__title { font-size: 11px; color: var(--txt-4); }
.article-meta__date { margin-left: auto; font-size: 11px; color: var(--txt-4); white-space: nowrap; }

.article-body {
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.65;
  color: var(--txt-3);
}
.article-body > * + * { margin-top: 1.05em; }
.article-body h2 {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--txt-1);
  margin-top: 1.8em;
  letter-spacing: -.01em;
}
.article-body h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--txt-2);
  margin-top: 1.5em;
}
.article-body strong { color: var(--txt-1); font-weight: 600; }
.article-body a { color: var(--blue); font-weight: 500; text-decoration: underline; text-underline-offset: 2px; }
.article-body ul { list-style: disc; padding-left: 1.2em; }
.article-body ol { list-style: decimal; padding-left: 1.2em; }
.article-body li + li { margin-top: .4em; }
.article-body blockquote {
  border: 0;
  border-left: 2px solid var(--bdr-3);
  margin: 0;
  padding: 2px 0 2px 16px;
  color: var(--txt-4);
}

.article-foot {
  max-width: 68ch;
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--bdr);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.link-back { font-size: 12px; font-weight: 600; color: var(--blue); }

/* ==========================================================================
   Related commentary
   Stays inside the article's 780px column so the page keeps one measure. The
   cards therefore run narrower than on the index, and are stepped down a
   little further on purpose: a shorter band, a smaller title and a two line
   summary make them read as secondary to the piece above them.
   ========================================================================== */

.related { margin-top: 22px; }
.related .commentary-grid { gap: 14px; }
.related .commentary-hero { height: 116px; }
.related .commentary-title { font-size: 13.5px; }
.related .commentary-summary { -webkit-line-clamp: 2; }
.related .commentary-read { margin-bottom: 12px; }

/* A 237px card cannot carry avatar, name, job title and date on one line. The
   role went first (it truncated mid word: "Sharia Advisory Boa..."), then the
   date, which is the least load-bearing element on what is a navigational card
   and is still shown on the article itself. Dropping both rather than shrinking
   type is deliberate: author names are arbitrary-length data, so tuning pixels
   to fit the current longest byline would break on the next author added. Names
   that are genuinely too long still ellipsize, which is correct rather than a
   defect. */
.related .commentary-author-title,
.related .commentary-date { display: none; }
.related .commentary-author { gap: 7px; }
.related .commentary-avatar { width: 26px; height: 26px; font-size: 9.5px; }

/* Below the grid breakpoint these cards are full width again, so the role fits
   and comes back. */
@media (max-width: 900px) {
  .related .commentary-author-title { display: block; }
  .related .commentary-date { display: block; }
  .related .commentary-author { gap: 8px; }
  .related .commentary-avatar { width: 30px; height: 30px; font-size: 10px; }
  .related .commentary-hero { height: 140px; }
  .related .commentary-title { font-size: 16px; }
  .related .commentary-summary { -webkit-line-clamp: 3; }
}

.disclaimer-note {
  max-width: 68ch;
  margin-top: 20px;
  padding: 14px 16px;
  background: var(--bg-card-2);
  border: 1px solid var(--bdr);
  border-radius: var(--r-sm);
  font-size: 11px;
  line-height: 1.6;
  color: var(--txt-4);
}

/* ==========================================================================
   7. Pagination, empty state, footer
   ========================================================================== */

.pagination { display: flex; gap: 6px; margin-top: 20px; flex-wrap: wrap; }
.pagination .page-numbers {
  font-size: 12px;
  font-weight: 500;
  padding: 7px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--bdr);
  color: var(--txt-3);
  background: var(--bg-card);
  transition: border-color .15s, color .15s;
}
.pagination .page-numbers:hover { border-color: var(--bdr-2); color: var(--txt-1); }
.pagination .page-numbers.current {
  background: #3b5bff;
  border-color: #3b5bff;
  color: #fff;
}

.empty-state { padding: 32px 4px; }
.empty-state__title { font-size: 15px; font-weight: 600; color: var(--txt-1); margin-bottom: 6px; }
.empty-state__body { font-size: 12.5px; color: var(--txt-4); max-width: 52ch; }

.site-footer {
  border-top: 1px solid var(--bdr);
  padding-block: 20px 32px;
  margin-top: 8px;
}
.site-footer__lead {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--txt-2);
  margin-bottom: 6px;
}
.site-footer__body { font-size: 11px; line-height: 1.6; color: var(--txt-4); }
.site-footer__meta { font-size: 11px; color: var(--txt-4); margin-top: 8px; }
.site-footer__meta strong { color: var(--txt-2); font-weight: 600; }

.screen-reader-text {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.skip-link:focus {
  position: fixed;
  top: 8px; left: 8px;
  width: auto; height: auto;
  clip: auto;
  z-index: 100;
  background: var(--bg-card);
  color: var(--txt-1);
  padding: 10px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--bdr-3);
  font-size: 12px;
  font-weight: 600;
}

/* ==========================================================================
   8. Responsive. Single breakpoint, matching the portal. Type steps up on
   small screens where a public reader is not leaning into a data view.
   ========================================================================== */

@media (max-width: 900px) {
  .commentary-grid { grid-template-columns: 1fr; }

  .commentary-title { font-size: 16px; }
  .commentary-summary { font-size: 13px; }
  .commentary-read { font-size: 12.5px; }
  .commentary-author-name { font-size: 12.5px; }
  .commentary-author-title, .commentary-date { font-size: 11px; }
  .commentary-cat { font-size: 10px; }

  .page-head__title { font-size: 22px; }
  .article-title { font-size: 22px; max-width: none; }
  .article-hero { height: 170px; }

  /* Heading and nav no longer fit on one row: long archive titles would wrap
     against the links. The heading and subline stack, and the nav takes the
     full width beneath, wrapping to a second line on a phone. Breaking at 900px
     rather than 600px keeps the title from being squeezed onto two lines in
     between. */
  .page-bar {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "title"
      "sub"
      "nav";
    padding-block: 20px 16px;
  }
  .page-bar__title { margin-right: 0; }
  .page-bar__nav { margin-top: 12px; }
}

@media (max-width: 600px) {
  .card { padding: 14px; }
  .article-body { font-size: 14.5px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
