/*
blog-patterns.css -- Wave 41 Track B: Design 2.0 for the public blog.

Additive sibling file, same discipline marketing-patterns.css itself
documents (see that file's header comment): every rule built from
tokens.css custom properties, never a hardcoded color/space value.

Scope (updated Wave 42 Track D): loaded by
templates/website/blog_base.html, and therefore by the whole blog family
(the index, the CMS article template, and the 1,108 individually-templated
legacy articles that were re-based onto that shell this wave). It is still
never loaded by templates/website/index.html, so it still cannot reach the
~8,800 non-blog SEO pages. Page-level loading remains the real safety
boundary, not selector naming.

Reuses existing components.css/marketing-patterns.css primitives
wherever they already fit the shape needed (.rx-marketing__media-card
for post-preview cards, .rx-badge--brand for tag chips, .rx-avatar for
the byline, .rx-stagger-item/.rx-marketing__reveal for entrance motion,
the IntersectionObserver reveal script already proven in
templates/design_system/layouts/marketing_base.html) rather than
inventing parallel ones. New rules below are only for what's genuinely
blog-specific: long-form article typography (nothing in the design
system covers this yet -- confirmed by search before writing this file)
and a couple of blog-only layout wrappers.

BACKDROP CHANGE -- Wave 42 Track D. When this file was written, its host
pages sat on the legacy family's black body (static/css/style.css's
body{background:#000}), so Wave 41 Track F correctly pinned the article
body, byline and section headings to the FIXED on-dark tokens
(--rx-color-text-on-dark / --rx-color-text-on-dark-muted) to get above
4.5:1 there. Those pages now extend marketing_base.html, whose body
background is the theme-aware --rx-color-surface (white in light mode).
Leaving them on the on-dark tokens would have inverted Track F's own bug:
near-white text on a white page. Every one of those declarations is now
--rx-color-text / --rx-color-text-muted, which follow the theme in both
directions. Two exceptions are deliberate and unchanged: .rx-article-cta
(its own --rx-color-ink panel) and .rx-article-body blockquote/details
(their own --rx-color-surface-alt cards) already carried explicit,
context-correct colours.

Article body links moved the same way: --rx-color-brand (the bright gold,
chosen for legibility on black) back to --rx-color-brand-strong, which
tokens.css documents as the text-on-light gold (6.05:1 on white vs. the
bright gold's 2.24:1).
*/

/* ================= Index (templates/website/blog.html) ================= */

/* ---------- Hero ----------
   Restyles the existing .site-heading/.site-title-tagline/.site-title/
   .heading-divider markup already in blog.html (untouched HTML, see
   that template) rather than introducing new hero markup -- keeps the
   diff on that huge file to the extra_css block and a couple of class
   additions on already-present elements. */
.rx-blog-hero { padding: var(--rx-space-2) 0 var(--rx-space-4); }
.rx-blog-hero .site-title-tagline {
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-2);
  /* Wave 42 Track G: was --rx-color-brand (#C9A227) -- the bright gold
     chosen for legibility on style.css's black body, back when this index
     rendered there. Track D re-based the family onto marketing_base's
     themed surface, and this hero declaration was not swept with the rest
     of that colour pass (its report §5 lists three that were). Measured
     live at 390/768/1440px: 2.42:1 on the light surface, under AA.
     --rx-color-accent-strong is the theme-aware token Track D and Track E
     both standardised on for exactly this swap: #7A5F09 on light,
     #C9A227 on dark -- so the dark-mode appearance is unchanged. */
  color: var(--rx-color-accent-strong);
}
.rx-blog-hero .site-title {
  font-family: var(--rx-font-display);
  font-weight: var(--rx-weight-bold);
}
@media (max-width: 640px) {
  .rx-blog-hero .site-title { font-size: var(--rx-text-3xl); }
}

/* ---------- "Latest From RideXpress" (CMS-backed posts) ----------
   New, additive section -- see website.views.blog()'s own comment on
   why the `blogs` queryset (fetched by that view since before this
   wave, but never looped over by this template) now actually renders.
   Uses .rx-marketing__media-card/.rx-marketing__service-grid from
   marketing-patterns.css as-is (loaded by this same page's extra_css
   block) rather than a parallel card component. */
.rx-blog-latest {
  max-width: 1200px;
  margin: 0 auto var(--rx-space-12);
  padding: 0 var(--rx-space-6);
}
.rx-blog-latest__heading {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-2xl);
  font-weight: var(--rx-weight-bold);
  color: var(--rx-color-text);
  margin: 0 0 var(--rx-space-6);
}

