/*
 * Optimistic Brain App — app-specific component styles.
 *
 * These are components the APP needs that are NOT part of the shared design
 * system (styles.css stays identical to the website theme). Loaded AFTER
 * styles.css by functions.php, so it may extend the shared classes.
 *
 * Exercise page system: the Meditation section and the Micro-Practice section
 * mirror each other — a white card with a coloured top bar (green / terracotta)
 * sitting above a colour-filled "About …" accordion. Same shape, two colours.
 */

/* ---------- Accordions (native Details block) — filled, colour-coded ---------- */
.prose .wp-block-details{
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-6);
  margin: var(--space-4) 0;
}
.prose .wp-block-details > summary{
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-h4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.prose .wp-block-details > summary::-webkit-details-marker{ display: none; }
.prose .wp-block-details > summary::after{
  content: "\25BE";          /* down chevron — rotates up when open */
  font-size: .9em;
  line-height: 1;
  flex: none;
  transition: transform .2s ease;
}
.prose .wp-block-details[open] > summary::after{ transform: rotate(180deg); }
.prose .wp-block-details > summary + *{ margin-top: var(--space-4); }

/* Green variant — "About This Meditation" (pairs with the green-topped player) */
.prose .wp-block-details.details-green{ background: var(--accent-primary); }
.prose .details-green > summary,
.prose .details-green > summary::after,
.prose .details-green p{ color: #fff; }

/* Terracotta variant — "About Micro Practices" (pairs with the terracotta-topped box) */
.prose .wp-block-details.details-terra{ background: var(--accent-terracotta); }
.prose .details-terra > summary,
.prose .details-terra > summary::after,
.prose .details-terra p{ color: #fff; }

/* Form-friendly variant — a terracotta HEADER BAR over a light, readable body.
   The solid .details-green/.details-terra tints tint the whole box, which makes
   form fields unreadable, so the "Add data" form uses this instead. */
.prose .wp-block-details.details-form{
  background: #fff;
  border: 1px solid var(--accent-terracotta);
  border-radius: var(--radius-md);
  padding: 0;
  overflow: hidden;
}
.prose .details-form > summary{
  background: var(--accent-terracotta);
  color: #fff;
  padding: var(--space-3) var(--space-6);
  margin: 0;
}
.prose .details-form > summary::after{ color: #fff; }
.prose .details-form > *:not(summary){ margin: var(--space-4) var(--space-6); }

/* ---------- Micro Practice — white card with a terracotta top bar ---------- */
.prose .micro-practice{
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-top: 4px solid var(--accent-terracotta);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  margin: 0 0 var(--space-4);
}
.prose .micro-practice > :first-child{ margin-top: 0; }
.prose .micro-practice h3{ color: var(--text-brand); }
/* When a gold band leads with a Micro Practice (the exercise pattern), the
   band's pt-14 puts more space above the card than the ~32px rhythm below it.
   Trim the band's top padding in that case so the card sits evenly. */
.band-gold:has(> .wrap.prose > .micro-practice:first-child){ padding-top: var(--space-8); }

/* ---------- Audio player — white card with a green top bar ---------- */
.prose .ex-audio{
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-top: 4px solid var(--accent-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  margin: var(--space-4) auto;
}
.prose .ex-audio iframe{
  display: block;
  border-radius: var(--radius-md);
}

/* ---------- Favorite / Bookmark button (Favorites plugin) ----------
   The plugin renders <a class="simplefavorite-button active preset"> with INLINE
   green + black-border styling. We override it (with !important) into the site's
   primary green pill so it reads like every other button. */
.prose a.simplefavorite-button,
.prose .simplefavorite-button{
  display: inline-flex !important;
  align-items: center;
  gap: .5em;
  background: var(--accent-primary) !important;
  border: 1px solid var(--accent-primary) !important;
  color: #fff !important;
  border-radius: 999px !important;
  padding: .6em 1.3em !important;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-caption);
  line-height: 1;
  text-decoration: none !important;
  box-shadow: none !important;
  cursor: pointer;
  transition: filter .15s ease;
}
.prose .simplefavorite-button:hover{ filter: brightness(1.08); }
.prose .simplefavorite-button.active{
  background: var(--accent-primary) !important;
  border-color: var(--accent-primary) !important;
  color: #fff !important;
}
.prose .simplefavorite-button i,
.prose .simplefavorite-button .sf-icon-bookmark{
  color: #fff !important;
  font-style: normal;
}

/* ---------- Lists ----------
   Exercise components (micro practice, affirmation statements, writing-process
   steps, and the coloured dropdowns) sit line-to-line — John's single-line
   preference. Everywhere else (article/blog prose) keeps the stylesheet's
   normal list spacing (gap:var(--space-2)), so articles read correctly. */
.prose .micro-practice ul, .prose .micro-practice ol,
.prose .affirm-box ul, .prose .affirm-box ol,
.prose .ex-process ul, .prose .ex-process ol,
.prose .wp-block-details ul, .prose .wp-block-details ol{ gap: 0; }
.prose .micro-practice li, .prose .affirm-box li,
.prose .ex-process li, .prose .wp-block-details li{ margin: 0; }

/* ---------- Article media (images / video / embeds) ----------
   The stylesheet forces prose images to width:100% and figures to margin:0,
   which balloons small images and jams media against the text. In article
   bodies: show images at natural size (capped to the column), centred, with
   breathing room; give embeds and self-hosted video the same spacing. */
.prose img{ width: auto; max-width: 100%; height: auto; }
.prose .wp-block-image{ margin-block: var(--space-6); text-align: center; }
.prose .wp-block-image img{ margin-inline: auto; }
.prose .wp-block-embed, .prose .wp-block-video{ margin-block: var(--space-6); }
.prose .wp-block-video video{ width: 100%; height: auto; display: block; border-radius: var(--radius-md); }

/* ---------- Exercise Process — Writing/Journaling timed steps ----------
   White card with a green top bar (mirrors .ex-audio). Holds the "Exercise
   Process" for writing exercises: an h3 title, then each timed phase as an h4
   sub-heading followed by its own numbered list that restarts at 1. Spacing
   uses the shared tokens so it matches the site's prose rhythm. */
.prose .ex-process{
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-top: 4px solid var(--accent-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-8);
  margin: 0;
}
.prose .ex-process > :first-child{ margin-top: 0; }
.prose .ex-process h3{ margin: 0 0 var(--space-4); }
.prose .ex-process h4{ color: var(--text-brand); margin: var(--space-6) 0 var(--space-2); }
.prose .ex-process ol{ margin: 0; }

/* ---------- Exercise Library ([ob_exercises]) ----------
   The app's browse screen: a row of filter chips over a card grid. Tapping a
   chip shows/hides cards in place (see the shortcode's inline script). Cards
   are the little exercise icons + a trimmed title. */
.ex-search-wrap{ max-width: 480px; margin: 0 auto var(--space-6); }
.ex-search{
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--text-primary);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  padding: var(--space-3) var(--space-6);
}
.ex-search:focus{ outline: none; border-color: var(--accent-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 20%, transparent); }
.ex-search::placeholder{ color: var(--text-muted); }
.ex-empty{ text-align: center; color: var(--text-muted); margin: var(--space-8) 0 0; }
.ex-filter{ justify-content: center; margin: 0 auto var(--space-6); max-width: 760px; }
.ex-filter .chip{ font-family: var(--font-body); }
/* Second filter row — the 4Steps axis — sits just above the Type row, each with
   a short leading label so the two axes read clearly. */
.ex-filter-step{ justify-content: center; margin: 0 auto var(--space-3); max-width: 760px; }
.ex-filter-step .chip{ font-family: var(--font-body); }
.ex-filter-time{ justify-content: center; margin: 0 auto var(--space-6); max-width: 760px; }
.ex-filter-time .chip{ font-family: var(--font-body); }
/* Roomier chips — more left/right padding (there's spare width in the filter),
   and chip text sized to match the exercise-card titles (--text-caption) so the
   filter and grid read as one calm scale instead of competing sizes. */
.ex-filter .chip,
.ex-filter-step .chip,
.ex-filter-time .chip{ padding-left: var(--space-6); padding-right: var(--space-6); font-size: var(--text-caption); }
/* In the Exercises library the Type row is followed by the Time row, so tighten
   its bottom gap (blogs, which reuse .ex-filter alone, are unaffected). */
.ex-library .ex-filter{ margin-bottom: var(--space-3); }

/* Color-coded filter rows: 4Steps = green, Type = rose, Time = navy. Each chip is a
   light tint of its row's color with darker same-hue text; the SELECTED chip is the
   solid color with white text (the "All" chip follows the same scheme). Type is
   scoped to .ex-library so the Blog library's .ex-filter chips stay neutral. */
.ex-filter-step .chip{
  background: color-mix(in srgb, var(--accent-primary) 12%, #fff);
  border-color: color-mix(in srgb, var(--accent-primary) 32%, #fff);
  color: color-mix(in srgb, var(--accent-primary) 85%, #000);
}
.ex-filter-step .chip:hover{ background: color-mix(in srgb, var(--accent-primary) 20%, #fff); }
.ex-filter-step .chip.chip--active{ background: var(--accent-primary); border-color: var(--accent-primary); color: #fff; }

.ex-library .ex-filter .chip{
  background: color-mix(in srgb, var(--accent-rose) 12%, #fff);
  border-color: color-mix(in srgb, var(--accent-rose) 32%, #fff);
  color: color-mix(in srgb, var(--accent-rose) 85%, #000);
}
.ex-library .ex-filter .chip:hover{ background: color-mix(in srgb, var(--accent-rose) 20%, #fff); }
.ex-library .ex-filter .chip.chip--active{ background: var(--accent-rose); border-color: var(--accent-rose); color: #fff; }

.ex-filter-time .chip{
  background: color-mix(in srgb, var(--accent-navy) 12%, #fff);
  border-color: color-mix(in srgb, var(--accent-navy) 32%, #fff);
  color: color-mix(in srgb, var(--accent-navy) 85%, #000);
}
.ex-filter-time .chip:hover{ background: color-mix(in srgb, var(--accent-navy) 20%, #fff); }
.ex-filter-time .chip.chip--active{ background: var(--accent-navy); border-color: var(--accent-navy); color: #fff; }
.ex-filter-label{
  align-self: center;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-caption);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-right: var(--space-1);
}
/* Colour-code each axis label to its row, matching that row's chips:
   4-Steps = green, Time = navy, Type = rose. */
.ex-filter-step .ex-filter-label{ color: var(--accent-primary); }
.ex-filter-time .ex-filter-label{ color: var(--accent-navy); }
.ex-library .ex-filter .ex-filter-label{ color: var(--accent-rose); }
.ex-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-4);
}
.ex-card{
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--text-primary);
  transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.ex-card:hover{ border-color: var(--accent-primary); box-shadow: var(--shadow-raised); }
.ex-card__icon{ display: block; }
.ex-card__icon img{ width: 64px; height: 64px; object-fit: contain; display: block; }
.ex-card__title{
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-caption);
  line-height: var(--leading-snug);
  color: var(--text-primary);
}
/* Mobile: 3 chips per row and 3 cards per row with a compact icon + title.
   MUST come after the base .ex-grid/.ex-card rules above so it overrides them
   (the default auto-fill min-150px collapses to one column at padded phone
   widths). Applies to BOTH the Exercises and Blogs libraries. */
@media (max-width: 600px){
  .ex-filter, .ex-filter-step, .ex-filter-time{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); max-width: none; }
  .ex-filter .chip, .ex-filter-step .chip, .ex-filter-time .chip{ width: 100%; text-align: center; padding: var(--space-2) var(--space-3); font-size: 13px; white-space: normal; line-height: 1.2; }
  .ex-filter-label{ grid-column: 1 / -1; text-align: center; margin: 0 0 var(--space-1); }
  .ex-grid{ grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
  .ex-card{ padding: var(--space-3) var(--space-1); gap: var(--space-2); }
  .ex-card__icon img{ width: 44px; height: 44px; }
  .ex-card__title{ font-size: 11px; line-height: 1.2; }
}

/* Exercises library layout — moved here from the page's inline <style> so the
   Exercises page stays clean, valid blocks: chips first, the search box directly
   above the grid, and no per-chip counts. */
.ex-library{ display: flex; flex-direction: column; }
.ex-library .ex-filter{ order: 1; margin-bottom: var(--space-4) !important; }
.ex-library .ex-search-wrap{ order: 2; margin-bottom: var(--space-6) !important; }
.ex-library .ex-grid{ order: 3; }
.ex-library .ex-empty{ order: 4; }
.ex-filter .chip--count{ display: none; }

/* ---------- Bookmarks list ([ob_bookmarks]) ----------
   Saved items grouped into "Practices & Exercises" and "Articles to Read".
   Compact rows: icon + full title on the left, a quiet "Remove" action on the
   right (the Favorites plugin's toggle button, relabelled via ::after). */
.ob-bm-group + .ob-bm-group{ margin-top: var(--space-10); }
.ob-bm-head{ font-family: var(--font-display); font-weight: 700; font-size: var(--text-h4); color: var(--text-brand); margin: 0 0 var(--space-2); }
.ob-bm-list{ display: flex; flex-direction: column; }
.ob-bm-card{
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--border-subtle);
}
.ob-bm-card:last-child{ border-bottom: 1px solid var(--border-subtle); }
.ob-bm-main{ display: flex; align-items: center; gap: var(--space-4); flex: 1; min-width: 0; text-decoration: none; color: var(--text-primary); }
.ob-bm-icon{ flex: 0 0 auto; }
.ob-bm-icon img{ width: 52px; height: 52px; object-fit: contain; display: block; }
.ob-bm-title{ font-family: var(--font-display); font-weight: 600; font-size: var(--text-body); line-height: 1.3; }
.ob-bm-main:hover .ob-bm-title{ color: var(--text-brand); }
.ob-bm-empty{ text-align: center; color: var(--text-muted); }
/* Remove action — the plugin's toggle button, made into a quiet text button.
   Its font is zeroed (the plugin may re-inject "Bookmarked") and "Remove" is
   painted with ::after so our label always wins. */
.ob-bm-list .simplefavorite-button{
  flex: 0 0 auto;
  display: inline-flex !important; align-items: center;
  background: none !important; border: 0 !important; box-shadow: none !important;
  padding: var(--space-2) !important; margin: 0 !important;
  font-size: 0 !important; line-height: 1; text-decoration: none !important; cursor: pointer;
}
.ob-bm-list .simplefavorite-button i{ display: none !important; }
.ob-bm-list .simplefavorite-button::after{
  content: "Remove"; font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-caption); letter-spacing: .02em; color: var(--accent-terracotta);
}
.ob-bm-list .simplefavorite-button:hover::after{ text-decoration: underline; }
@media (max-width: 600px){
  .ob-bm-icon img{ width: 44px; height: 44px; }
  .ob-bm-title{ font-size: var(--text-caption); }
}

/* ---------- Courses ([ob_courses]) ----------
   One green-topped card per course: icon + title + description, matching the
   exercise cards. Equal padding all round, tight icon-to-title gap, and the
   site's relaxed paragraph line-height on the description. */
.ob-courses-list{ display: grid; gap: var(--space-6); }
.ob-course-card{
  display: flex; align-items: flex-start; gap: var(--space-6);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-top: 4px solid var(--accent-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  text-decoration: none; color: var(--text-primary);
  transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.ob-course-card:hover{ border-color: var(--accent-primary); box-shadow: var(--shadow-raised); }
.ob-course-icon{ flex: 0 0 auto; }
.ob-course-icon img{ width: 72px; height: 72px; object-fit: contain; display: block; }
.ob-course-body{ min-width: 0; }
.ob-course-title{ display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--text-h4); color: var(--text-brand); margin-bottom: var(--space-2); }
.ob-course-desc{ display: block; color: var(--text-secondary); line-height: var(--leading-relaxed); }
@media (max-width: 600px){
  .ob-course-card{ flex-direction: column; align-items: center; text-align: center; gap: var(--space-3); }
  .ob-course-icon img{ width: 64px; height: 64px; }
}

/* ---------- News feed ([ob_news]) ----------
   Substantial preview cards — image + title + excerpt + source/date — each
   linking out to its source. Side-by-side on desktop, full-width stacked on
   mobile. */
.ob-news-grid{ display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
.ob-news-card{
  display: flex; flex-direction: column;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden; text-decoration: none; color: var(--text-primary);
  transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.ob-news-card:hover{ border-color: var(--accent-primary); box-shadow: var(--shadow-raised); }
.ob-news-card.is-hidden{ display: none; }
.ob-news-img{ display: block; aspect-ratio: 16 / 9; overflow: hidden; }
.ob-news-img img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.ob-news-body{ display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-6); }
.ob-news-title{ font-family: var(--font-display); font-weight: 700; font-size: var(--text-h4); line-height: var(--leading-snug); color: var(--text-primary); }
.ob-news-excerpt{ color: var(--text-secondary); font-size: var(--text-body); line-height: var(--leading-relaxed); }
.ob-news-meta{ color: var(--text-muted); font-size: var(--text-caption); }
.ob-news-more{ color: var(--accent-primary); font-weight: 600; font-size: var(--text-caption); margin-top: var(--space-1); }
.ob-news-morewrap{ text-align: center; margin-top: var(--space-8); }
@media (max-width: 781px){
  .ob-news-grid{ grid-template-columns: 1fr; gap: var(--space-4); }
}

/* ---------- Sticky header ----------
   Keep the top bar in place as the page scrolls. A sticky element can only
   travel inside its own parent's box. .site-header sits inside the block
   theme's <header class="wp-block-template-part"> wrapper, which is only as
   tall as the bar itself, so sticking it there leaves no room to travel and it
   scrolls away. The WRAPPER has to be the sticky element: its parent is
   .wp-site-blocks, which spans the whole page, so it holds through the full
   scroll. Offset for the WP admin bar so it does not hide behind it. */
header.wp-block-template-part{
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--surface-page);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
}
body.admin-bar header.wp-block-template-part{ top: 32px; }
@media (max-width: 782px){
  body.admin-bar header.wp-block-template-part{ top: 46px; }
}
.site-header{ background: var(--surface-page); }

/* ---------- Flush bands: no dead space between sections ----------
   WordPress gives every child of a flow container margin-block-start:24px.
   Between .wp-site-blocks children that is the white gap under the header and
   above the footer; between the coloured bands it is a stripe of page
   background cutting through the section colours. Both are removed so the
   bands stack edge to edge and the header sits tight to the content.
   NOTE the band selector is a DESCENDANT match, not "> *": the bands are not
   direct children of .site-main, so a child selector never reaches them. */
.wp-site-blocks > *{ margin-block-start: 0 !important; }
.site-main .band-green,
.site-main .band-white,
.site-main .band-gold,
.site-main > *{ margin-block-start: 0 !important; margin-top: 0 !important; }

/* ---------- Mobile bottom tab bar ----------
   Persistent primary nav on phones (Home / Exercises / Blogs / Saved) so a
   detail page is never a dead end. Hidden on desktop (header nav is used
   there). Printed on every front-end page by optimistic_brain_tabbar(). */
.ob-tabbar{ display: none; }
@media (max-width: 781px){
  .ob-tabbar{
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
    display: flex;
    background: var(--surface-card);
    border-top: 1px solid var(--border-subtle);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -2px 12px rgba(0,0,0,.06);
  }
  .ob-tab{
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 4px 6px; text-decoration: none;
    color: var(--text-muted);
    font-family: var(--font-body); font-size: 10px; font-weight: 600; letter-spacing: .02em;
  }
  .ob-tab svg{ width: 22px; height: 22px; display: block; }
  .ob-tab.is-active{ color: var(--accent-primary); }
  /* Keep page content clear of the fixed bar (incl. iPhone home-bar area). */
  body{ padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
}

/* ---------- Blog listing ([ob_blog]) ----------
   A category's articles as a compact list: thumbnail + title + excerpt, newest
   first. Used on the Blogs sub-pages. */
.ob-blog-list{ display: grid; gap: 0; }
.ob-blog-card{
  display: flex; align-items: flex-start; gap: var(--space-4);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-subtle);
  text-decoration: none; color: var(--text-primary);
}
.ob-blog-card:last-child{ border-bottom: 1px solid var(--border-subtle); }
.ob-blog-thumb{ flex: 0 0 auto; }
.ob-blog-thumb img{ width: 72px; height: 72px; object-fit: contain; display: block; }
.ob-blog-body{ min-width: 0; }
.ob-blog-title{ display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--text-body); line-height: 1.3; margin-bottom: var(--space-1); }
.ob-blog-card:hover .ob-blog-title{ color: var(--text-brand); }
.ob-blog-excerpt{ display: block; color: var(--text-secondary); font-size: var(--text-caption); line-height: var(--leading-relaxed); }
@media (max-width: 600px){
  .ob-blog-card{ gap: var(--space-3); }
  .ob-blog-thumb img{ width: 60px; height: 60px; }
}

/* ---------- Daily Tips ([ob_tips]) ----------
   Static tip-of-the-day feed: icon + title + text, no links. A rolling window
   of recent days, newest first. Cards side-by-side on desktop, full-width
   stacked on mobile. Reuses the News/exercise card tokens for one consistent
   card look across the app. */
.ob-tips-grid{ display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--space-6); }
.ob-tip-card{
  display: flex; flex-direction: column; gap: var(--space-3);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.ob-tip-card.is-today{ border-color: var(--accent-primary); }
.ob-tip-date{ color: var(--text-muted); font-size: var(--text-caption); text-transform: uppercase; letter-spacing: .04em; }
.ob-tip-head{ display: flex; align-items: center; gap: var(--space-3); }
.ob-tip-icon{ flex: 0 0 auto; width: 52px; height: 52px; display: inline-flex; }
.ob-tip-icon img{ width: 100%; height: 100%; object-fit: contain; display: block; }
.ob-tip-title{ font-family: var(--font-display); font-weight: 700; font-size: var(--text-h4); line-height: var(--leading-snug); color: var(--text-primary); }
.ob-tip-text{ color: var(--text-secondary); font-size: var(--text-body); line-height: var(--leading-relaxed); margin: 0; }
@media (max-width: 781px){
  .ob-tips-grid{ grid-template-columns: 1fr; gap: var(--space-4); }
}

/* ---------- Bottom-of-post nav (blog articles + exercises) ----------
   Appended to single posts by optimistic_brain_post_footer_nav(). Blogs show
   Previous / Next on one row with "All Blogs" centered below; exercises show
   "All Exercises" and "Try another" as centered text links. Spacing comes from
   the scale (no divider rule) so it sits cleanly between the bands above/below. */
.ob-postnav{ display: flex; flex-direction: column; gap: var(--space-6); }
.ob-postnav__foot{ display: flex; justify-content: center; align-items: center; gap: var(--space-8); }
.ob-postnav__row{ display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-6); }
.ob-postnav--ex{ display: flex; justify-content: center; align-items: center; gap: var(--space-8); }
.ob-postnav__prev, .ob-postnav__next{ display: flex; flex-direction: column; gap: 2px; text-decoration: none; max-width: 46%; }
.ob-postnav__next{ text-align: right; align-items: flex-end; }
.ob-postnav__prev.is-empty, .ob-postnav__next.is-empty{ max-width: none; }
.ob-postnav__dir{ font-size: var(--text-caption); color: var(--text-muted); font-weight: 600; }
.ob-postnav__ttl{ font-family: var(--font-display); font-weight: 700; font-size: var(--text-body); line-height: var(--leading-snug); color: var(--text-primary); }
.ob-postnav__prev:hover .ob-postnav__ttl, .ob-postnav__next:hover .ob-postnav__ttl{ color: var(--accent-primary); }
.ob-postnav__all{ color: var(--accent-primary); font-weight: 600; font-size: var(--text-caption); text-decoration: none; }
.ob-postnav--blog .ob-postnav__all{ align-self: center; }
.ob-postnav__all:hover{ text-decoration: underline; }
@media (max-width: 600px){
  .ob-postnav{ padding-inline: var(--space-4); }
  .ob-postnav__ttl{ font-size: var(--text-caption); }
  .ob-postnav--ex{ flex-direction: column; gap: var(--space-4); }
}

/* ---------- Home dashboard tiles (front-page.html) ----------
   The whole card is a single link, with an icon. Green top accent + green
   title to match the app's card look. Two-up on desktop, stacked on mobile. */
.ob-cards{ display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
.ob-card{
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-6);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-top: 3px solid var(--accent-primary);
  border-radius: var(--radius-lg);
  text-decoration: none; color: var(--text-primary);
  transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.ob-card:hover{ border-color: var(--accent-primary); box-shadow: var(--shadow-raised); }
.ob-card__icon{ flex: 0 0 auto; width: 56px; height: 56px; object-fit: contain; display: block; }
.ob-card__text{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ob-card__title{ font-family: var(--font-display); font-weight: 700; font-size: var(--text-h4); line-height: var(--leading-snug); color: var(--text-brand); }
.ob-card__desc{ color: var(--text-secondary); font-size: var(--text-body); line-height: var(--leading-snug); }
@media (max-width: 600px){
  .ob-cards{ grid-template-columns: 1fr; }
}

/* ---------- Consistent single-post (blog + exercise) text rhythm ----------
   Blogs and exercises share ONE spacing system so they read identically:
   - even paragraph spacing between every element (matches the exercise rhythm);
   - list items single-spaced — NO gap between bullets/numbers;
   - paragraph spacing appears only BEFORE a list starts and AFTER it ends.
   Scoped to detail views — blog/exercise posts plus course + lesson screens —
   so standalone pages are left untouched. */
body.single-post .prose > * + *,
body.single-mpcs-lesson .prose > * + *,
body.single-mpcs-course .prose > * + *{ margin-top: var(--space-8); }
body.single-post .prose ul,
body.single-post .prose ol,
body.single-mpcs-lesson .prose ul,
body.single-mpcs-lesson .prose ol,
body.single-mpcs-course .prose ul,
body.single-mpcs-course .prose ol{ gap: 0; margin-bottom: 0; }
body.single-post .prose li,
body.single-mpcs-lesson .prose li,
body.single-mpcs-course .prose li{ margin: 0; }
/* Normalize the audio and details boxes to the same 32px rhythm on the older
   "Meditations" posts (whose page-level styles pin them to 16px). Higher
   specificity + !important beats those inline rules, so no per-post edits are
   needed and every blog/exercise/meditation/affirmation/lesson reads identically. */
body.single-post .prose .ex-audio,
body.single-mpcs-lesson .prose .ex-audio,
body.single-mpcs-course .prose .ex-audio{ margin-top: var(--space-8) !important; margin-bottom: 0 !important; }
body.single-post .prose .wp-block-details,
body.single-mpcs-lesson .prose .wp-block-details,
body.single-mpcs-course .prose .wp-block-details{ margin-top: var(--space-8) !important; }

/* Courses & lessons show their content only — suppress the auto-generated hero
   banner (their content carries its own icon/title). Targets the first <section>
   under .site-main (the hero band); the content and footer band are untouched. */
body.single-mpcs-course .site-main > section:first-of-type,
body.single-mpcs-lesson .site-main > section:first-of-type{ display: none; }

/* Course landing pages: separate the curriculum from the closing band. The
   lesson listing is the last thing in .entry-content and the band follows it
   immediately, so without this the white card butts straight into the green.
   The general sibling combinator skips the hero section above, which is
   hidden by the rule before this one. !important because the block layout
   stylesheet zeroes this margin at a weight inline styles cannot beat. */
body.single-mpcs-course .site-main > .entry-content ~ section{
	margin-top: var(--space-10) !important;
}

/* Prev/Next lesson navigation → a compact pale-gold strip (sits between the
   content and the green closing band) with balanced top/bottom padding. */
#mpcs-lesson-navigation{
	background: var(--surface-tint-gold);
	/* Full-width band with its links on the same column as the lesson text. The
	   gutter is whichever is larger: the standard band inset, or half the space
	   left over after the content column. The percentage resolves against this
	   element's own containing block, which is the content wrapper, so it is
	   correct at every width. */
	padding: var(--space-6) max(var(--space-10), calc((100% - var(--content-width)) / 2));
	margin: var(--space-8) 0 0;
	max-width: none;
}

/* A band supplies its own top and bottom padding, so the first and last things
   inside it must not add margins of their own. Without this the first heading's
   top margin escapes the wrapper and lands on top of the band's padding, which
   is what put a 96px gap between an embedded exercise and the text below it
   where 64px was intended. */
body.single-mpcs-lesson .band-white > .wrap.prose > :first-child,
body.single-mpcs-lesson .band-gold > .wrap.prose > :first-child,
body.single-mpcs-lesson .band-green > .wrap.prose > :first-child,
body.single-mpcs-course .band-white > .wrap.prose > :first-child,
body.single-mpcs-course .band-gold > .wrap.prose > :first-child,
body.single-mpcs-course .band-green > .wrap.prose > :first-child{
	margin-top: 0 !important;
}
body.single-mpcs-lesson .band-white > .wrap.prose > :last-child,
body.single-mpcs-lesson .band-gold > .wrap.prose > :last-child,
body.single-mpcs-lesson .band-green > .wrap.prose > :last-child,
body.single-mpcs-course .band-white > .wrap.prose > :last-child,
body.single-mpcs-course .band-gold > .wrap.prose > :last-child,
body.single-mpcs-course .band-green > .wrap.prose > :last-child{
	margin-bottom: 0 !important;
}

/* The Prev/Next links now live inside the "You've finished Day N" box, moved
   there by the footer script in functions.php, so MemberPress's own strip is
   hidden. Everything above about #mpcs-lesson-navigation is kept in case the
   strip is ever brought back. */
body.ob-day-lesson #mpcs-lesson-navigation{ display: none !important; }

/* Second line inside the finished box: previous on the left, next on the right,
   sitting on the box's own padding. An absent side is an empty span, which keeps
   the remaining link pinned to its edge on Day 1 and Day 31. */
/* The box is gold on every lesson, since it now carries the navigation that the
   gold strip used to. Marked important because the snippet that draws the box
   sets its own background. */
body.single-mpcs-lesson #ob-day-done{ background: var(--surface-tint-gold) !important; }
#ob-day-done.has-nav{ padding-left: var(--space-6); padding-right: var(--space-6); }
.ob-day-nav{
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-4);
	margin-top: var(--space-3);
}
.ob-day-nav a{
	color: var(--accent-primary);
	font-weight: 600;
	font-size: var(--text-caption);
	text-decoration: none;
	white-space: nowrap;
}
.ob-day-nav a:hover{ text-decoration: underline; }

/* An embedded exercise brings its own "About This Practice" accordion with it.
   That accordion exists for the exercise's standalone page in the library. On a
   lesson page the lesson itself already explains the practice, so hide it. */
body.single-mpcs-lesson .wp-block-details.details-green{ display: none !important; }

/* Hiding the accordion leaves the spacing that was meant to sit below it, so the
   element that followed it opens with a gap it has not earned. Zero the top
   margin of whatever came next: the Guided Practice heading on rebuilt exercises,
   or the player itself on the older ones. */
body.single-mpcs-lesson .wp-block-details.details-green + .wp-block-heading,
body.single-mpcs-lesson .wp-block-details.details-green + .ex-audio,
body.single-mpcs-lesson .prose .wp-block-details.details-green + *{
	margin-top: 0 !important;
}

/* MemberPress breadcrumb repeats the course as a same-page "section" link
   ("Intro Course" and "Introduction Course" both point at the course). Hide the
   redundant middle (section) crumb so it reads "Course > Lesson". The
   :not(.mpcs-active) guard keeps it safe on any lesson that has no section crumb. */
body.single-mpcs-lesson .mpcs-breadcrumbs .mpcs-breadcrumb:nth-of-type(2):not(.mpcs-active){ display: none; }

/* Lesson bookmark — exactly ONE styled button. Hide the plugin's stray auto-added
   buttons; show only the exercise's own hero button (.ob-hero, on exercise-lessons)
   or our injected .ob-lesson-bm (on concept lessons, placed under the breadcrumb). */
body.single-mpcs-lesson .simplefavorite-button,
body.single-mpcs-course .simplefavorite-button{ display: none !important; }
body.single-mpcs-lesson .ob-hero .simplefavorite-button,
body.single-mpcs-lesson .ob-lesson-bm .simplefavorite-button,
body.single-mpcs-course .ob-lesson-bm .simplefavorite-button{ display: inline-flex !important; }
.ob-lesson-bm{ margin: var(--space-6) 0 var(--space-2); }
.ob-lesson-bm--center{ display: flex; justify-content: center; }

/* The lesson's own title, restored above an embedded exercise (the exercise's
   hero title is stripped so it isn't duplicated). */
.ob-lesson-title{ margin-top: var(--space-6); }

/* Spacing balance for an embedded exercise on a lesson page. The exercise's own
   bands assume a full hero sits above them; here a compact title+bookmark does
   instead, so: keep the title block tight, trim the first band's top padding so
   the player isn't stranded below the bookmark, and even out the closing band
   (its pb-16 read heavier than its pt-14). Scoped to lessons — the exercise's own
   page keeps its original spacing. */
body.single-mpcs-lesson .ob-lesson-title .ob-lesson-bm{ margin-top: var(--space-3) !important; }
/* Every band section gets the SAME 32px top & bottom — on exercise/blog pages,
   lessons and courses alike — so all sections read consistently (per John). */
body.single-post .band-green.ob-hero,
body.single-post .band-white,
body.single-post .band-gold,
body.single-mpcs-lesson .band-white,
body.single-mpcs-lesson .band-gold,
body.single-mpcs-course .band-white,
body.single-mpcs-course .band-gold{ padding-top: var(--space-8) !important; padding-bottom: var(--space-8) !important; }

/* Embedded exercises in lessons/courses: drop the SECTION background tints so a
   lesson reads on its own background and can be styled independently. Only the
   band backgrounds go — the inner boxes (micro-practice card, terracotta/green
   dropdowns) keep their colours. Standalone exercise pages (single-post) keep
   their section colours untouched. */
body.single-mpcs-lesson .site-main .band-gold,
body.single-mpcs-course .site-main .band-gold{
	background-color: transparent !important;
}

/* Hero banner look — shared by the lesson banner (optimistic_brain_lesson_hero)
   and the exercise-page hero. Kept in the theme so lesson banners render
   correctly even on concept lessons that don't embed an exercise (and so lack
   the exercise's inline shell CSS). Values mirror that shell. */
.ob-hero-inner{ max-width: 560px; margin: 0 auto; text-align: center; }
.ob-hero .ob-icon{ width: 106px; height: auto; display: block; margin: 0 auto 8px; }
.ob-hero .ob-title{ margin: 0 0 10px; }
.ob-hero .ob-lead{ margin: 0 0 20px; }
.ob-hero .eyebrow{ font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-secondary); font-weight: 700; margin: 0 0 8px; }
.ob-hero .eyebrow a{ color: inherit; text-decoration: none; }
.ob-hero .eyebrow a:hover{ color: var(--text-brand); text-decoration: underline; }
@media (min-width: 782px){
	.ob-hero-inner{ max-width: 880px; display: flex; align-items: center; gap: 40px; text-align: left; }
	.ob-hero .ob-icon{ flex: 0 0 168px; width: 168px; margin: 0; }
	.ob-hero-text{ flex: 1; }
}
.ob-hero .simplefavorite-button{
	display: inline-flex !important; align-items: center; justify-content: center; gap: 0;
	background: var(--accent-primary) !important; border: 1px solid var(--accent-primary) !important; color: var(--text-inverse) !important;
	border-radius: 999px !important; padding: .7em 1.6em !important;
	font-family: var(--font-body); font-weight: 600; font-size: 14px; line-height: 1; text-decoration: none !important; box-shadow: none !important;
}
.ob-hero .simplefavorite-button i,
.ob-hero .simplefavorite-button .sf-icon-bookmark{ color: var(--text-inverse) !important; font-style: normal; }
.ob-hero .simplefavorite-button.active{ background: var(--accent-terracotta) !important; border-color: var(--accent-terracotta) !important; }
.ob-hero .simplefavorite-button:hover{ background: var(--accent-primary-hover) !important; border-color: var(--accent-primary-hover) !important; }

/* Phones: side padding so text isn't jammed against the screen edge.
   (1) MemberPress lesson/course chrome — breadcrumb, title, body — isn't inside
   a padded band, so inset the whole content column; full-width bands break out
   past this (WP alignfull) and supply their own inset.
   (2) Trim the content bands' own side padding to a phone-friendly size across
   posts/pages/lessons/courses so banded and bare content read with a consistent
   inset and nothing over-pads on small screens. */
@media (max-width: 600px){
	.site-main .band-green,
	.site-main .band-white,
	.site-main .band-gold,
	.site-main .alignfull.has-background{
		padding-left: var(--space-4) !important;
		padding-right: var(--space-4) !important;
	}
	body.single-mpcs-lesson .site-main,
	body.single-mpcs-course .site-main{
		padding-left: var(--space-4);
		padding-right: var(--space-4);
	}
	/* (3) The full-width bands sit inside the content wrapper rather than being
	   direct children of .site-main, so WordPress's alignfull breakout never
	   reaches them and (2) above leaves every band inset by the phone gutter.
	   Pull the wrapper itself back out by that gutter instead, which takes the
	   bands and the Prev/Next strip with it, and drop the strip's own side
	   padding to the phone size so its links line up with the band text. */
	body.single-mpcs-lesson .entry-content > .alignfull,
	body.single-mpcs-course .entry-content > .alignfull,
	body.single-mpcs-lesson .entry-content > #mpcs-lesson-navigation,
	body.single-mpcs-course .entry-content > #mpcs-lesson-navigation,
	body.single-mpcs-lesson .site-main > section,
	body.single-mpcs-course .site-main > section{
		margin-left: calc(var(--space-4) * -1);
		margin-right: calc(var(--space-4) * -1);
	}
	#mpcs-lesson-navigation{
		padding-left: var(--space-4);
		padding-right: var(--space-4);
	}
}

/* Recolor ONLY MemberPress's purple buttons (the "Start" buttons + the "In
   Progress" pill, which carry .is-purple) to the site green. The white "View"
   buttons on completed lessons don't have .is-purple, so they stay as they are. */
.is-purple{
	background-color: var(--accent-primary) !important;
	border-color: var(--accent-primary) !important;
	color: var(--text-inverse) !important;
}
.is-purple:hover{
	background-color: var(--accent-primary-hover) !important;
	border-color: var(--accent-primary-hover) !important;
	color: var(--text-inverse) !important;
}
.ob-lesson-bm .simplefavorite-button{
	align-items: center; justify-content: center; gap: 0;
	background: var(--accent-primary) !important; border: 1px solid var(--accent-primary) !important; color: var(--text-inverse) !important;
	border-radius: 999px !important; padding: .7em 1.6em !important;
	font-family: var(--font-body); font-weight: 600; font-size: 14px; line-height: 1; text-decoration: none !important; box-shadow: none !important;
}
.ob-lesson-bm .simplefavorite-button i{ color: var(--text-inverse) !important; font-style: normal; }
.ob-lesson-bm .simplefavorite-button.active{ background: var(--accent-terracotta) !important; border-color: var(--accent-terracotta) !important; }
.ob-lesson-bm .simplefavorite-button:hover{ background: var(--accent-primary-hover) !important; border-color: var(--accent-primary-hover) !important; }

/* Core button blocks inside content adopt the site button (.btn) look, so
   action buttons like "Go To Exercises…" match the rest of the site. */
.prose .wp-block-button__link.wp-element-button{
	background: var(--accent-primary);
	border: 1px solid var(--accent-primary);
	color: var(--text-inverse);
	border-radius: var(--radius-md);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: var(--text-body);
	padding: var(--space-3) var(--space-6);
}
.prose .wp-block-button__link.wp-element-button:hover{
	background: var(--accent-primary-hover);
	border-color: var(--accent-primary-hover);
	color: var(--text-inverse);
}

/* Footer copyright is rendered via the [ob_year] shortcode block, which
   wpautop-wraps its content in a <p>. Zero its margin so the flex footer
   row stays aligned exactly as the old <span> did. */
.site-footer > p{ margin: 0; }

/* ---------- Home dashboard cards, rebuilt as native editable blocks ----------
   Same look as the old raw-HTML cards. The block editor wraps things in extra
   groups/figures, so: neutralise flow-layout margins inside the grid/card,
   size the icon <img> (class now sits on the <figure>), and keep the WHOLE card
   clickable via a stretched link on the title (position:relative + ::after). */
.ob-cards > *,
.ob-card > *,
.ob-card__text > *{ margin-block: 0; }
.ob-card{ position: relative; }
.ob-card__icon{ margin: 0; }
.ob-card__icon img{ width: 56px; height: 56px; object-fit: contain; display: block; }
.ob-card__title,
.ob-card__desc{ margin: 0; }
.ob-card__title a{ color: inherit; text-decoration: none; }
.ob-card__title a::after{ content: ""; position: absolute; inset: 0; }

/* Some pages carry a hidden inline <style> block as their first content item.
   WordPress inserts its default block-gap between that hidden block and the
   first band, doubling the white space above the hero. Remove it so the hero
   sits flush under the header, consistent with the home page. */
.wp-block-post-content > style + .wp-block-group{ margin-block-start: 0; }

/* Courses list: real gap between the course icon and its text
   (moved here from the Courses page's inline <style>). */
.ob-course-card{ gap: var(--space-6); }

/* Bookmarks page: centered "Clear all bookmarks" action, and hide that page's
   own auto favorite button (moved from the Bookmarks page's inline <style>). */
.ob-clear{ text-align: center; margin-top: var(--space-8); }
.ob-clear .clear-favorites,
.ob-clear a{ color: var(--accent-terracotta); font-weight: 600; font-size: var(--text-caption); text-decoration: underline; cursor: pointer; background: none; border: 0; }
.simplefavorite-button[data-postid="47474"]{ display: none !important; }

/* "Premium" badge — a small corner tag on premium (MemberPress-protected)
   exercise and course cards. Shown only when optimistic_brain_is_premium() is true. */
.ex-card,
.ob-course-card{ position: relative; }
/* Exercise cards: icons align along the TOP; the Premium badge is pushed to the
   BOTTOM of the card (margin-top:auto in the flex column) so all badges line up
   on one bottom row regardless of title length. */
.ex-card__premium{
  align-self: center;
  margin-top: auto;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-inverse);
  background: var(--accent-gold);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  line-height: 1.5;
}
/* Course cards keep the corner badge (larger cards, no clipping there). */
.ob-course-card__premium{
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-inverse);
  background: var(--accent-gold);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  line-height: 1.5;
}
/* Above the 600px breakpoint the course card is a row and the badge sits in the
   top-right corner, absolutely positioned. Two consequences had to be handled.

   (1) At right:var(--space-2) the badge sat 8px from the card edge while every
       other element sits on the 24px padding, so it straddled the top border
       instead of lining up with the text column. Matching the card's padding
       fixes that.

   (2) Being out of flow, the badge reserved no space, so a long course title ran
       underneath it. Measured on the live page: the Relationships title crossed
       the badge's left edge by 46px with 3px of vertical clearance. The title
       therefore reserves room on the right. A title long enough to need it wraps
       to a second line, which is the intended trade.

   Below 600px the card centres its content and John confirmed it looks right, so
   neither rule applies there. */
@media (min-width: 601px){
  .ob-course-card__premium{ right: var(--space-6); }
  .ob-course-title{ padding-right: var(--space-24); }
}

/* Bookmark button placement: the button lives in the hero of exercises /
   articles / lessons only. Hide the Favorites plugin's auto-injected button on
   all PAGES except the Bookmarks page (47474, which needs its Remove buttons). */
body.page:not(.page-id-47474) .simplefavorite-button{ display: none !important; }