/* ---------- Legacy card grid re-skin ----------
   Deliberately does NOT rename .blog-item/.blog-item-img/.blog-item-info/
   .blog-title/.theme-btn -- the pagination script at the bottom of
   blog.html selects cards by that exact class name
   (document.querySelectorAll(".blog-item")), and every one of the
   ~2,000 individual card blocks in that template already uses these
   exact names. Renaming any of them would either silently break
   pagination (wrong element count/order) or require touching every
   card block -- both against this task's "shared templates only, never
   per-article rewrites" rule. Re-skinned entirely via descendant
   selectors scoped under #blog-container instead, so nothing here can
   reach the .theme-btn submit button in this same page's shared header
   (templates/website/index.html, line ~509), which this stylesheet
   happens to load on top of. */
#blog-container.row { margin-top: 0; }
#blog-container .blog-item {
  /* Wave 41 Track B bug found + fixed during visual verification: a
     `row-gap` on this flex row (removed) combined with the pagination
     script's `.blog-item` (not its `.col-md-6.col-lg-4` wrapper)
     display:none toggling inflated #blog-container to ~40,000px tall --
     each of the ~1,067 off-page, zero-height column wrappers still
     resolved as its own zero-height flex line, and the row-gap value
     was added between every one of those phantom lines. Reverted to
     this file's original spacing mechanism (.blog-item's own
     margin-bottom, from static/css/style.css, left un-overridden below)
     which doesn't have that failure mode: margin on a display:none
     element simply doesn't apply, so hidden cards contribute nothing. */
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-lg);
  padding: 0;
  box-shadow: var(--rx-shadow-sm);
  transition: border-color var(--rx-motion-fast) var(--rx-ease-standard),
              box-shadow var(--rx-motion-fast) var(--rx-ease-standard),
              transform var(--rx-motion-fast) var(--rx-ease-standard);
}
#blog-container .blog-item:hover {
  border-color: var(--rx-color-border-strong);
  box-shadow: var(--rx-shadow-md);
  transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
  #blog-container .blog-item { transition: none; }
  #blog-container .blog-item:hover { transform: none; }
}
#blog-container .blog-item-img {
  border-radius: 0;
  height: auto;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--rx-color-surface-alt);
}
#blog-container .blog-item-img img { width: 100%; height: 100%; object-fit: cover; }
#blog-container .blog-item:hover .blog-item-img img { transform: scale(1.06); }
#blog-container .blog-item-info {
  padding: var(--rx-space-5);
  flex: 1;
  display: flex;
  flex-direction: column;
}
#blog-container .blog-title {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-lg);
  line-height: var(--rx-leading-tight);
  color: var(--rx-color-text);
  margin: 0 0 var(--rx-space-4);
  flex: 1;
}
#blog-container .blog-title a { color: inherit; }
#blog-container .blog-item:hover .blog-title a { color: var(--rx-color-brand-strong); }
#blog-container .blog-item-info .theme-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-2);
  background: var(--rx-color-brand);
  color: var(--rx-color-ink);
  font-family: var(--rx-font-body);
  font-weight: var(--rx-weight-semibold);
  font-size: var(--rx-text-sm);
  padding: 9px 18px;
  border-radius: var(--rx-radius-md);
  margin-top: 0;
}
#blog-container .blog-item-info .theme-btn:hover { background: var(--rx-color-brand-strong); color: var(--rx-color-white); }

/* ---------- Pagination controls ----------
   blog.html's own inline <style> block (bottom of that file) already
   scopes .pagination/.page-number/.dots to this page and is left in
   place unmodified (only the hardcoded #dab024e7 color values in it
   were swapped for tokens -- see that block directly) -- nothing new
   needed here. */

/* ================= Article (templates/website/blog/blog_detail.html) ================= */

/* ---------- Featured image ---------- */
.rx-article-hero-img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--rx-radius-lg);
  box-shadow: var(--rx-shadow-md);
  background: var(--rx-color-surface-alt);
}

/* ---------- Byline / meta row ---------- */
.rx-article-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--rx-space-3);
  margin: var(--rx-space-5) 0 var(--rx-space-6);
  padding-bottom: var(--rx-space-5);
  border-bottom: 1px solid var(--rx-color-border);
}
/* Wave 42 Track D: superseded. The Wave 41 Track F reasoning preserved
   below was correct while these pages rendered on style.css's black
   body; after the marketing_base re-base they render on a themed
   surface, so the on-dark tokens it introduced have been swapped back
   to the theme-aware ones. See this file's header comment. */
/* Wave 41 Track F fix: same root cause as .rx-article-body above -- this
   row sits directly on the page's black background (.rx-article-meta
   itself sets no background), so the theme-aware --rx-color-text/
   --rx-color-text-muted (dark-navy/mid-grey, meant for light surfaces)
   measured 1.33:1 / 4.0:1 here, both under the 4.5:1 AA floor for normal
   text. Swapped to their already-existing fixed on-dark counterparts
   (--rx-color-text-on-dark / --rx-color-text-on-dark-muted), the same
   tokens this file already uses correctly elsewhere (e.g.
   .rx-blog-latest__heading just above in this file). */
.rx-article-meta__author {
  display: flex;
  align-items: center;
  gap: var(--rx-space-2);
  font-weight: var(--rx-weight-semibold);
  color: var(--rx-color-text);
}
.rx-article-meta__sep { color: var(--rx-color-text-muted); }
.rx-article-meta__details {
  color: var(--rx-color-text-muted);
  font-size: var(--rx-text-sm);
  display: flex;
  flex-wrap: wrap;
  gap: var(--rx-space-1) var(--rx-space-2);
}

/* ---------- Long-form article typography ----------
   No prose/article typography pattern existed anywhere in the design
   system before this (checked patterns.css/components.css/
   marketing-patterns.css). Tuned for reading at article length, not
   short marketing copy: a real measure (65-75ch), generous leading, and
   a clear type-scale step between h2/h3/h4 so a long post stays
   scannable. Applies to the sanitized rich-text output of
   custom_filters.render_blog_html (taxipro/html_sanitizer.py's
   _ALLOWED_TAGS: p/br/strong/em/b/i/h2/h3/h4/ul/ol/li/a/details/
   summary/blockquote/cite -- every selector below maps to one of those,
   nothing extra, nothing missing) plus the FAQ/CTA/Quote/YouTube block
   styling that already existed inline in blog_detail.html (folded in
   here so it lives with the rest of this page's typography instead of
   a second, separate <style> block; values unchanged from the
   original, only the color source changed from a hardcoded
   `var(--theme-color, #dab024e7)` to this design system's own
   --rx-color-brand token). */
/* Wave 42 Track D: superseded. The Wave 41 Track F reasoning preserved
   below was correct while these pages rendered on style.css's black
   body; after the marketing_base re-base they render on a themed
   surface, so the on-dark tokens it introduced have been swapped back
   to the theme-aware ones. See this file's header comment. */
/* Wave 41 Track F fix: this whole block used var(--rx-color-text) --
   tokens.css's THEME-AWARE token, dark-navy (#132435) unless a page sets
   data-theme="dark" or the OS prefers dark. This page (blog_detail.html,
   via templates/website/index.html) never sets data-theme -- only
   marketing_base.html does -- and static/css/style.css fixes body{
   background:#000} unconditionally, regardless of theme. Confirmed via
   live DOM background-chain inspection: every ancestor from
   .rx-article-body up to <body> has a transparent background, so this
   text sits directly on black. Real measured contrast in a default
   (non-dark-preferring) browser: 1.33:1 -- WCAG AA needs 4.5:1. In effect
   the entire article body was reading as near-invisible dark-navy-on-
   black for any visitor whose OS doesn't prefer dark mode, which is the
   common case. This file already has the correct fix pattern one
   selector away (.rx-blog-latest__heading / .rx-related-posts__heading,
   both correctly use --rx-color-text-on-dark, a token fixed at #F5FAFF
   regardless of theme -- see tokens.css) -- applying that same, already-
   proven token here instead. blockquote/details below get their color
   explicitly re-pinned to --rx-color-text: those two sub-elements carry
   their own light --rx-color-surface-alt background (unlike plain
   paragraphs/headings), so they still need dark-on-light, not on-dark. */
.rx-article-body {
  max-width: 72ch;
  color: var(--rx-color-text);
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-lg);
  line-height: var(--rx-leading-loose);
}
.rx-article-body > *:first-child { margin-top: 0; }
.rx-article-body p { margin: 0 0 var(--rx-space-5); }
.rx-article-body h2 {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-2xl);
  line-height: var(--rx-leading-tight);
  font-weight: var(--rx-weight-bold);
  color: var(--rx-color-text);
  margin: var(--rx-space-10) 0 var(--rx-space-4);
}
.rx-article-body h3 {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-xl);
  line-height: var(--rx-leading-tight);
  font-weight: var(--rx-weight-semibold);
  color: var(--rx-color-text);
  margin: var(--rx-space-8) 0 var(--rx-space-3);
}
.rx-article-body h4 {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-lg);
  font-weight: var(--rx-weight-semibold);
  color: var(--rx-color-text);
  margin: var(--rx-space-6) 0 var(--rx-space-2);
}
.rx-article-body ul, .rx-article-body ol {
  margin: 0 0 var(--rx-space-5);
  padding-left: 1.4em;
}
.rx-article-body li { margin-bottom: var(--rx-space-2); }
/* Wave 42 Track D: superseded. The Wave 41 Track F reasoning preserved
   below was correct while these pages rendered on style.css's black
   body; after the marketing_base re-base they render on a themed
   surface, so the on-dark tokens it introduced have been swapped back
   to the theme-aware ones. See this file's header comment. */
/* Wave 41 Track F fix: same root cause as the block comment above --
   --rx-color-brand-strong (#7A5F09) is tokens.css's own documented
   "text-on-light use" gold (measures 3.47:1 on this page's actual black
   background, under the 4.5:1 AA floor; correctly measures 6.05:1 on
   white/light). Swapped the base link color to --rx-color-brand
   (#C9A227, the standard brighter gold -- 8.68:1 on black) and its hover
   to a fixed on-dark-safe value. blockquote/details below explicitly
   restore --rx-color-brand-strong for links nested in *their* own light
   sub-card, where --rx-color-brand itself would fail (2.24:1) -- same
   light/dark-context split as the block comment above. */
/* Wave 42 Track D: --rx-color-accent-strong, not --rx-color-brand-strong.
   The latter is a FIXED #7A5F09 and measured 2.70:1 on the dark theme's
   surface once these pages started following the theme -- the mirror image
   of the bug Track F fixed for the black legacy page. --rx-color-accent-strong
   resolves to #7A5F09 in light and to the lighter focus-ring gold in dark,
   the same theme-aware swap Track F itself used to fix /terms' TOC links. */
.rx-article-body a { color: var(--rx-color-accent-strong); text-decoration: underline; text-underline-offset: 2px; }
.rx-article-body a:hover { color: var(--rx-color-text); }
.rx-article-body blockquote a, .rx-article-body details a { color: var(--rx-color-brand-strong); }
.rx-article-body blockquote a:hover, .rx-article-body details a:hover { color: var(--rx-color-accent); }
.rx-article-body strong, .rx-article-body b { font-weight: var(--rx-weight-bold); }
.rx-article-body blockquote {
  margin: var(--rx-space-6) 0;
  padding: var(--rx-space-4) var(--rx-space-6);
  border-left: 4px solid var(--rx-color-brand);
  background: var(--rx-color-surface-alt);
  border-radius: 0 var(--rx-radius-md) var(--rx-radius-md) 0;
  font-style: italic;
  font-size: var(--rx-text-xl);
  line-height: var(--rx-leading-normal);
  color: var(--rx-color-text);
}
.rx-article-body blockquote cite {
  display: block;
  margin-top: var(--rx-space-3);
  font-style: normal;
  font-weight: var(--rx-weight-semibold);
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text-muted);
}
.rx-article-body details {
  margin: 0 0 var(--rx-space-3);
  padding: var(--rx-space-4) var(--rx-space-5);
  background: var(--rx-color-surface-alt);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-md);
  color: var(--rx-color-text);
}
.rx-article-body summary {
  cursor: pointer;
  font-weight: var(--rx-weight-semibold);
  font-family: var(--rx-font-display);
}
.rx-article-body details[open] summary { margin-bottom: var(--rx-space-3); color: var(--rx-color-brand-strong); }
.rx-article-body details p:last-child { margin-bottom: 0; }
.rx-article-body .rx-cta-btn {
  display: inline-block;
  padding: 12px 28px;
  margin: var(--rx-space-3) 0;
  background: var(--rx-color-brand);
  color: var(--rx-color-ink);
  font-weight: var(--rx-weight-bold);
  border-radius: var(--rx-radius-md);
  text-decoration: none;
}
.rx-article-body .rx-cta-btn:hover { background: var(--rx-color-brand-strong); color: var(--rx-color-white); }
/* Wave 41 Track E: press feedback for the one clickable CTA embedded in
   article body content -- had :hover only, same "confirm the tap" gap
   as every other legacy-family CTA (see legacy-design2-bridge.css's own
   note on why :hover alone under-serves mobile readers). */
.rx-article-body .rx-cta-btn:active { background: var(--rx-color-brand-strong); }
@media (prefers-reduced-motion: no-preference) {
  .rx-article-body .rx-cta-btn { transition: background-color var(--rx-motion-fast) var(--rx-ease-standard), transform var(--rx-motion-instant) var(--rx-ease-standard); }
  .rx-article-body .rx-cta-btn:active { transform: scale(0.97); }
}
.rx-article-body .rx-yt-embed-wrap { border-radius: var(--rx-radius-lg); }
@media (max-width: 640px) {
  .rx-article-body { font-size: var(--rx-text-base); }
  .rx-article-body h2 { font-size: var(--rx-text-xl); }
  .rx-article-body blockquote { font-size: var(--rx-text-lg); }
}

/* ---------- Tag chips (real per-post Blogs.tags, not a fixed list) ---------- */
.rx-article-tags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rx-space-2); margin: var(--rx-space-6) 0; }
.rx-article-tags__label { font-weight: var(--rx-weight-semibold); color: var(--rx-color-text); margin-right: var(--rx-space-1); }

/* ---------- "Tags :" label above the 4 service chips ----------
/* Wave 42 Track D: superseded. The Wave 41 Track F reasoning preserved
   below was correct while these pages rendered on style.css's black
   body; after the marketing_base re-base they render on a themed
   surface, so the on-dark tokens it introduced have been swapped back
   to the theme-aware ones. See this file's header comment. */
   Wave 41 Track F fix: blog_detail.html's actual markup for this row is
   <div class="blog-details-tags"><h5>Tags : </h5>...</div> (a pre-
   existing legacy block, unrelated to the .rx-article-tags rule just
   above, which targets different markup this template doesn't use --
   confirmed via grep, not fixed/renamed here, out of this pass's
   narrow scope). static/css/style.css's own
   `.blog-details-tags h5{color:var(--color-dark)}` assumes a light card
   background -- true for the other ~1,090+ legacy blog article
   templates this same rule also reaches, which this file deliberately
   does NOT touch (see this file's own header comment on its page-level
   scoping). On THIS page specifically the label sits directly on the
   black body background with no card (confirmed via live DOM
   background-chain inspection), measuring ~1.4:1 -- far under the 4.5:1
   AA floor, effectively invisible. Overridden here, scoped to exactly
   this page via this file's existing load boundary (blog.html /
   blog_detail.html only), rather than editing the shared style.css rule
   other legacy pages may depend on. */
.blog-details-tags h5 { color: var(--rx-color-text); }

/* ---------- Booking CTA box ---------- */
.rx-article-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--rx-space-4);
  margin: var(--rx-space-8) 0;
  padding: var(--rx-space-6);
  background: var(--rx-color-ink);
  border-radius: var(--rx-radius-lg);
}
.rx-article-cta p {
  margin: 0;
  color: var(--rx-color-text-on-dark);
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-lg);
  font-weight: var(--rx-weight-semibold);
  max-width: 40ch;
}

/* ---------- Related posts ---------- */
.rx-related-posts { margin: var(--rx-space-10) 0; }
.rx-related-posts__heading {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-xl);
  font-weight: var(--rx-weight-bold);
  color: var(--rx-color-text);
  margin: 0 0 var(--rx-space-5);
}
.rx-related-posts__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--rx-space-5);
}

/* ---------- Sidebar widgets (search/social/tags) ---------- */
.rx-article-sidebar .widget {
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-lg);
  padding: var(--rx-space-5);
  margin-bottom: var(--rx-space-5);
}
/* Bug found + fixed during visual verification: static/css/style.css's
   `.widget .widget-title{...color:var(--color-dark)!important}` fixes
   this heading to a permanently dark navy, on the assumption every
   widget sits on `.widget`'s own light `--theme-bg-light` background
   (true everywhere else this class is used). This card's background
   above is token-driven and correctly goes dark in dark mode/prefers-
   color-scheme -- without this override the heading became dark-navy-
   on-dark-navy (near-unreadable) the moment that happened. `!important`
   is the only way to win against another `!important` rule; scoped
   tightly to .rx-article-sidebar so it can't affect any other widget
   elsewhere on the site. */
.rx-article-sidebar .widget-title {
  font-family: var(--rx-font-display);
  color: var(--rx-color-text) !important;
  margin: 0 0 var(--rx-space-4);
}
