/*
Theme Name:   KSA Custom Theme
Theme URI:    https://ksaconsultinginc.com
Description:  Standalone custom theme for ASK KSA. Delivers the LearnDash course library and WooCommerce course sales from hand-built templates, with no page builder and no parent theme.
Author:       Lara Kroeker Interactive
Author URI:   https://larakroekerinteractive.com
Version:      3.30.58
Requires at least: 6.0
Requires PHP: 7.4
License:      GNU General Public License v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  ksa
*/

/* ============================================================
   Base type — binds real content to the token system by TAG, not just
   by class. reset.css sets a generic system-font fallback (font-size:
   1rem, Apple/Segoe system stack) on <body> with no KSA tokens at all;
   without this rule anything not wrapped in one of the component
   classes below silently renders in the wrong font at the wrong size,
   invisible unless you go looking for it. This is the actual answer
   to "how do we make sure no body text escapes the system": bind the
   tag itself, so there's a correct default even when nobody remembers
   to add a class.

   .ksa-lead / .ksa-body / .ksa-small are the three explicit escape
   hatches for when a div/span needs a role on purpose rather than by
   inheriting from <body> or from a component class that already sets
   one of these — same job as LKI's .lki-lead/.lki-body/.lki-small.
   ============================================================ */
body {
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
}

.ksa-lead {
  font-family: var(--font-condensed);
  font-weight: var(--fw-light);
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-lh);
  color: var(--fg);
}

.ksa-body {
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
}

.ksa-small {
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg-muted);
}

/* ============================================================
   Nav — header-ksa-preview.php
   Static (scrolls with the page, not fixed) per decision Aug 6, 2026.
   Uses --ksa- tokens from colors_and_type.css exclusively — no new
   colors introduced here.
   ============================================================ */

.ksa-nav__topbar {
  height: 6px;
  background: var(--ksa-navy-darker);
}

.ksa-nav {
  background: var(--ksa-white);
  border-bottom: 1px solid var(--border);
}

.ksa-nav__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-5);
  display: flex;
  align-items: center;
  gap: var(--sp-5);
}

.ksa-nav__logo-link {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.ksa-nav .ksa-nav__logo {
  height: 64px;
  width: auto;
  display: block;
}

.ksa-nav__links {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-right: auto;
}

.ksa-nav .ksa-nav__link {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--fg);
  text-decoration: none;
  padding: var(--sp-2) 0;
  border-bottom: 2px solid transparent;
  transition: color 200ms ease-out, border-color 200ms ease-out;
}

.ksa-nav .ksa-nav__link:hover {
  color: var(--cta);
}

.ksa-nav .ksa-nav__link[aria-current="page"] {
  border-bottom-color: var(--cta);
}

/* Shared CTA pill — used in the nav (.ksa-nav), the footer's own CTA
   row at the top of .ksa-footer, and previewed on /design-guidelines/
   (.ksa-dg-button-grid, which can't use .ksa-nav or .ksa-footer__cta
   as the ancestor without dragging in their own unrelated layout).
   Same button, three contexts. */
.ksa-nav .ksa-nav__cta,
.ksa-footer__cta .ksa-nav__cta,
.ksa-dg-button-grid .ksa-nav__cta {
  flex-shrink: 0;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: var(--cta);
  color: var(--cta-text);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--radius-pill);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 200ms ease-out;
}

.ksa-nav .ksa-nav__cta:hover,
.ksa-footer__cta .ksa-nav__cta:hover,
.ksa-dg-button-grid .ksa-nav__cta:hover {
  background: var(--cta-hover);
  color: var(--cta-text);
}

.ksa-nav .ksa-nav__cta:active,
.ksa-footer__cta .ksa-nav__cta:active,
.ksa-dg-button-grid .ksa-nav__cta:active {
  background: var(--cta-active);
  color: var(--cta-text);
}

.ksa-nav__utility {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-shrink: 0;
}

.ksa-nav .ksa-nav__utility-link {
  font-size: var(--type-small-size);
  font-weight: var(--fw-medium);
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
  transition: color 200ms ease-out;
}

.ksa-nav .ksa-nav__utility-link:hover {
  color: var(--cta);
}

.ksa-nav .ksa-nav__utility-link--logout {
  color: var(--fg-muted);
}

.ksa-nav .ksa-nav__cart {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--fg);
  text-decoration: none;
  position: relative;
  padding: var(--sp-2);
  min-height: 44px;
  min-width: 44px;
  transition: color 200ms ease-out;
}

.ksa-nav .ksa-nav__cart:hover {
  color: var(--cta);
}

.ksa-nav__cart-icon {
  flex-shrink: 0;
}

.ksa-nav__cart-count {
  position: absolute;
  top: -2px;
  left: 22px;
  background: var(--cta);
  color: var(--cta-text);
  font-size: var(--type-micro-size);
  font-weight: var(--fw-bold);
  line-height: 1;
  min-width: 16px;
  height: 16px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 3px;
}

.ksa-nav__cart-total {
  font-size: var(--type-small-size);
  font-weight: var(--fw-medium);
  color: inherit;
}

/* Real Mini Cart block — kept in the DOM for its drawer/store, but not
   visually shown; #ksaNavCartTrigger above is the visible button and
   opens this block's drawer by proxy. Not display:none, so the block's
   own JS never has to reason about a hidden/unmounted element. */
.ksa-nav .wp-block-woocommerce-mini-cart {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

.ksa-nav .ksa-nav__hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
}

.ksa-nav .ksa-nav__hamburger span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--fg);
  transition: transform 200ms ease-out, opacity 200ms ease-out;
}

.ksa-nav .ksa-nav__hamburger.is-open span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.ksa-nav .ksa-nav__hamburger.is-open span:nth-child(2) {
  opacity: 0;
}
.ksa-nav .ksa-nav__hamburger.is-open span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.ksa-nav__drawer {
  display: none;
  flex-direction: column;
  background: var(--ksa-white);
  border-bottom: 1px solid var(--border);
  padding: var(--sp-2) var(--sp-5) var(--sp-5);
}

.ksa-nav__drawer.is-open {
  display: flex;
}

.ksa-nav__drawer .ksa-nav__drawer-link,
.ksa-nav__drawer .ksa-nav__drawer-cta {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
  text-decoration: none;
  padding: var(--sp-3) 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--border);
}

.ksa-nav__drawer .ksa-nav__drawer-cta {
  color: var(--accent);
}

.ksa-nav .ksa-nav__link:focus-visible,
.ksa-nav .ksa-nav__cta:focus-visible,
.ksa-footer__cta .ksa-nav__cta:focus-visible,
.ksa-dg-button-grid .ksa-nav__cta:focus-visible,
.ksa-nav .ksa-nav__utility-link:focus-visible,
.ksa-nav .ksa-nav__hamburger:focus-visible,
.ksa-nav__drawer .ksa-nav__drawer-link:focus-visible,
.ksa-nav__drawer .ksa-nav__drawer-cta:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

@media (prefers-reduced-motion: reduce) {
  .ksa-nav__link,
  .ksa-nav__cta,
  .ksa-nav__utility-link,
  .ksa-nav__hamburger span {
    transition: none;
  }
}

@media (max-width: 768px) {
  .ksa-nav__links,
  .ksa-nav__cta,
  .ksa-nav__utility {
    display: none;
  }

  .ksa-nav .ksa-nav__hamburger {
    display: flex;
    margin-left: auto;
  }
}

/* Nav overlay — homepage only (header.php sets `$ksa_nav_overlay` from
   is_front_page()). Nav is pulled out of flow and floated transparent
   over the video hero instead of sitting in its own solid white bar;
   .ksa-hero-video's own top padding (below) reserves the room for it so
   the heading/buttons don't render underneath. Logo keeps its own
   navy/white artwork so it doesn't need a color swap; links, utility
   links and the hamburger do. */
.ksa-nav__topbar--overlay {
  background: transparent;
}

.ksa-nav--overlay {
  position: absolute;
  top: 6px; /* below the (now-transparent) 6px topbar, same visual position as the static nav elsewhere */
  left: 0;
  right: 0;
  z-index: 20;
  background: transparent;
  border-bottom: none;
}

.ksa-nav--overlay .ksa-nav__link,
.ksa-nav--overlay .ksa-nav__utility-link,
.ksa-nav--overlay .ksa-nav__cart {
  color: var(--ksa-white);
}

.ksa-nav--overlay .ksa-nav__utility-link--logout {
  color: var(--fg-on-dark-muted);
}

.ksa-nav--overlay .ksa-nav__hamburger span {
  background: var(--ksa-white);
}

/* ============================================================
   Footer — footer-ksa-preview.php
   ============================================================ */

.ksa-footer {
  background: var(--ksa-navy-darker);
}

.ksa-footer__cta-band {
  background: var(--ksa-blue);
}

.ksa-footer__cta {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
}

.ksa-footer__cta-text {
  font-family: var(--font-condensed);
  font-weight: var(--fw-light);
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-lh);
  color: var(--fg-on-dark);
  text-align: center;
  margin: 0;
  max-width: 820px;
}

.ksa-footer__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-7);
}

.ksa-footer .ksa-footer__heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-caps-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--fg-on-dark);
  margin: 0 0 var(--sp-4);
}

.ksa-footer .ksa-footer__text {
  font-size: var(--type-small-size);
  line-height: var(--type-body-lh);
  color: var(--fg-on-dark-muted);
  margin: 0 0 var(--sp-4);
}

/* font-size set explicitly: the Contact column's links sit inside
   .ksa-footer__text and inherited its 14px, but the Services list and
   the "Sign up for updates" link sit outside it and were falling back
   to the 18px body default — three columns, two different link sizes. */
.ksa-footer .ksa-footer__link {
  font-size: var(--type-small-size);
  line-height: var(--type-body-lh);
  color: var(--fg-on-dark-muted);
  text-decoration: none;
  transition: color 200ms ease-out;
}

.ksa-footer .ksa-footer__link:hover {
  color: var(--cta);
}

.ksa-footer .ksa-footer__link--accent {
  color: var(--cta);
}

.ksa-footer .ksa-footer__link--accent:hover {
  color: var(--cta-hover);
}

/* Scoped to the Services list only — "Sign up for updates →" already
   has its own trailing arrow and shouldn't get a second, leading one. */
.ksa-footer .ksa-footer__list .ksa-footer__link--accent::before {
  content: "→";
  display: inline-block;
  margin-right: var(--sp-2);
}

.ksa-footer .ksa-footer__list {
  list-style: none;
  margin: 0 0 var(--sp-4);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.ksa-footer__socials {
  display: flex;
  gap: var(--sp-3);
}

.ksa-footer .ksa-footer__social {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--fg-on-dark-subtle);
  color: var(--fg-on-dark-muted);
  transition: border-color 200ms ease-out, color 200ms ease-out;
}

.ksa-footer .ksa-footer__social:hover {
  border-color: var(--cta);
  color: var(--cta);
}

.ksa-footer .ksa-footer__social:focus-visible,
.ksa-footer .ksa-footer__link:focus-visible,
.ksa-footer .ksa-footer__link--accent:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-footer__bottombar {
  background: var(--ksa-navy-darker);
  padding: var(--sp-4) var(--sp-5);
}

/* Copyright left, legal links right; stacks on narrow screens. The
   max-width/centring moved from .ksa-footer__copyright to this wrapper
   when the legal links were added (Aug 7, 2026). */
.ksa-footer__bottombar-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
}

.ksa-footer__copyright {
  font-size: var(--type-small-size);
  color: var(--fg-on-dark-subtle);
  margin: 0;
}

.ksa-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
}

.ksa-footer .ksa-footer__legal a {
  font-size: var(--type-small-size);
  color: var(--fg-on-dark-subtle);
  text-decoration: none;
  transition: color 200ms ease-out;
}

.ksa-footer .ksa-footer__legal a:hover {
  color: var(--cta);
}

.ksa-footer .ksa-footer__legal a:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

@media (max-width: 600px) {
  .ksa-footer__bottombar-inner {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ksa-footer .ksa-footer__link,
  .ksa-footer .ksa-footer__link--accent,
  .ksa-footer .ksa-footer__social {
    transition: none;
  }
}

@media (max-width: 768px) {
  .ksa-footer__inner {
    grid-template-columns: 1fr;
    gap: var(--sp-6);
  }
}

.ksa-page-hero {
  background: var(--ksa-navy);
}

.ksa-page-hero__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-9) var(--sp-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-7);
}

.ksa-page-hero__copy {
  max-width: 720px;
}

.ksa-page-hero .ksa-page-hero__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
  color: var(--cta);
  margin: 0 0 var(--sp-4);
}

.ksa-page-hero .ksa-page-hero__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg-on-dark);
  margin: 0;
}

/* Matches .ksa-page-section__text--lead's size/weight/line-height —
   not its centering/max-width/margin, which assume a centered section
   layout the hero (flex row, icon on the right) doesn't use. */
.ksa-page-hero .ksa-page-hero__text--lead {
  font-size: var(--type-lead-size);
  font-weight: var(--fw-light);
  line-height: var(--type-lead-lh);
}

.ksa-page-hero__icon {
  flex-shrink: 0;
  width: 140px;
  height: 140px;
  object-fit: contain;
}

.ksa-page-section {
  background: var(--ksa-white);
}

.ksa-page-section--tinted {
  background: var(--ksa-grey-5);
}

.ksa-page-section__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5);
}

/* Compact variant — for thin utility rows (like the course filter bar)
   where the standard section padding leaves too much dead space above
   and below a single row of controls.

   Top padding is deliberately larger than the bottom: the bar needs
   breathing room from the section above it, but should stay close to
   the course grid it actually controls. */
.ksa-page-section--tight .ksa-page-section__inner {
  padding-top: var(--sp-9);
  padding-bottom: var(--sp-5);
}

/* Drops top padding entirely on whatever section immediately follows
   a --tight one, so that section's own top padding doesn't stack with
   --tight's bottom padding and make the gap below look bigger than
   the gap above (both gaps land on a white background and visually
   merge into one, unlike the tinted section above --tight, whose
   bottom padding is colored and doesn't read as extra white space). */
.ksa-page-section--flush-top .ksa-page-section__inner {
  padding-top: 0;
}

/* Brand New Courses — extra breathing room above and below the mosaic
   grid, more than the standard section padding. */
.ksa-home-courses .ksa-page-section__inner {
  padding-top: var(--sp-10);
  padding-bottom: var(--sp-10);
}

.ksa-page-section .ksa-page-section__heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-5);
}

/* Sized like the page's H1 (still an <h2> tag — one real H1 per page,
   in the hero — this just borrows its scale for emphasis). */
.ksa-page-section .ksa-page-section__heading--big {
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
}

.ksa-page-section .ksa-page-section__eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  line-height: var(--type-caps-lh);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-page-section__eyebrow--center {
  text-align: center;
}

.ksa-page-section .ksa-page-section__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  max-width: 720px;
  margin: 0 0 var(--sp-5);
}

.ksa-page-section .ksa-page-section__heading--center {
  text-align: center;
  max-width: none;
}

.ksa-page-section .ksa-page-section__text--lead {
  font-size: var(--type-lead-size);
  font-weight: var(--fw-light);
  line-height: var(--type-lead-lh);
  text-align: center;
  max-width: 820px;
  margin: 0 auto var(--sp-7);
}

.ksa-page-section .ksa-page-section__link {
  color: var(--link);
  text-decoration: underline;
  transition: color 200ms ease-out;
}

.ksa-page-section .ksa-page-section__link:hover {
  color: var(--link-hover);
}

.ksa-page-section .ksa-contact-info {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-5);
}

.ksa-socials {
  display: flex;
  gap: var(--sp-3);
}

.ksa-page-section .ksa-social-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  color: var(--fg-muted);
  transition: border-color 200ms ease-out, color 200ms ease-out;
}

.ksa-page-section .ksa-social-btn:hover {
  border-color: var(--cta);
  color: var(--cta);
}

.ksa-page-section .ksa-social-btn:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* Cards enlarged Aug 7, 2026: the 200px minimum packed 5 across and
   left them looking like tags rather than something to click. 320px
   gives roughly 3 across at full width, still collapsing cleanly. */
.ksa-newsletter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--sp-5);
}

.ksa-page-section .ksa-newsletter-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 200ms ease-out;
}

.ksa-page-section .ksa-newsletter-card:hover {
  border-color: var(--cta);
}

.ksa-page-section .ksa-newsletter-card:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-newsletter-card__image {
  display: block;
  width: 100%;
  height: 180px;
  object-fit: cover;
}

.ksa-page-section .ksa-newsletter-card__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  padding: var(--sp-5) var(--sp-5) 0;
}

.ksa-page-section .ksa-newsletter-card__date {
  font-size: var(--type-small-size);
  color: var(--fg-muted);
  padding: var(--sp-2) var(--sp-5) var(--sp-5);
}

@media (max-width: 768px) {
  .ksa-page-hero__inner {
    flex-direction: column-reverse;
    text-align: center;
  }

  .ksa-page-hero__copy {
    max-width: none;
  }
}

/* ============================================================
   Pro Tips video blocks — page-pro-tips.php
   ============================================================ */

/* Copy left, video right (reversed Aug 7, 2026). Done with `order`
   rather than by reordering the markup, so the video stays first in the
   DOM — which is what mobile wants (see the 768px query below, where the
   order is reset and the video returns to the top). */
.ksa-pro-tip {
  display: grid;
  grid-template-columns: 1fr minmax(280px, 400px);
  gap: var(--sp-7);
  align-items: start;
}

.ksa-pro-tip__video {
  order: 2;
}

.ksa-pro-tip__body {
  order: 1;
}

.ksa-pro-tip__video-frame {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--ksa-navy-darker);
}

.ksa-pro-tip__video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.ksa-page-section .ksa-pro-tip__text p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-pro-tip__text ul {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-5);
  color: var(--fg);
}

.ksa-page-section .ksa-pro-tip__text li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  margin-bottom: var(--sp-2);
}

.ksa-page-section .ksa-pro-tip__text strong {
  font-weight: var(--fw-bold);
  color: var(--fg);
}

.ksa-pro-tip__courses {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

/* Generic pill button — reusable anywhere inside .ksa-page-section, not
   just Pro Tips. Same visual language as .ksa-nav__cta. Also nested
   under .ksa-hero-video for the homepage hero, which isn't a
   .ksa-page-section — same rule, different ancestor. (Until Aug 27,
   2026 this also covered .ksa-hero-carousel; that section was replaced
   by the video hero and the carousel markup no longer exists anywhere
   in the theme, so that selector was dropped rather than left dead.) */
.ksa-page-section .ksa-pill-btn,
.ksa-hero-video .ksa-pill-btn {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: var(--cta);
  color: var(--cta-text);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--radius-pill);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 200ms ease-out;
}

.ksa-page-section .ksa-pill-btn:hover,
.ksa-hero-video .ksa-pill-btn:hover {
  background: var(--cta-hover);
}

.ksa-page-section .ksa-pill-btn:focus-visible,
.ksa-hero-video .ksa-pill-btn:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* Ghost/outline pill variant — added Aug 27, 2026 for the homepage
   hero's "Consulting" button. Same footprint as .ksa-pill-btn but
   transparent, so it reads as secondary next to a solid CTA on a dark
   (video/photo) background. Padding is trimmed by the border width so
   both buttons line up at the same height. */
.ksa-page-section .ksa-pill-btn--ghost,
.ksa-hero-video .ksa-pill-btn--ghost {
  background: transparent;
  border: 2px solid var(--ksa-white);
  color: var(--ksa-white);
  padding: calc(var(--sp-3) - 2px) calc(var(--sp-5) - 2px);
}

.ksa-page-section .ksa-pill-btn--ghost:hover,
.ksa-hero-video .ksa-pill-btn--ghost:hover {
  background: var(--ksa-white);
  color: var(--ksa-navy);
}

.ksa-page-section .ksa-pill-btn--ghost:focus-visible,
.ksa-hero-video .ksa-pill-btn--ghost:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* "CTA Text" — Small doing a button's job. For a secondary action
   next to real content, where a solid pill would compete with it. */
.ksa-page-section .ksa-text-link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--cta);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 200ms ease-out, color 200ms ease-out;
}
.ksa-page-section .ksa-text-link:hover {
  border-color: var(--cta-hover);
  color: var(--cta-hover);
}
.ksa-page-section .ksa-text-link__arrow {
  display: inline-block;
  transition: transform 250ms cubic-bezier(.34, 1.56, .64, 1);
}
.ksa-page-section .ksa-text-link:hover .ksa-text-link__arrow {
  transform: translateX(4px);
}
.ksa-page-section .ksa-text-link:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* "Tag" — Eyebrow's 13px without the uppercase/tracking, for a label
   that names a fact rather than announcing a section. */
.ksa-page-section .ksa-tag {
  display: inline-block;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  color: var(--accent);
  background: var(--ksa-blue-light);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-pill);
}

@media (max-width: 768px) {
  .ksa-pro-tip {
    grid-template-columns: 1fr;
  }

  /* Single column — put the video back on top, ahead of the copy. */
  .ksa-pro-tip__video,
  .ksa-pro-tip__body {
    order: 0;
  }
}

/* ============================================================
   Services page — page-services.php
   ============================================================ */

.ksa-services-list {
  display: flex;
  flex-direction: column;
}

.ksa-service-block {
  padding: var(--sp-7) 0;
  border-bottom: 1px solid var(--border);
}

.ksa-service-block:first-child {
  padding-top: 0;
}

.ksa-service-block:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.ksa-page-section .ksa-service-block__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

/* `align-items: start` is what puts the "Services include:" list level
   with the TOP OF THE PHOTO rather than stretching it down the row —
   the photo now leads the left column, so both columns begin on the
   same line. */
.ksa-service-block__row {
  display: grid;
  grid-template-columns: 1fr minmax(240px, 340px);
  gap: var(--sp-8);
  align-items: start;
}

/* Fixed ratio with object-fit:cover so all five blocks read as one set
   regardless of each source photo's own ratio — the originals range
   from 3:2 to 4:3, which would otherwise give every block a different
   image height and lose the rhythm down the page.
   32:9 is exactly half the height of the 16:9 this started at — a wide
   banner strip above each title, so the photo sets the tone without
   pushing the actual content down the page. */
.ksa-service-block .ksa-service-block__img {
  display: block;
  width: 100%;
  aspect-ratio: 32 / 9;
  height: auto;
  object-fit: cover;
  /* 25%, not the default 50%. At a strip this wide the crop window is
     less than half the source height, and a centred window cut the
     tops off heads — the standing woman in the CSQM photo lost her
     head entirely and the PD photo cropped through the eyes. Biasing
     the window upward keeps faces intact in all five, and still reads
     naturally on the two photos with no people in them (checked each
     crop before committing to the number). */
  object-position: center 25%;
  border-radius: var(--radius-md);
  /* grayscale + a brand-blue overlay (below) pulls every source photo
     toward the same blue regardless of its own original colour, so a
     yellow-highlighter close-up and a navy-toned office shot read as
     one consistent set instead of five unrelated stock photos. */
  filter: grayscale(0.6) contrast(1.05) brightness(1.05);
}

.ksa-service-block__img-wrap {
  position: relative;
  display: block;
  margin: 0 0 var(--sp-5);
}

.ksa-service-block__img-wrap::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--ksa-blue);
  mix-blend-mode: color;
  opacity: 0.25;
  border-radius: var(--radius-md);
  pointer-events: none;
}

.ksa-page-section .ksa-service-block__label {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-service-block__list {
  list-style: disc;
  margin: 0;
  padding-left: var(--sp-5);
  color: var(--fg);
}

.ksa-page-section .ksa-service-block__list li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  margin-bottom: var(--sp-3);
}

.ksa-page-section .ksa-service-block__body {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-service-block .ksa-service-block__link {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--cta);
  text-decoration: none;
  transition: color 200ms ease-out;
}

.ksa-service-block .ksa-service-block__link:hover {
  color: var(--cta-hover);
}

.ksa-service-block .ksa-service-block__link:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-testimonial-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
}

.ksa-testimonial-card {
  margin: 0;
  background: var(--ksa-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-7) var(--sp-6);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.ksa-testimonial-card__mark {
  font-family: Georgia, serif;
  font-style: italic;
  font-size: 64px;
  line-height: 0.6;
  color: var(--cta);
}

.ksa-page-section .ksa-testimonial-card blockquote {
  margin: 0;
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  font-weight: var(--fw-regular);
  font-style: italic;
}

.ksa-testimonial-card figcaption {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-top: auto;
}

.ksa-testimonial-card__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--ksa-white);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
}

.ksa-testimonial-card__who {
  display: flex;
  flex-direction: column;
}

.ksa-testimonial-card__name {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--fg);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.ksa-testimonial-card__company {
  font-size: var(--type-small-size);
  color: var(--accent);
  margin-top: 2px;
}

@media (max-width: 900px) {
  .ksa-service-block__row {
    grid-template-columns: 1fr;
    gap: var(--sp-5);
  }

  .ksa-testimonial-grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   About page — page-about.php
   ============================================================ */

.ksa-about-row {
  display: grid;
  grid-template-columns: minmax(240px, 380px) 1fr;
  gap: var(--sp-8);
  align-items: center;
}


.ksa-about-row--reverse {
  grid-template-columns: 1fr minmax(240px, 380px);
}

.ksa-about-row--reverse .ksa-about-row__media {
  order: 2;
}

.ksa-about-row__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
}

/* Small/big rhythm for the 4 "Kirsten's approach" / "trusted voice" /
   "leadership beyond practice" / "experienced support" rows — added
   Aug 27, 2026, modeled on stg-zoedaokroeker-staging.kinsta.cloud/about/'s
   .zoe-timeline__media (one fixed photo shape, alternating container
   size down the page). "big" needs no rule of its own — it's the same
   240-380px column the row already defaults to; only "small" narrows it. */
.ksa-about-row--small {
  grid-template-columns: minmax(200px, 280px) 1fr;
}

.ksa-about-row--small.ksa-about-row--reverse {
  grid-template-columns: 1fr minmax(200px, 280px);
}

/* Portrait modifier for those same 4 rows — locks every photo to one
   shape via object-fit: cover regardless of the source file's own
   aspect ratio (the underlying JPEGs are already center-cropped close
   to this, but the ratio is enforced here, not assumed from the file). */
.ksa-about-row__img--portrait {
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* Round modifier — Kirsten's second photo, styled as a LinkedIn-style
   avatar crop instead of a second big rectangular photo (two large
   rectangular photos on one page read as redundant). Stacks the avatar
   over a name caption now that the section heading no longer names her
   itself ("Experience behind the advice." vs. the old "Meet Kirsten..."). */
.ksa-about-row__media--round {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
}

.ksa-about-row__img--round {
  width: 220px;
  height: 220px;
  object-fit: cover;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  border: 6px solid var(--ksa-white);
}

/* Profile-icon size — added Aug 27, 2026 so the avatar reads as a small
   identifying icon next to its caption rather than a second large
   photo competing with the row's own media column. Same selector
   weight as .ksa-about-row__img--round (one class each); this rule
   comes later in the cascade, so its width/height win while everything
   else (object-fit, radius, border) is inherited from the rule above. */
.ksa-about-row__img--icon {
  width: 120px;
  height: 120px;
}

.ksa-about-row__icon-caption {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg);
  text-align: center;
  margin: 0;
}

.ksa-page-section .ksa-about-row__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

/* Lead variant — same light-weight, larger lead size as the hero and
   intro paragraphs elsewhere, but left-aligned and unconstrained since
   it sits in a copy column rather than a full-width centered block. */
.ksa-page-section .ksa-about-row__text--lead {
  font-size: var(--type-lead-size);
  font-weight: var(--fw-light);
  line-height: var(--type-lead-lh);
}

.ksa-page-section .ksa-about-row__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-5);
}

/* Callout, not an inline link — bigger, regular-weight navy text on a
   tinted block with a left accent border. Replaces an earlier version
   that was small bold blue text and read like a link, not a pull-quote. */
.ksa-page-section .ksa-about-row__pull {
  font-family: var(--font-condensed);
  font-weight: var(--fw-light);
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-lh);
  color: var(--fg);
  background: var(--ksa-blue-light);
  border-left: 4px solid var(--accent);
  padding: var(--sp-5) var(--sp-6);
  margin: var(--sp-2) 0 var(--sp-6);
}

/* ---- Kirsten bio timeline (About page) — 3 short cards replacing
   what used to be 3 dense paragraphs. Navy top-border for the two
   past beats, orange for "Today" — the one accent colour, marking
   the present. ---- */
.ksa-timeline-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-7);
}

.ksa-timeline-card {
  border-top: 3px solid var(--cta);
  padding-top: var(--sp-4);
}

.ksa-page-section .ksa-timeline-card__eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent);
  margin: 0 0 var(--sp-2);
}

.ksa-page-section .ksa-timeline-card__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-timeline-card__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0;
}

/* Same 3-column grid as .ksa-timeline-grid directly above it, so the
   closing group's left edge lines up exactly with the 2nd timeline
   card's — not just visually "aligned right", but on the same column
   lines the cards use. */
.ksa-about-closing {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-7);
}

/* Quote first in markup, photo second — image sits on the right. */
.ksa-about-closing__group {
  grid-column: 2 / 4;
  display: flex;
  align-items: center;
  gap: var(--sp-6);
}

.ksa-about-closing__img {
  flex-shrink: 0;
  width: 160px;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radius-lg);
}

/* Plain italic body text, not the boxed pull-quote treatment — no
   accent line, just a narrower column that wraps to about 4 lines. */
.ksa-page-section .ksa-about-closing__quote {
  max-width: 440px;
  margin: 0;
  font-size: var(--type-body-size);
  font-style: italic;
  line-height: var(--type-body-lh);
  color: var(--fg);
}

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

  .ksa-about-closing {
    grid-template-columns: 1fr;
  }

  .ksa-about-closing__group {
    grid-column: 1;
    flex-direction: column;
    align-items: flex-start;
  }

  .ksa-about-closing__img {
    width: 140px;
  }
}

.ksa-page-section .ksa-page-section__text p {
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-page-section__text p:last-child {
  margin-bottom: 0;
}

/* Narrow heading column, wide filters + list column — same
   narrow-label/wide-content ratio as .ksa-service-block__row and
   .ksa-pd-intro — each side in its own wrapper div so the grid always
   has exactly 2 children regardless of how much markup each holds. */
.ksa-faq {
  display: grid;
  grid-template-columns: minmax(240px, 340px) 1fr;
  gap: var(--sp-8);
}

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

.ksa-page-section .ksa-faq__heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
  margin: 0;
}

.ksa-faq .ksa-course-filter {
  margin-bottom: var(--sp-6);
}

/* No gap between rows: the alternating stripes below need to be
   contiguous to read as a list rather than as separate cards. The
   rounded corners move to the container, which clips the first and
   last stripe for them. */
.ksa-faq-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.ksa-faq-item {
  background: var(--ksa-white);
  padding: var(--sp-4) var(--sp-5);
  transition: background-color 200ms ease-out;
}

/* --ksa-grey-5 is the token literally documented as "alt rows". Class
   rather than :nth-child, since :nth-child counts hidden items too —
   filtering the list by category would otherwise throw off which
   visible row looks "even". JS applies/removes this on filter. */
.ksa-faq-item--alt {
  background: var(--ksa-grey-5);
}

/* Higher specificity than .ksa-faq-item--alt (0,2,0 vs 0,1,0), so
   hover always wins over the zebra regardless of source order. */
.ksa-faq-item:hover {
  background: var(--ksa-blue-light);
}

.ksa-faq-item + .ksa-faq-item {
  margin-top: 0;
}

.ksa-page-section .ksa-faq-item__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
  cursor: pointer;
  list-style: none;
}

.ksa-faq-item__q::-webkit-details-marker {
  display: none;
}

/* Outlined at rest, filled orange on rollover. Real Phosphor plus/
   minus glyphs via mask-image (crisp vector, not a font glyph) — the
   circle chrome lives on .ksa-faq-item__icon itself so the mask only
   ever clips the glyph layer, never the border/background. */
.ksa-faq-item__icon {
  flex-shrink: 0;
  position: relative;
  width: 36px;
  height: 36px;
  background: transparent;
  border: 1px solid var(--cta);
  border-radius: var(--radius-pill);
  transition: background-color 200ms ease-out;
}

.ksa-faq-item__icon::after {
  content: "";
  position: absolute;
  inset: 9px;
  background-color: var(--cta);
  -webkit-mask-image: url("assets-icons/System Icons/plus-light.svg");
  mask-image: url("assets-icons/System Icons/plus-light.svg");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  transition: background-color 200ms ease-out;
}

.ksa-faq-item[open] .ksa-faq-item__icon::after {
  -webkit-mask-image: url("assets-icons/System Icons/minus-light.svg");
  mask-image: url("assets-icons/System Icons/minus-light.svg");
}

/* Both selectors, so the fill appears whether the pointer is over the
   button itself or anywhere else on the row — the whole row is the
   click target, so the button has to react to the whole row. */
.ksa-faq-item__q:hover .ksa-faq-item__icon,
.ksa-faq-item:hover .ksa-faq-item__icon {
  background: var(--cta);
}

.ksa-faq-item__q:hover .ksa-faq-item__icon::after,
.ksa-faq-item:hover .ksa-faq-item__icon::after {
  background-color: var(--cta-text);
}

.ksa-faq-item__q:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-page-section .ksa-faq-item__a p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: var(--sp-4) 0 0;
}

@media (max-width: 900px) {
  .ksa-about-row,
  .ksa-about-row--reverse {
    grid-template-columns: 1fr;
  }

  .ksa-about-row--reverse .ksa-about-row__media {
    order: 0;
  }

}

/* ============================================================
   PD Courses page — page-professional-development-courses.php
   ============================================================ */

.ksa-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-7);
  text-align: center;
}

.ksa-page-section .ksa-feature-card__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-feature-card__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0;
}

/* No `align-items: start` — the default `stretch` is what makes the
   "Already Enrolled?" card run the full height of the copy beside it,
   instead of floating as a short block against a tall paragraph. */
.ksa-pd-intro {
  display: grid;
  grid-template-columns: 1fr minmax(260px, 340px);
  gap: var(--sp-8);
}

/* Box treatment matched to .ksa-about-row__pull on the About page, per
   request: same blue wash, same 4px accent rule on the left, same
   square corners and same padding. Only the BOX matches — the type
   inside stays at its own smaller, more UI-like scale, since this is a
   1-2 sentence prompt with a link rather than an excerpted line of
   body copy. */
.ksa-pd-intro__aside {
  background: var(--ksa-blue-light);
  border-left: 4px solid var(--accent);
  border-radius: 0;
  padding: var(--sp-5) var(--sp-6);
}

.ksa-page-section .ksa-pd-intro__aside-title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-pd-intro__aside-text {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg);
  margin: 0;
}

.ksa-page-section .ksa-pd-intro__aside-text a {
  color: var(--link);
  text-decoration: underline;
}

.ksa-page-section .ksa-pd-intro__aside-text a:hover {
  color: var(--link-hover);
}

.ksa-course-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-5);
}

/* The title sits as a cell in the grid itself, not as a heading above
   it — a photo/text mosaic idea. */
.ksa-course-mosaic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas: "c1 c2 c3" "c4 title c5";
  gap: var(--sp-5);
}
.ksa-page-section .ksa-course-mosaic__title {
  grid-area: title;
  background: var(--ksa-blue-light);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: var(--sp-6) var(--sp-5);
}
.ksa-page-section .ksa-course-mosaic__title p {
  color: var(--fg-muted);
  margin: 0 0 var(--sp-5);
}
/* The eyebrow is also a <p> — without this it inherits the muted grey
   above on specificity instead of its own blue. */
.ksa-page-section .ksa-course-mosaic__title .ksa-page-section__eyebrow {
  color: var(--accent);
}
.ksa-course-mosaic .ksa-course-card[data-cell="c1"] { grid-area: c1; }
.ksa-course-mosaic .ksa-course-card[data-cell="c2"] { grid-area: c2; }
.ksa-course-mosaic .ksa-course-card[data-cell="c3"] { grid-area: c3; }
.ksa-course-mosaic .ksa-course-card[data-cell="c4"] { grid-area: c4; }
.ksa-course-mosaic .ksa-course-card[data-cell="c5"] { grid-area: c5; }

@media (max-width: 900px) {
  .ksa-course-mosaic {
    grid-template-columns: 1fr;
    grid-template-areas: "c1" "c2" "title" "c3" "c4" "c5";
  }
}

/* No hover ring on the card itself — it holds two distinct actions
   (Add to Cart, Learn More) plus the title/image links, so a single
   whole-card highlight misleadingly implies one shared click target. */
.ksa-course-card {
  display: flex;
  flex-direction: column;
  background: var(--ksa-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.ksa-course-card__image {
  display: block;
  flex-shrink: 0;
}

.ksa-course-card__image img {
  display: block;
  width: 100%;
  height: auto;
}

.ksa-course-card__body {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  padding: var(--sp-5);
}

/* Matches .ksa-feature-card__title exactly (the Informative/Practical/
   Engaging headings above this grid) — --type-h4-size, not h3. */
.ksa-page-section .ksa-course-card__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-course-card__title a {
  color: var(--fg);
  text-decoration: none;
}

.ksa-page-section .ksa-course-card__title a:hover {
  color: var(--cta);
}

.ksa-page-section .ksa-course-card__desc {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
  flex-grow: 1;
}

.ksa-course-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
}

.ksa-course-card__price {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--fg);
}

.ksa-course-card .ksa-course-card__link {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--cta);
  text-decoration: none;
  white-space: nowrap;
  transition: color 200ms ease-out;
}

.ksa-course-card .ksa-course-card__link:hover {
  color: var(--cta-hover);
}

.ksa-course-card__cart {
  margin-top: var(--sp-3);
}

.ksa-page-section .ksa-course-card__cart a.button {
  display: block;
  width: 100%;
  text-align: center;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--fg);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color 200ms ease-out, border-color 200ms ease-out, color 200ms ease-out;
}

.ksa-page-section .ksa-course-card__cart a.button:hover {
  background: var(--cta);
  border-color: var(--cta);
  color: var(--cta-text);
}

/* This button is an <a>, not a <button>, so without this it falls back
   to the browser default outline instead of the KSA focus ring the
   filter buttons get. */
.ksa-page-section .ksa-course-card__cart a.button:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-page-section .ksa-course-card__cart a.added_to_cart {
  display: block;
  margin-top: var(--sp-2);
  text-align: center;
  font-size: var(--type-small-size);
  color: var(--link);
  text-decoration: underline;
}

.ksa-page-section .ksa-course-card__cart a.added_to_cart:hover {
  color: var(--link-hover);
}

.ksa-course-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.ksa-page-section .ksa-course-filter__btn {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 200ms ease-out, border-color 200ms ease-out, color 200ms ease-out;
}

.ksa-page-section .ksa-course-filter__btn:hover,
.ksa-page-section .ksa-course-filter__btn.is-active {
  background: var(--filter-colour, var(--ksa-orange-light));
  border-color: var(--border);
  color: var(--filter-text, var(--cta-text));
}

.ksa-page-section .ksa-course-filter__btn:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-testimonial-grid--four {
  grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 1100px) {
  .ksa-course-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 900px) {
  .ksa-feature-grid {
    grid-template-columns: 1fr;
    gap: var(--sp-6);
  }

  .ksa-pd-intro {
    grid-template-columns: 1fr;
  }

  .ksa-testimonial-grid--four {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 560px) {
  .ksa-course-grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Homepage — front-page.php
   ============================================================ */

.ksa-home-intro-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-6);
}

/* Bottom padding is deliberately smaller than top — the card's own
   48px bottom padding was stacking with the section's own 64px
   bottom padding, leaving 112px of dead space under "Learn More"
   before the next section. 24+64=88px reads as one gap, not two. */
.ksa-home-intro-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--sp-7) var(--sp-6) var(--sp-5);
}

.ksa-home-intro-card__icon {
  width: 72px;
  height: 72px;
  object-fit: contain;
  margin-bottom: var(--sp-4);
}

.ksa-page-section .ksa-home-intro-card__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}
/* --type-h3-size is doing its documented "Card Title" job here, not
   a heading job — see colors_and_type.css. */

.ksa-page-section .ksa-home-intro-card__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-5);
  flex-grow: 1;
}

/* Homepage background video, with a still-image fallback. */
.ksa-hero-video {
  position: relative;
  height: 720px;
  /* Reserves room for .ksa-nav--overlay, which floats on top of this
     section instead of taking its own space in the page flow — roughly
     the nav's own height (128px) plus a little breathing room. */
  padding-top: 140px;
  overflow: hidden;
  background: var(--ksa-navy);
}

.ksa-hero-video__bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.ksa-hero-video__poster,
.ksa-hero-video__bg video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.ksa-hero-video__bg video { opacity: 0; }
.ksa-hero-video__bg video.is-playing { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .ksa-hero-video__bg video { display: none; }
}

.ksa-hero-video__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(1, 31, 65, 0.75) 0%, rgba(1, 31, 65, 0.35) 55%, rgba(1, 31, 65, 0.15) 100%);
}

.ksa-hero-video__inner {
  position: relative;
  z-index: 1;
  max-width: 1280px;
  height: 100%;
  margin: 0 auto;
  padding: 0 var(--sp-5);
  display: flex;
  align-items: center;
}

.ksa-hero-video__content {
  max-width: 640px;
}

.ksa-hero-video__heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-display-size);
  line-height: var(--type-display-lh);
  color: var(--ksa-white);
  margin: 0 0 var(--sp-4);
}

.ksa-hero-video__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg-on-dark-muted);
  margin: 0 0 var(--sp-6);
}

.ksa-hero-video__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* Staggered load reveal — headline, then lede, then buttons, each a
   beat behind the last. */
.ksa-hero-video__heading,
.ksa-hero-video__text,
.ksa-hero-video__buttons {
  opacity: 0;
  transform: translateY(16px);
  animation: ksaHeroIn 700ms ease forwards;
}
.ksa-hero-video__heading { animation-delay: 100ms; }
.ksa-hero-video__text { animation-delay: 280ms; }
.ksa-hero-video__buttons { animation-delay: 460ms; }
@keyframes ksaHeroIn {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .ksa-hero-video__heading,
  .ksa-hero-video__text,
  .ksa-hero-video__buttons {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

/* In-house training callout — replaces the old "Featured Courses"
   product query, added Aug 27, 2026. Centered intro copy, then a
   3-column grid of left-aligned sub-sections, collapsing to 1 column
   on mobile alongside the other homepage grids. */
.ksa-inhouse-callout {
  max-width: 900px;
  margin: 0 auto;
  text-align: center;
}

.ksa-inhouse-callout__lead {
  margin-bottom: var(--sp-5);
}

.ksa-inhouse-callout__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-inhouse-callout__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  text-align: left;
  margin: var(--sp-7) 0;
}

/* Same border/radius/padding language as .ksa-course-card, no shadow. */
.ksa-inhouse-callout__item {
  background: var(--ksa-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--sp-6);
  transition: border-color 200ms ease-out, transform 200ms ease-out;
}
.ksa-inhouse-callout__item:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.ksa-inhouse-callout__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  line-height: var(--type-h4-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-inhouse-callout__closing {
  font-size: var(--type-body-size);
  font-weight: var(--fw-bold);
  color: var(--fg);
  margin: var(--sp-6) 0 0;
}

/* Inline "Get in Touch" arrow-link at the end of the closing sentence —
   replaces a standalone pill button below it, added Aug 27, 2026. Same
   visual language as .ksa-course-card__link's "Learn More →". */
.ksa-inhouse-callout__cta-link {
  display: inline-block;
  font-family: var(--font-condensed);
  font-size: inherit;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--cta);
  text-decoration: none;
  white-space: nowrap;
  margin-left: var(--sp-2);
  transition: color 200ms ease-out;
}

.ksa-inhouse-callout__cta-link:hover {
  color: var(--cta-hover);
}

.ksa-inhouse-callout__cta-link:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

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

  .ksa-inhouse-callout__grid {
    grid-template-columns: 1fr;
  }

  .ksa-hero-video {
    height: 780px;
  }

  .ksa-hero-video__heading {
    font-size: var(--type-h2-size);
  }
}

.ksa-page-section .ksa-course-content h2,
.ksa-page-section .ksa-course-content h3 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
  margin: var(--sp-7) 0 var(--sp-4);
}

.ksa-page-section .ksa-course-content h2:first-child,
.ksa-page-section .ksa-course-content h3:first-child {
  margin-top: 0;
}

/* "Course Content" is LearnDash's own heading (inside its
   .ld-section-heading wrapper, from the curriculum widget). Sized up
   to H1 — the curriculum list is the most important thing on the page
   for a viewer, so it should read as the dominant heading, bigger than
   "Overview" beside it. !important for the usual reason: LearnDash's
   own rule for this heading is more specific and loads after this
   file. */
.ksa-page-section .ksa-course-content .ld-section-heading h2 {
  font-family: var(--font-condensed) !important;
  font-weight: var(--fw-bold) !important;
  font-size: var(--type-h1-size) !important;
  line-height: var(--type-h1-lh) !important;
  color: var(--fg) !important;
  margin: 0 0 var(--sp-4) !important;
}

.ksa-page-section .ksa-course-content p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-course-content ul {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-5);
  color: var(--fg);
}

.ksa-page-section .ksa-course-content li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  margin-bottom: var(--sp-2);
}

.ksa-page-section .ksa-course-content strong {
  font-weight: var(--fw-bold);
  color: var(--fg);
}

.ksa-page-section .ksa-course-content a {
  color: var(--link);
  text-decoration: underline;
}

.ksa-page-section .ksa-course-content a:hover {
  color: var(--link-hover);
}

/* Curriculum lesson rollover — orange instead of LearnDash's blue.
 *
 * COLOUR CHOICE IS DELIBERATE: this is --cta-active (#A6570F), not the
 * brand orange --cta (#E07D2C). This text sits on a white card, and
 * #E07D2C on white is 2.94:1 — it fails WCAG AA, which is exactly what
 * colors_and_type.css warns about on the --ksa-orange token ("NOT for
 * text links"). --cta-hover (#C4661A) is still only 3.99:1. #A6570F
 * measures 5.26:1 and passes, while still reading unmistakably orange.
 * The hero eyebrow above can use the full brand orange because navy
 * behind it gives 5.61:1.
 *
 * SPECIFICITY: LearnDash prints its "Primary Color" setting as an
 * INLINE <style> block — not an external file — containing
 * `.learndash-wrapper .ld-item-list .ld-item-list-item
 * a.ld-item-name:hover { color: #00559b !important }`. That is (0,5,1)
 * AND !important AND last in the document, so it can only be beaten by
 * a more specific important declaration. Hence the long chain below
 * (0,7,1) plus !important. Same fight as the "Purchase this Course"
 * button earlier in this project — if a LearnDash colour refuses to
 * change, look for that inline block before assuming the selector is
 * wrong. */
.ksa-page-section .ksa-course-content .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name:hover,
.ksa-page-section .ksa-course-content .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name:hover .ld-item-title {
  color: var(--cta-active) !important;
}

/* "Overview" / "Learning Objectives" paired into 2 columns by
   ksa_extract_learndash_blocks() (functions.php) — only when a course
   actually has both; everything else stays single-column. */

.ksa-page-section .ksa-course-content > .learndash .ld-tabs {
  margin-top: 0;
  padding-top: 0;
}

.ksa-page-section .ksa-course-video {
  margin: 0 0 var(--sp-6);
}

.ksa-page-section .ksa-course-video iframe {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 0;
}

.ksa-course-content__columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: var(--sp-7);
  margin-bottom: var(--sp-6);
}

.ksa-course-content__col {
  display: flex;
  flex-direction: column;
}

/* LearnDash's own ld30 CSS puts a 36px margin-top on the curriculum
   list wrapper (.ld-item-list.ld-lesson-list) — meant for when it
   follows other page content in the default single-column template.
   Here it's the first (only) thing in its column, so that margin just
   pushed "Course Content" below "Overview"'s top edge instead of
   lining the two headings up. !important for the usual reason: it's
   LearnDash's own rule, loaded after this file. */
.ksa-page-section .ksa-course-content .ld-item-list.ld-lesson-list {
  margin-top: 0 !important;
}

/* Course category "eyebrow" above the H1 — see
   ksa_get_course_category_label() in functions.php. */
.ksa-page-hero .ksa-page-hero__eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-on-dark-muted);
  margin: 0 0 var(--sp-3);
}

/* The certificate alert + status/progress bar, pulled out of
   the_content()'s filtered output and placed in their own section at
   the bottom of the page — see ksa_extract_learndash_blocks(). Both
   are LearnDash's own components (ld30 theme), already designed for a
   plain white/light background, so — unlike the first version of this
   template, which placed them in the dark hero and needed heavy
   !important overrides just to stay legible — barely anything needs
   overriding here. Just enough to give the pair consistent spacing as
   a group. */
.ksa-course-ld-blocks {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.ksa-course-ld-block .ld-course-status,
.ksa-course-ld-block .ld-alert {
  margin: 0 !important;
}

@media (max-width: 900px) {
  .ksa-course-content__columns {
    grid-template-columns: 1fr;
    gap: var(--sp-5);
  }
}

/* ============================================================
   LearnDash course pages — single-sfwd-courses.php
   ============================================================ */

/* White instead of the sitewide default orange — establishes a
   hierarchy with the lesson hero below it: course (white, the full H1
   size) reads as the bigger, containing level; lesson (white, stepped
   down to H2) reads as the smaller thing nested under it. Scoped to
   .ksa-course-hero so every other page keeps the normal orange H1. */
.ksa-course-hero .ksa-page-hero__title {
  color: var(--fg-on-dark);
}

/* Category eyebrow orange, matching the lesson hero — the two now read
   as one family. Safe on the navy hero: #E07D2C on #011F41 is 5.61:1,
   passes WCAG AA. (That is NOT true of orange text on white — see the
   note on the curriculum hover further down.) */
.ksa-course-hero .ksa-page-hero__eyebrow {
  color: var(--cta);
}

/* ============================================================
   LearnDash lesson pages — single-sfwd-lessons.php
   See ksa_extract_lesson_blocks() (functions.php) for how the video
   and the breadcrumb/status bar are pulled out of the_content().
   Header uses the same ksa_course_artwork() banner as the course page
   (single-course.php), passing the lesson's own title through instead
   of the linked course's, so course and lesson headers read as one
   family instead of two different designs.
   ============================================================ */

/* Positioning context for the back-link below. */
.ksa-lesson-art-wrap {
  position: relative;
}

/* A small "Back to course" link over the artwork's corner. Colours are
   dark-on-light — this banner is a light category tint, the opposite
   of the old dark-navy lesson hero it replaces. */
.ksa-lesson-art-back {
  position: absolute;
  right: var(--sp-5);
  bottom: var(--sp-4);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
  text-decoration: none;
}

.ksa-lesson-art-back:hover {
  color: var(--art-accent);
}

.ksa-page-section .ksa-lesson-content h2,
.ksa-page-section .ksa-lesson-content h3 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
  margin: var(--sp-7) 0 var(--sp-4);
}

.ksa-page-section .ksa-lesson-content h2:first-child,
.ksa-page-section .ksa-lesson-content h3:first-child {
  margin-top: 0;
}

.ksa-page-section .ksa-lesson-content p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-lesson-content ul {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-5);
  color: var(--fg);
}

.ksa-page-section .ksa-lesson-content li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  margin-bottom: var(--sp-2);
}

.ksa-page-section .ksa-lesson-content strong {
  font-weight: var(--fw-bold);
  color: var(--fg);
}

.ksa-page-section .ksa-lesson-content a {
  color: var(--link);
  text-decoration: underline;
}

.ksa-page-section .ksa-lesson-content a:hover {
  color: var(--link-hover);
}

.ksa-page-section .ksa-lesson-content iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  margin-bottom: var(--sp-6);
}

/* Previous/Mark Complete/Back to Course/Next Lesson — sits directly
   under the writing on the same white background now, at the same
   content width, rather than in a separate tinted section (the
   breadcrumb/status bar it used to be grouped with is gone; a lone
   block didn't need its own section). */
.ksa-lesson-actions {
  margin-top: var(--sp-6);
}

html body {
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
}

html h1, html h2, html h3, html h4, html h5, html h6 {
  font-family: var(--font-condensed);
  color: var(--fg);
}

.ksa-404__code {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: 96px;
  line-height: 1;
  color: var(--cta);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-404__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-404__text {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-404__search {
  margin: var(--sp-5) 0;
  max-width: 480px;
}

.ksa-404__links {
  font-size: var(--type-body-size);
  margin: var(--sp-5) 0 0;
}

.ksa-404__links a {
  color: var(--link);
  text-decoration: underline;
}

.ksa-404__links a:hover {
  color: var(--link-hover);
}

/* ============================================================
   Generic page content — page.php and page-my-account.php
   Author-written HTML whose shape we don't control (legal pages, and
   WooCommerce's own account output), so it's styled by element rather
   than by class. Deliberately restrained: this is a readable default,
   not a design.
   ============================================================ */

/* Text/column split for page.php only — 3/4 text, 1/4 aside. The aside
   is empty today (Lara fills it in per-page later); it just reserves
   the column so the text stops running full-width. Not used by
   page-my-account.php, which has no aside markup and stays full-width. */
.ksa-page-content-grid {
  display: grid;
  grid-template-columns: 3fr 1fr;
  gap: var(--sp-8);
  align-items: start;
}

@media (max-width: 768px) {
  .ksa-page-content-grid {
    grid-template-columns: 1fr;
  }
}

/* Page title on the white background, dark navy — no navy hero band. */
.ksa-page-section .ksa-page-title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-6);
}

/* Blog post featured image — sits between the title and the content,
   same rounded treatment as photos elsewhere on the site. */
.ksa-page-section .ksa-single-post__thumbnail {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  margin: 0 0 var(--sp-6);
}

/* Heading scale for author-written content. Deliberately covers h2-h4,
   because these pages do NOT start at h2: Terms and Privacy use <h3>
   for every section heading and Refund Policy uses <h4>. Sized so the
   hierarchy holds whichever level a page happens to start at:
   title 45 > h2 35 > h3 24 > h4 20 > body 18.

   h4 used to be a hardcoded 20px here because --type-h4-size itself was
   18px (identical to body). The token now carries the real 20px value
   (colors_and_type.css), so this rule uses it directly like h2 and h3 do. */
.ksa-page-section .ksa-page-content h2,
.ksa-page-section .ksa-account__content h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
  margin: var(--sp-7) 0 var(--sp-4);
}

.ksa-page-section .ksa-page-content h2:first-child,
.ksa-page-section .ksa-account__content h2:first-child,
.ksa-page-section .ksa-page-content h3:first-child,
.ksa-page-section .ksa-account__content h3:first-child {
  margin-top: 0;
}

.ksa-page-section .ksa-page-content h3,
.ksa-page-section .ksa-account__content h3 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  color: var(--fg);
  margin: var(--sp-6) 0 var(--sp-3);
}

.ksa-page-section .ksa-page-content h4,
.ksa-page-section .ksa-account__content h4 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  line-height: var(--type-h4-lh);
  color: var(--fg);
  margin: var(--sp-5) 0 var(--sp-3);
}

.ksa-page-section .ksa-page-content p,
.ksa-page-section .ksa-account__content p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-page-content ul,
.ksa-page-section .ksa-page-content ol,
.ksa-page-section .ksa-account__content ul,
.ksa-page-section .ksa-account__content ol {
  margin: 0 0 var(--sp-4) var(--sp-5);
  padding: 0;
}

.ksa-page-section .ksa-page-content li,
.ksa-page-section .ksa-account__content li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin-bottom: var(--sp-2);
}

.ksa-page-section .ksa-page-content a,
.ksa-page-section .ksa-account__content a {
  color: var(--link);
  text-decoration: underline;
}

.ksa-page-section .ksa-page-content a:hover,
.ksa-page-section .ksa-account__content a:hover {
  color: var(--link-hover);
}

/* The account page's photo sits above the account area rather than
   floating beside it — a plain stacked default, matching the decision
   to leave WooCommerce's own output unstyled for now. */
.ksa-account__photo {
  margin: 0 0 var(--sp-6);
}

.ksa-account__photo img {
  max-width: 286px;
  height: auto;
  border-radius: var(--radius-sm);
}

.ksa-page-section .ksa-shop__header {
  margin: 0 0 var(--sp-6);
}

.ksa-page-section .ksa-shop__eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-shop__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-shop__desc {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  max-width: 820px;
}

/* Result count (left) + ordering select (right). WooCommerce's own
   markup, styled via its existing classes rather than rewritten. */
.ksa-page-section .ksa-shop__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding-bottom: var(--sp-4);
  margin-bottom: var(--sp-6);
  border-bottom: 1px solid var(--border);
}

.ksa-page-section .ksa-shop__toolbar .woocommerce-result-count {
  font-size: var(--type-small-size);
  color: var(--fg-muted);
  margin: 0;
}

.ksa-page-section .ksa-shop__toolbar .orderby {
  font-family: var(--font-sans);
  font-size: var(--type-small-size);
  color: var(--fg);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--ksa-white);
}

.ksa-page-section .ksa-shop__empty {
  font-size: var(--type-body-size);
  color: var(--fg);
}

/* Pagination — woocommerce_pagination() output */
.ksa-page-section .woocommerce-pagination {
  margin-top: var(--sp-7);
}

.ksa-page-section .woocommerce-pagination ul.page-numbers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
  border: 0;
}

.ksa-page-section .woocommerce-pagination ul.page-numbers li {
  border: 0;
  margin: 0;
}

/* Scoped to `li .page-numbers`, NOT a bare `.page-numbers`: WooCommerce
   puts class="page-numbers" on the <ul> container as well as on each
   link/span inside it. A bare selector therefore styles the list itself
   as if it were a button — and its :hover painted the entire full-width
   bar orange whenever the cursor passed over the pagination. */
.ksa-page-section .woocommerce-pagination li .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding: 0 var(--sp-3);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--fg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color 200ms ease-out, border-color 200ms ease-out, color 200ms ease-out;
}

.ksa-page-section .woocommerce-pagination li a.page-numbers:hover,
.ksa-page-section .woocommerce-pagination li .page-numbers.current {
  background: var(--cta);
  border-color: var(--cta);
  color: var(--cta-text);
}

.ksa-page-section .woocommerce-pagination li .page-numbers:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* ---- Page header: category / title / short description ----
   On the white page background above Overview, NOT in the sitewide navy
   hero band (removed from this template Aug 6, 2026). Its own classes
   rather than .ksa-page-hero's, which are written light-on-dark and
   would need overriding property by property.

   Lives INSIDE the left column, so it takes the Overview column's width
   automatically (no max-width of its own) and the purchase card sits
   level with the top of the page instead of starting below the title.

   Title is dark navy here, not the sitewide orange H1 — this page puts
   its accent on the eyebrow and the purchase card instead, and an
   orange H1 at this size competed with the Add to Cart button for
   attention. */

.ksa-page-section .ksa-product__header {
  margin: 0 0 var(--sp-7);
}

.ksa-page-section .ksa-product__eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-product__title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-product__lede {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg-muted);
  margin: 0;
}

.ksa-page-section .ksa-product__columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: var(--sp-8);
  align-items: start;
}

/* ---- Left column: video + Overview + Learning Objectives ---- */

/* Both blocks are author-written HTML (post_content and an ACF
   textarea), so they're styled by element rather than by class — there
   are no hooks to target inside them. */
.ksa-page-section .ksa-product__content h2,
.ksa-page-section .ksa-product__objectives h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-product__content p,
.ksa-page-section .ksa-product__objectives p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

.ksa-page-section .ksa-product__content p:last-child,
.ksa-page-section .ksa-product__objectives p:last-child {
  margin-bottom: 0;
}

.ksa-page-section .ksa-product__objectives {
  margin-top: var(--sp-7);
}

.ksa-page-section .ksa-product__objectives ul {
  margin: 0;
  padding-left: var(--sp-5);
  list-style: disc;
}

.ksa-page-section .ksa-product__objectives li {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin-bottom: var(--sp-2);
}

.ksa-page-section .ksa-product__objectives li:last-child {
  margin-bottom: 0;
}

/* Course Content list only (not Learning Objectives, which keeps plain
   bullets) — a two-column grid of module cards instead of a bare bullet
   list: a blue "MODULE 0X" eyebrow (optionally suffixed "· STEP N" when
   single-product.php parses that off the LearnDash lesson title) above
   a bold navy title, on a light-grey card. Stacks to one column below
   560px, the same breakpoint already used elsewhere in this file. */
.ksa-page-section .ksa-product__course-content-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}

.ksa-page-section .ksa-product__module-card {
  padding: var(--sp-4) var(--sp-5);
  background: var(--bg);
  border: 1px solid var(--ksa-grey-4);
  border-radius: var(--radius-md);
}

.ksa-page-section .ksa-product__module-card-eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-2);
}

.ksa-page-section .ksa-product__module-card-title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  line-height: var(--type-h4-lh);
  color: var(--fg);
  margin: 0;
}

@media (max-width: 560px) {
  .ksa-page-section .ksa-product__course-content-grid {
    grid-template-columns: 1fr;
  }
}

/* The long description opens with a bare Vimeo URL that WordPress
   auto-embeds — same situation as the lesson template: a raw iframe
   carrying hardcoded width/height attributes, which overflows on
   anything narrower without this. */
.ksa-page-section .ksa-product__content iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  margin-bottom: var(--sp-6);
  border: 0;
}

/* ---- Right column: the purchase card ---- */

/* Sticky so the price and buy button stay reachable while reading a
   long objectives list. Falls back to normal flow where position:sticky
   has nothing to stick within (the stacked mobile layout below). */
.ksa-page-section .ksa-product__buy {
  position: sticky;
  top: var(--sp-5);
}

.ksa-page-section .ksa-product__buy-card {
  background: var(--bg-raised);
  border: 1px solid var(--ksa-grey-4);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--sp-5);
}

.ksa-page-section .ksa-product__buy-image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  margin-bottom: var(--sp-5);
}

.ksa-page-section .ksa-product__buy-price {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

/* The CPD field ships its own <h2>Verifiable CPD</h2> followed by a
   bare line ("1.0 hour"). Inside the card that heading is a label, not
   a section heading — knocked down to caps-label scale so it doesn't
   compete with the price above it. */
.ksa-page-section .ksa-product__buy-hours {
  border-top: 1px solid var(--ksa-grey-4);
  padding-top: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.ksa-page-section .ksa-product__buy-hours h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 var(--sp-1);
}

.ksa-page-section .ksa-product__buy-hours p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0;
}

/* ---- Add to cart ----
   WooCommerce's own form markup (button.single_add_to_cart_button +
   an optional quantity input), restyled to the site's CTA language —
   same visual as .ksa-pill-btn, but full width since it's the single
   most important control on the page. Quantity only renders for the 3
   products that aren't sold_individually. */
.ksa-page-section .ksa-product__buy-cart form.cart {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  margin: 0;
}

.ksa-page-section .ksa-product__buy-cart .quantity {
  flex: 0 0 auto;
}

/* Spacing between quantity and button is a margin on the input, NOT a
   `gap` on the form. The 25 sold_individually products still render a
   .quantity wrapper — WooCommerce just puts an <input type="hidden">
   inside it rather than a number field, and gives the wrapper no
   "hidden" class. That wrapper is a real flex item of zero width, so a
   form-level `gap` still applied and shunted the Add to Cart button
   12px right of the price and CPD line above it (measured on staging:
   button at x=933, card content at x=921). A hidden input has no box,
   so hanging the spacing off the visible number field instead means it
   simply doesn't exist on those products. */
.ksa-page-section .ksa-product__buy-cart .quantity input.qty[type="number"] {
  margin-right: var(--sp-3);
}

.ksa-page-section .ksa-product__buy-cart .quantity input.qty {
  width: 72px;
  height: 100%;
  min-height: 48px;
  padding: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
  text-align: center;
  border: 1px solid var(--ksa-grey-3);
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
}

.ksa-page-section .ksa-product__buy-cart button.single_add_to_cart_button {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: var(--cta);
  color: var(--cta-text);
  padding: var(--sp-3) var(--sp-5);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color 200ms ease-out;
}

.ksa-page-section .ksa-product__buy-cart button.single_add_to_cart_button:hover {
  background: var(--cta-hover);
}

.ksa-page-section .ksa-product__buy-cart button.single_add_to_cart_button:active {
  background: var(--cta-active);
}

.ksa-page-section .ksa-product__buy-cart button.single_add_to_cart_button:focus-visible,
.ksa-page-section .ksa-product__buy-cart .quantity input.qty:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* WooCommerce adds .loading during the AJAX add — its own stylesheet
   normally supplies a spinner, but that lives in the WC frontend CSS
   which isn't guaranteed to be styling this custom form. A simple
   dimmed, non-interactive state reads correctly on its own. */
.ksa-page-section .ksa-product__buy-cart button.single_add_to_cart_button.loading {
  opacity: 0.6;
  pointer-events: none;
}

/* ---- Back link ---- */

.ksa-page-section .ksa-product__back {
  margin: var(--sp-8) 0 0;
  font-size: var(--type-body-size);
}

/* ---- Responsive ---- */

@media (max-width: 900px) {
  .ksa-page-section .ksa-product__columns {
    grid-template-columns: 1fr;
    gap: var(--sp-7);
  }

  /* Card first on narrow screens: price and buy button above the long
     read, rather than stranded below several screens of objectives. */
  .ksa-page-section .ksa-product__buy {
    position: static;
    order: -1;
  }
}

/* ---- Shared button treatment ----
   .button.alt / #place_order / .checkout-button are Woo's PRIMARY
   actions; plain .button is its secondary (Update cart, Apply coupon).
   Matches .ksa-pill-btn so a Woo button and a KSA button next to each
   other read as the same control. */

.ksa-woo-page .woocommerce a.button,
.ksa-woo-page .woocommerce button.button,
.ksa-woo-page .woocommerce input.button,
.ksa-account .woocommerce a.button,
.ksa-account .woocommerce button.button,
.ksa-account .woocommerce input.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--sp-3) var(--sp-5);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-decoration: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color 200ms ease-out, color 200ms ease-out, border-color 200ms ease-out;
  /* Secondary by default — outlined, not filled. The primary rule
     below re-fills the ones that deserve it. */
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--border-strong);
}

.ksa-woo-page .woocommerce a.button:hover,
.ksa-woo-page .woocommerce button.button:hover,
.ksa-woo-page .woocommerce input.button:hover,
.ksa-account .woocommerce a.button:hover,
.ksa-account .woocommerce button.button:hover {
  border-color: var(--cta);
  background: transparent;
  color: var(--fg);
}

/* Primary: the actions that move money forward.
   SPECIFICITY NOTE — these carry the extra `.woocommerce` ancestor on
   purpose. WooCommerce's own rule is
   `.woocommerce:where(body:not(...)) a.button.alt`, and `:where()`
   contributes ZERO specificity, so that resolves to (0,3,1) — which
   beat the obvious `.ksa-woo-page .button.alt` (0,3,0) and left
   "Proceed to checkout" rendering in Woo purple. Adding `.woocommerce`
   (a real ancestor of all Woo shortcode output — verified in the DOM,
   not assumed) makes these (0,4,1) and wins honestly, without
   !important. */
.ksa-woo-page .woocommerce a.button.alt,
.ksa-woo-page .woocommerce button.button.alt,
.ksa-woo-page .woocommerce input.button.alt,
.ksa-woo-page .woocommerce a.checkout-button,
.ksa-woo-page .woocommerce #place_order,
.ksa-account .woocommerce a.button.alt,
.ksa-account .woocommerce button.woocommerce-Button {
  background: var(--cta);
  color: var(--cta-text);
  border-color: var(--cta);
}

.ksa-woo-page .woocommerce a.button.alt:hover,
.ksa-woo-page .woocommerce button.button.alt:hover,
.ksa-woo-page .woocommerce input.button.alt:hover,
.ksa-woo-page .woocommerce a.checkout-button:hover,
.ksa-woo-page .woocommerce #place_order:hover,
.ksa-account .woocommerce a.button.alt:hover,
.ksa-account .woocommerce button.woocommerce-Button:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  color: var(--cta-text);
}

.ksa-woo-page .woocommerce a.button.alt:active,
.ksa-woo-page .woocommerce button.button.alt:active,
.ksa-woo-page .woocommerce a.checkout-button:active,
.ksa-woo-page .woocommerce #place_order:active {
  background: var(--cta-active);
  border-color: var(--cta-active);
}

/* Disabled. "Update cart" ships disabled until a quantity actually
   changes, so this state is on screen most of the time — it has to
   look deliberately unavailable rather than like a faded primary.
   Secondary buttons stay outlined and go grey; only a disabled
   PRIMARY uses the muted-orange fill (rule below), because that one
   is still the page's main action, just not ready yet. */
.ksa-woo-page .woocommerce a.button.disabled,
.ksa-woo-page .woocommerce button.button.disabled,
.ksa-woo-page .woocommerce button.button:disabled,
.ksa-woo-page .woocommerce input.button:disabled {
  background: transparent;
  border-color: var(--border);
  color: var(--fg-subtle);
  cursor: not-allowed;
}

.ksa-woo-page .woocommerce a.button.alt.disabled,
.ksa-woo-page .woocommerce button.button.alt.disabled,
.ksa-woo-page .woocommerce button.button.alt:disabled,
.ksa-woo-page .woocommerce input.button.alt:disabled {
  background: var(--cta-disabled);
  border-color: var(--cta-disabled);
  color: var(--cta-text);
}

.ksa-woo-page .button:focus-visible,
.ksa-woo-page button.button:focus-visible,
.ksa-woo-page a:focus-visible,
.ksa-woo-page input:focus-visible,
.ksa-woo-page select:focus-visible,
.ksa-woo-page textarea:focus-visible,
.ksa-account .button:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* "Proceed to checkout" is the one control the whole cart page exists
   to serve — full width of its column, not a small inline pill. */
.ksa-woo-page .woocommerce .wc-proceed-to-checkout a.checkout-button {
  display: flex;
  width: 100%;
  min-height: 52px;
  margin: 0;
}

/* The account area's own submit buttons. Woo doesn't mark any of
   these `.alt`, so without this they'd all render as outlined
   secondaries — including "Log in", which is the entire point of the
   logged-out account page. Named individually rather than styling
   every `button.button` inside .ksa-account as primary, because the
   account screens also carry genuine secondary actions. */
.ksa-account .woocommerce button.woocommerce-form-login__submit,
.ksa-account .woocommerce button.woocommerce-form-register__submit,
.ksa-account .woocommerce button[name="save_account_details"],
.ksa-account .woocommerce button[name="save_address"] {
  background: var(--cta);
  color: var(--cta-text);
  border-color: var(--cta);
}

.ksa-account .woocommerce button.woocommerce-form-login__submit:hover,
.ksa-account .woocommerce button.woocommerce-form-register__submit:hover,
.ksa-account .woocommerce button[name="save_account_details"]:hover,
.ksa-account .woocommerce button[name="save_address"]:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  color: var(--cta-text);
}

/* ---- Links inside Woo output ---- */

.ksa-woo-page a:not(.button):not(.remove) {
  color: var(--link);
  text-decoration: underline;
}

.ksa-woo-page a:not(.button):not(.remove):hover {
  color: var(--link-hover);
}

/* Product names in the cart table read as content, not as links to
   chase — Woo's stock #AA0000 red made them the loudest thing on the
   page. Undecorated navy until hover.
   Needs the `.shop_table` ancestor to reach (0,3,1): the generic link
   rule above is `a:not(.button):not(.remove)`, and each :not() counts
   its argument's specificity, so that rule is already (0,3,1) — a
   plain `.ksa-woo-page .product-name a` (0,2,1) lost to my own rule
   and the names came out link-blue and underlined. */
.ksa-woo-page .shop_table .product-name a {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  text-decoration: none;
}

.ksa-woo-page .shop_table .product-name a:hover {
  color: var(--link);
  text-decoration: underline;
}

/* The "×" remove control. Woo ships it red and tiny; this keeps the
   destructive colour meaningful but gives it a real hit area.
   `!important` on colour ONLY, and only because WooCommerce itself
   declares `.woocommerce a.remove { color: var(--wc-red) !important }`
   — an important declaration can only be beaten by another important
   one, no amount of extra specificity helps. Every other property
   here wins on the cascade normally. */
.ksa-woo-page .woocommerce a.remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  font-size: 22px;
  line-height: 1;
  color: var(--fg-subtle) !important;
  text-decoration: none;
  transition: background-color 200ms ease-out, color 200ms ease-out;
}

.ksa-woo-page .woocommerce a.remove:hover {
  background: var(--error-bg);
  color: var(--error-text) !important;
}

/* ---- Tables (cart contents, cart totals, order review) ---- */

.ksa-woo-page table.shop_table {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
}

.ksa-woo-page table.shop_table th {
  padding: var(--sp-4);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg);
  text-align: left;
  border-bottom: 1px solid var(--border);
}

/* Tint only real COLUMN headers. The cart-totals and order-review
   tables use <th> for ROW labels (Subtotal / GST / Total), so tinting
   every th striped those tables horizontally — grey label cell, white
   value cell, on every row. */
.ksa-woo-page table.shop_table thead th {
  background: var(--ksa-grey-5);
}

/* Column headers sized to the "Cart totals" heading beside them.
   At --type-small-size they were SMALLER than the 18px product names
   in the rows below, so the header read as subordinate to its own
   data. Sentence case rather than small caps for the same reason
   "Cart totals" is: it's a heading, and headings on this site are not
   shouted. Scoped to thead so the totals table's ROW labels
   (Subtotal / GST / Total) keep their 14px caps. */
.ksa-woo-page table.shop_table thead th {
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  text-transform: none;
  letter-spacing: 0;
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
}

.ksa-woo-page table.shop_table td {
  padding: var(--sp-4);
  font-size: var(--type-body-size);
  color: var(--fg);
  border-top: 1px solid var(--border);
  vertical-align: middle;
}

.ksa-woo-page table.shop_table tbody tr:first-child td {
  border-top: 0;
}

/* Cart totals: the grand total is the number people actually look
   for, so it gets weight the subtotal and GST rows don't.
   Sentence case, not the small caps the 14px SUBTOTAL / GST labels
   use. At 24px it shares a tier with "Cart totals" and the table's
   column headers, and those are sentence case — an uppercase "TOTAL"
   was the only shouted thing at that size. */
.ksa-woo-page .cart_totals .order-total th,
.ksa-woo-page .cart_totals .order-total td,
.ksa-woo-page .woocommerce-checkout-review-order-table .order-total th,
.ksa-woo-page .woocommerce-checkout-review-order-table .order-total td {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  text-transform: none;
  letter-spacing: 0;
  background: var(--ksa-grey-5);
}

.ksa-woo-page .cart_totals h2,
.ksa-woo-page .cart-collaterals h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

/* ---- Form fields (coupon, billing, account) ----
   .thwcfd-* wrappers come from the Checkout Field Editor plugin, which
   owns the real field set — styling the inputs by element inside the
   scoped ancestors covers its fields and Woo's identically. */

.ksa-woo-page input[type="text"],
.ksa-woo-page input[type="email"],
.ksa-woo-page input[type="tel"],
.ksa-woo-page input[type="password"],
.ksa-woo-page input[type="number"],
.ksa-woo-page textarea,
.ksa-woo-page select,
.ksa-account input[type="text"],
.ksa-account input[type="email"],
.ksa-account input[type="tel"],
.ksa-account input[type="password"],
.ksa-account textarea,
.ksa-account select {
  width: 100%;
  min-height: 44px;
  padding: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

/* Checkout's own fields need the extra ancestors: WooCommerce styles
   them through `.woocommerce form .form-row .input-text` (0,3,1),
   which beat the attribute-selector rule above (0,2,1) and left the
   billing inputs on Woo's own border colour. Same border treatment,
   just stated at a weight that wins. */
.ksa-woo-page .woocommerce form .form-row .input-text,
.ksa-woo-page .woocommerce form .form-row select,
.ksa-woo-page .woocommerce form .form-row textarea,
.ksa-account .woocommerce form .form-row .input-text,
.ksa-account .woocommerce form .form-row select,
.ksa-account .woocommerce form .form-row textarea {
  min-height: 44px;
  padding: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

/* Country / Region and Province are select2 widgets, not native
   selects — WooCommerce enhances them, and the real <select> is
   collapsed to 1px while `.select2-selection` is what the customer
   actually sees. Styling only the <select> left these two fields
   visibly different from every other input on the form. */
.ksa-woo-page .select2-container--default .select2-selection--single {
  height: 44px;
  padding: 0 var(--sp-3);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.ksa-woo-page .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  line-height: 42px;
  color: var(--fg);
}

.ksa-woo-page .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 42px;
}

/* The open dropdown is appended to <body>, outside .ksa-woo-page, so
   it can't be scoped the same way. `.select2-*` is specific enough to
   this plugin that unscoped rules are safe — select2 is only loaded
   for these WooCommerce fields on this site. */
.select2-dropdown {
  border-color: var(--border-strong);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
}

.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted[data-selected] {
  background: var(--accent);
  color: var(--fg-on-dark);
}

.ksa-woo-page input::placeholder,
.ksa-account input::placeholder {
  color: var(--fg-subtle);
}

.ksa-woo-page label,
.ksa-account label {
  display: inline-block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--type-small-size);
  font-weight: var(--fw-medium);
  color: var(--fg-muted);
}

.ksa-woo-page .form-row {
  margin-bottom: var(--sp-4);
}

/* Checkboxes must not inherit the full-width input rule above. */
.ksa-woo-page input[type="checkbox"],
.ksa-woo-page input[type="radio"],
.ksa-account input[type="checkbox"],
.ksa-account input[type="radio"] {
  width: auto;
  min-height: 0;
}

/* Coupon row: input and button on one line rather than stacked. */
.ksa-woo-page .coupon {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
}

.ksa-woo-page .coupon #coupon_code {
  width: auto;
  min-width: 200px;
  flex: 0 1 auto;
}

/* ---- Checkout section headings ---- */

.ksa-woo-page h3,
.ksa-woo-page #order_review_heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
  margin: var(--sp-7) 0 var(--sp-4);
}

.ksa-woo-page h3:first-child {
  margin-top: 0;
}

/* ---- WooCommerce notices ----
   The "You cannot add another X to your cart" / "Product added" /
   "Have a coupon?" strips. WooCommerce calls these notices: error,
   message (its word for success) and info.

   Deliberately NOT scoped to .ksa-woo-page. They were, and that only
   covered cart and checkout — so the same notice on a product page,
   the shop archive or My Account still rendered in WooCommerce's stock
   grey-with-a-coloured-top-rule. Notices can surface almost anywhere
   Woo runs, so the treatment has to be global to be consistent.
   `.woocommerce-error` and friends are specific enough to Woo that an
   unscoped selector is safe here.

   Woo emits errors as <ul> and the others as <div>, hence list-style
   and the zeroed padding-left. */
.woocommerce-info,
.woocommerce-message,
.woocommerce-error {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4);
  margin: 0 0 var(--sp-5);
  border: 0;
  border-left: 4px solid;
  border-radius: var(--radius-md);
  list-style: none;
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
}

/* WooCommerce puts an icon-font glyph on these via ::before. The
   "WooCommerce" webfont isn't resolving on this install, so it
   rendered as a tofu box sitting on top of the first word
   ("R□eturning customer?"). The coloured left border already carries
   the same meaning, so the glyph is redundant as well as broken. */
.woocommerce-info::before,
.woocommerce-message::before,
.woocommerce-error::before {
  content: none;
}

.woocommerce-info li,
.woocommerce-message li,
.woocommerce-error li {
  list-style: none;
  margin: 0;
}

.woocommerce-info {
  background: var(--info-bg);
  border-left-color: var(--info-border);
  color: var(--info-text);
}

.woocommerce-message {
  background: var(--success-bg);
  border-left-color: var(--success-border);
  color: var(--success-text);
}

.woocommerce-error {
  background: var(--error-bg);
  border-left-color: var(--error-border);
  color: var(--error-text);
}

/* Links inside a notice inherit the notice's own colour rather than
   going link-blue, which read as a third colour in an already
   coloured strip. */
.woocommerce-info a:not(.button),
.woocommerce-message a:not(.button),
.woocommerce-error a:not(.button) {
  color: inherit;
  text-decoration: underline;
}

/* The inline action ("View cart", "Continue shopping"). Woo floats it
   right; the flex row above places it instead, so the float is
   cleared. Same orange pill as every other primary action.
   Qualified with `a.button` plus a wrapper so these reach (0,3,1) —
   Woo styles the same element through `.woocommerce a.button` at
   (0,2,1), and a plain `.woocommerce-error .button` (0,2,0) lost to
   it, leaving the button in Woo's grey-lavender. */
.woocommerce-notices-wrapper .woocommerce-info a.button,
.woocommerce-notices-wrapper .woocommerce-message a.button,
.woocommerce-notices-wrapper .woocommerce-error a.button,
.ksa-woo-page .woocommerce-info a.button,
.ksa-woo-page .woocommerce-message a.button,
.ksa-woo-page .woocommerce-error a.button {
  float: none;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: var(--sp-2) var(--sp-5);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-decoration: none;
  background: var(--cta);
  color: var(--cta-text);
  border: 1px solid var(--cta);
  border-radius: var(--radius-pill);
  transition: background-color 200ms ease-out, border-color 200ms ease-out;
}

.woocommerce-notices-wrapper .woocommerce-info a.button:hover,
.woocommerce-notices-wrapper .woocommerce-message a.button:hover,
.woocommerce-notices-wrapper .woocommerce-error a.button:hover,
.ksa-woo-page .woocommerce-info a.button:hover,
.ksa-woo-page .woocommerce-message a.button:hover,
.ksa-woo-page .woocommerce-error a.button:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  color: var(--cta-text);
}

.woocommerce-notices-wrapper .woocommerce-info a.button:focus-visible,
.woocommerce-notices-wrapper .woocommerce-message a.button:focus-visible,
.woocommerce-notices-wrapper .woocommerce-error a.button:focus-visible,
.ksa-woo-page .woocommerce-info a.button:focus-visible,
.ksa-woo-page .woocommerce-message a.button:focus-visible,
.ksa-woo-page .woocommerce-error a.button:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* Woo prints the wrapper on every page whether or not there is
   anything in it; an empty one would otherwise add a stray gap. */
.woocommerce-notices-wrapper:empty {
  display: none;
}

/* ---- My Account navigation ---- */

.ksa-account .woocommerce-MyAccount-navigation ul {
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
}

.ksa-account .woocommerce-MyAccount-navigation-link a {
  display: block;
  padding: var(--sp-3) var(--sp-4);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--fg);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}

.ksa-account .woocommerce-MyAccount-navigation-link a:hover {
  background: var(--ksa-grey-5);
  color: var(--link);
}

.ksa-account .woocommerce-MyAccount-navigation-link.is-active a {
  border-bottom-color: var(--cta);
  background: var(--ksa-grey-5);
}

/* ============================================================
   Mini-cart drawer — WooCommerce BLOCKS, not the classic cart.
   Separate stylesheets (mini-cart.css / wc-blocks.css) and a
   completely different class vocabulary, so none of the rules above
   reach it. The drawer markup is server-rendered as an interactivity-
   API template and hydrated client-side; these are the real class
   names from that markup.
   ============================================================ */

.wc-block-mini-cart__drawer .wc-block-mini-cart__title,
.wc-block-mini-cart__drawer .wc-block-mini-cart__title * {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-components-product-name {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
  text-decoration: none;
}

.wc-block-mini-cart__drawer .wc-block-components-product-name:hover {
  color: var(--link);
  text-decoration: underline;
}

/* The product short description. Same size as the PD page's course-card
   description so the drawer and the card it came from agree. Navy, not
   the muted grey it used to be — every body string on the site is --fg,
   and grey here was the one exception. */
.wc-block-mini-cart__drawer .wc-block-components-product-metadata__description {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-components-product-price,
.wc-block-mini-cart__drawer .wc-block-components-product-price__value {
  font-family: var(--font-sans);
  font-weight: var(--fw-medium);
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-cart-item__remove-link {
  color: var(--fg-subtle);
  text-decoration: none;
}

.wc-block-mini-cart__drawer .wc-block-cart-item__remove-link:hover {
  color: var(--error-text);
}

.wc-block-mini-cart__drawer .wc-block-components-totals-item__label {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-components-totals-item__value {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-components-totals-item__description {
  font-size: var(--type-small-size);
  color: var(--fg-muted);
}

/* Drawer footer buttons. "Go to checkout" is the primary action and
   was rendering as bare pink text; "View my cart" carries Woo's
   is-style-outline and stays secondary. Both are <a> elements, so
   they need display/alignment set explicitly. */
.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-actions .wc-block-components-button,
.wc-block-mini-cart__drawer .wc-block-mini-cart__shopping-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: var(--sp-3) var(--sp-5);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-decoration: none;
  border-radius: var(--radius-pill);
  transition: background-color 200ms ease-out, border-color 200ms ease-out;
}

.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-checkout,
.wc-block-mini-cart__drawer .wc-block-mini-cart__shopping-button {
  background: var(--cta);
  color: var(--cta-text);
  border: 1px solid var(--cta);
}

.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-checkout:hover,
.wc-block-mini-cart__drawer .wc-block-mini-cart__shopping-button:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  color: var(--cta-text);
}

.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-cart,
.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-cart.is-style-outline {
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--border-strong);
}

.wc-block-mini-cart__drawer .wc-block-mini-cart__footer-cart:hover {
  border-color: var(--cta);
  background: transparent;
  color: var(--fg);
}

.wc-block-mini-cart__drawer .wc-block-components-button:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

/* ---- Responsive ---- */

@media (max-width: 768px) {
  .ksa-woo-page .coupon {
    flex-direction: column;
    align-items: stretch;
  }

  .ksa-woo-page .coupon #coupon_code,
  .ksa-woo-page .coupon .button {
    width: 100%;
  }

  .ksa-woo-page table.shop_table th,
  .ksa-woo-page table.shop_table td {
    padding: var(--sp-3);
  }
}

/* .ksa-home-testimonials now sits on every page's testimonial deck
   (home, About, Services, PD Courses), not just the homepage's — the
   name is stale but the class is shared on purpose, not a copy-paste.
   Tinted, not white, so on the homepage specifically it doesn't sit
   flush against the also-white Brand New Courses section above it. */
/* Shared P4 texture overlay — a pseudo-element so opacity fades the
   pattern without touching the text sitting on top of it. Same
   technique as .ksa-course-art__pattern above. Used behind every
   testimonial deck and the homepage founder bio. */
.ksa-home-testimonials,
.ksa-home-bio {
  position: relative;
  isolation: isolate;
  background-color: var(--ksa-grey-5);
}
/* White sections carry the same P4 texture at a fraction of the
   opacity — almost white, just enough to warm up the flat white and
   blend it with the fuller texture on the tinted sections, instead of
   alternating between "textured" and "flat" down the page. */
.ksa-home-texture-light {
  position: relative;
  isolation: isolate;
}
.ksa-home-testimonials::before,
.ksa-home-bio::before,
.ksa-home-texture-light::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url("assets-patterns/Subtle Patterns/p4.png");
  background-repeat: repeat;
  pointer-events: none;
}
.ksa-home-testimonials::before,
.ksa-home-bio::before {
  opacity: 0.32;
}
.ksa-home-texture-light::before {
  opacity: 0.22;
}
/* Testimonial deck — homepage only. A single attributed quote,
   centered, rotating with dots. Markup from
   ksa_render_testimonial_deck() in functions.php. */
.ksa-tdeck {
  max-width: 780px;
  margin: 0 auto;
  text-align: center;
}

.ksa-tdeck__mark {
  display: block;
  font-family: Georgia, serif;
  font-size: 56px;
  line-height: 0.6;
  color: var(--cta);
  margin: 0 0 var(--sp-4);
}

.ksa-tdeck__stage {
  position: relative;
  min-height: 200px;
}

.ksa-tdeck__slide {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 600ms cubic-bezier(0.16, 1, 0.3, 1), transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.ksa-tdeck__slide.is-active {
  opacity: 1;
  transform: translateY(0);
}

/* Condensed/light/Quote-sized rather than sans/regular/Body-sized —
   an attributed customer quote is someone else's voice, not the
   page's own copy. See --type-quote-size in colors_and_type.css. */
.ksa-page-section .ksa-tdeck__quote {
  font-family: var(--font-condensed);
  font-weight: var(--fw-light);
  font-size: var(--type-quote-size);
  line-height: var(--type-quote-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-5);
}

.ksa-tdeck__attribution {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg-muted);
  margin: 0;
}

.ksa-tdeck__name {
  color: var(--fg);
  font-weight: var(--fw-bold);
}

.ksa-tdeck__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-5);
  margin-top: var(--sp-7);
}

.ksa-tdeck .ksa-tdeck__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--ksa-white);
  color: var(--fg);
  cursor: pointer;
  transition: background-color 200ms ease-out, border-color 200ms ease-out;
}

.ksa-tdeck .ksa-tdeck__btn:hover {
  background: var(--ksa-blue-light);
  border-color: var(--ksa-blue);
}

.ksa-tdeck .ksa-tdeck__btn:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

.ksa-tdeck__dots {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.ksa-tdeck__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--border);
  cursor: pointer;
}

.ksa-tdeck__dot.is-active {
  width: 18px;
  border-radius: 4px;
  background: var(--ksa-blue);
  transition: width 200ms ease-out;
}

.ksa-tdeck__dot:focus-visible {
  outline: var(--ksa-focus-width) solid var(--ksa-focus-color);
  outline-offset: var(--ksa-focus-offset);
}

@media (prefers-reduced-motion: reduce) {
  .ksa-tdeck__slide {
    transition: none;
  }
}

/* ============================================================
   Fixes — Aug 7, 2026 review round
   ============================================================ */

/* Hamburger: stays invisible chrome, never picks up a fill. */
.ksa-nav .ksa-nav__hamburger:hover,
.ksa-nav .ksa-nav__hamburger:focus {
  background: transparent;
  color: inherit;
}

/* ---- Testimonial attribution typography ----
   reset.css also sets `figcaption { font-style: italic }`, which was silently
   italicising the whole attribution block — so the name rendered as bold
   UPPERCASE ITALIC and the firm as blue italic. Both read as errors rather
   than styling. Name is now sentence-case condensed bold at body size, firm
   is muted grey regular: a plain, conventional attribution.
   The quote itself also loses its italic — 300+ characters of italic body
   text is genuinely harder to read, and the quote mark plus the card already
   signal that it is a quotation. */
.ksa-testimonial-card figcaption {
  font-style: normal;
}

.ksa-page-section .ksa-testimonial-card blockquote {
  font-style: normal;
}

.ksa-testimonial-card__name {
  font-size: var(--type-h4-size);
  text-transform: none;
  letter-spacing: 0;
  font-style: normal;
}

.ksa-testimonial-card__company {
  color: var(--fg-muted);
  font-style: normal;
}

/* ---- Product page excerpt ----
   Was 18px muted grey, which read as small print under a 45px title. Now the
   same treatment as the About page's mission line (.ksa-about-row__pull):
   condensed light at lead size, in full navy rather than grey — a real
   lede. The tinted box and rule from that class are deliberately not carried
   over; this is a standfirst, not a pull-quote. */
.ksa-page-section .ksa-product__lede {
  font-family: var(--font-condensed);
  font-weight: var(--fw-light);
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-lh);
  color: var(--fg);
}

/* ---- Product page back link ----
   Was the default underlined blue link. Now matches the Services page's
   "Let's talk →" treatment so a forward link looks the same everywhere. */
.ksa-page-section .ksa-product__back .ksa-page-section__link {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  color: var(--cta);
  text-decoration: none;
}

.ksa-page-section .ksa-product__back .ksa-page-section__link:hover {
  color: var(--cta-hover);
  text-decoration: underline;
}

/* ---- Mini-cart drawer: match the PD course card ----
   The drawer was rendering product names at 14px medium — WooCommerce
   Blocks styles them through
     table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name
   which is (0,3,1) and beat the plain (0,2,0) selector used above.
   Repeating that chain under .wc-block-mini-cart__drawer makes it
   (0,4,1) and wins on specificity — no !important needed, and it stays
   scoped to the drawer so the full cart page is untouched.

   Sizes deliberately mirror .ksa-course-card__* on the PD page: title
   at --type-h4-size condensed bold, description at --type-small-size,
   both in --fg. Hover goes orange, the same rollover the course cards
   use. */
.wc-block-mini-cart__drawer table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  line-height: var(--type-h4-lh);
  color: var(--fg);
  text-decoration: none;
}

.wc-block-mini-cart__drawer table.wc-block-cart-items .wc-block-cart-items__row a.wc-block-components-product-name:hover {
  color: var(--cta);
  text-decoration: none;
}

/* Prices and line totals to full navy, so nothing in the drawer sits at
   a different weight of grey. */
.wc-block-mini-cart__drawer .wc-block-components-product-price,
.wc-block-mini-cart__drawer .wc-block-components-product-price__value,
.wc-block-mini-cart__drawer .wc-block-cart-item__total .wc-block-components-product-price {
  color: var(--fg);
}

/* ---- Mini-cart drawer close button ----
   Woo ships it as a bare square icon button; this makes it round, to
   match the carousel arrows and the site's pill language.

   36x36 and inset from the corner.

   Two Woo rules had to be answered. `min-height: 3em` (48px) comes
   from `body:not(...) .wc-block-components-button:not(.is-link)` at
   (0,3,1), so going smaller needs (0,4,0) — reached by naming both
   classes the element already carries, not by reaching for !important.
   And the button is `position: absolute` with `margin: -1em`, which
   pulled it 4px OUTSIDE the drawer's top-right corner (measured: -4px
   on both edges). Zeroing that margin and setting its own top/right is
   what actually moves it off the corner — padding on the wrapper does
   nothing to an absolutely positioned child.

   The hover fill is the one `!important` here, and only because
   mini-cart.css declares `background: transparent !important` on this
   exact element — an important declaration can only be beaten by
   another one, no amount of specificity helps. The resting state is
   left transparent, which is correct anyway on the white drawer.

   WooCommerce's drawer auto-focuses this button the instant it opens
   (standard a11y focus-trap behaviour, not something we control) --
   so :focus-visible fires on every open, not just real keyboard nav,
   including a plain mouse click on the cart icon. It used to share
   the same solid-orange-fill rule as :hover, which made the button
   look permanently "stuck pressed" the moment the cart opened, before
   anyone touched anything. Fill is now :hover-only.

   Focus also can't use the sitewide outline ring (--ksa-focus-width/
   -offset): outlined, it sits OUTSIDE this round button with a gap,
   which reads as a separate floating ring detached from the button
   rather than a focus state on it -- confusing on every single open,
   not just real keyboard use. An inset box-shadow instead draws the
   ring flush with the button's own edge, so it reads as "this button"
   highlighted, not as a stray shape next to it. */
.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  min-height: 36px;
  padding: 0;
  margin: 0;
  top: var(--sp-4);
  right: var(--sp-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  color: var(--fg);
  cursor: pointer;
  outline: none;
  transition: background-color 200ms ease-out, border-color 200ms ease-out, color 200ms ease-out;
}

/* The X never actually showed up -- whatever icon markup/colour
   WooCommerce renders inside this button didn't match what fill:
   currentColor above was targeting, and chasing their internal
   structure further isn't worth it. Hide their icon and draw a plain
   CSS X instead: two centered bars crossed with rotation, coloured by
   the button's own `color` so it still follows :hover/:focus-visible
   automatically. */
.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close svg {
  display: none;
}

.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close::before,
.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
}

.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close::before {
  transform: translate(-50%, -50%) rotate(45deg);
}

.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close:hover {
  background: var(--cta) !important;
  border-color: var(--cta);
  color: var(--cta-text);
}

.wc-block-mini-cart__drawer .wc-block-components-drawer__close-wrapper .wc-block-components-button.wc-block-components-drawer__close:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--ksa-focus-width) var(--ksa-focus-color);
}

/* ---- Pinstripe on the dark bands ----
   Trialled on Services, then adopted everywhere. Applies to every
   navy/blue full-width band: the page hero, the footer CTA band and
   the footer itself.

   A repeating-linear-gradient rather than an image: no HTTP request,
   nothing to keep in the media library, and it scales at any width.

   background-IMAGE is set separately from background-COLOR on purpose.
   Each band keeps its own colour — the footer CTA band stays brand
   blue rather than being flattened to navy — and only the hero takes
   the #0a2545 from the spec, which is a shade lighter and bluer than
   --ksa-navy.

   The footer CTA band and the footer itself have moved to the P4
   diamond pattern instead, below, to unify with the homepage's
   texture — confirmed working on the CTA band first, then carried to
   the footer. The page hero keeps the stripe for now. */
.ksa-page-hero {
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.045) 0 1px,
    rgba(255, 255, 255, 0) 1px 7px
  );
}

.ksa-footer__cta-band,
.ksa-footer {
  position: relative;
  isolation: isolate;
}
.ksa-footer__cta-band::before,
.ksa-footer::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url("assets-patterns/p4-white.png");
  background-repeat: repeat;
  pointer-events: none;
}
.ksa-footer__cta-band::before {
  opacity: 0.15;
}
/* Lower than the CTA band — on this much darker base, the same 0.15
   white texture had enough contrast to read as busier/lighter overall
   than the near-black ground underneath it. Dimming the texture reads
   as darker than dimming the base further would have. */
.ksa-footer::before {
  opacity: 0.05;
}

.ksa-page-hero {
  background-color: #0a2545;
}

/* ---- My Account: navy text, orange rollovers ----
   Reversed from an earlier pass that made the resting links orange
   too. Resting state is navy like the rest of the site; orange is the
   rollover only.

   Three link families live on this page and all three need saying:
   the WooCommerce account nav (Dashboard / Orders / Addresses / Log
   out), ordinary links in the welcome copy, and the LearnDash course
   list from [ld_profile].

   :not(.button) keeps this off the account form's own buttons, which
   are already orange-filled with navy text. */
.ksa-page-section .ksa-account a:not(.button):not(.woocommerce-Button),
.ksa-page-section .ksa-account__content a:not(.button):not(.woocommerce-Button) {
  color: var(--fg);
  text-decoration: none;
}

.ksa-page-section .ksa-account a:not(.button):not(.woocommerce-Button):hover,
.ksa-page-section .ksa-account__content a:not(.button):not(.woocommerce-Button):hover {
  color: var(--cta);
  text-decoration: underline;
}

.ksa-account .woocommerce-MyAccount-navigation-link a {
  color: var(--fg);
}

.ksa-account .woocommerce-MyAccount-navigation-link a:hover {
  background: var(--ksa-grey-5);
  color: var(--cta);
}

/* The [ld_profile] course list. LearnDash prints its "Primary Color"
   setting as an INLINE <style> block containing
   `.learndash-wrapper .ld-item-list .ld-item-list-item
   a.ld-item-name:hover { color:#00559b !important }` — (0,5,1),
   important, and last in the document. Same fight as the curriculum
   hover on the course page, so the same answer: (0,7,1) plus
   !important. The resting colour needs no !important because
   LearnDash excludes .ld-item-name from its own resting rule. */
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name,
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name .ld-item-title {
  color: var(--fg);
}

.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name:hover,
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name:hover .ld-item-title {
  color: var(--cta) !important;
}

/* "Services include:" column, boxed to match .ksa-about-row__pull on
   About and the "Already Enrolled?" note on PD — same blue wash, same
   4px accent rule, same square corners and padding. Type inside is
   unchanged; this is the box only.

   The list keeps its own bullet indent, so the box's left padding is
   what separates the rule from the text rather than the ul's. */
.ksa-page-section .ksa-service-block__list-col {
  background: var(--ksa-blue-light);
  border-left: 4px solid var(--accent);
  padding: var(--sp-5) var(--sp-6);
}

/* Last bullet sits flush with the box's bottom padding instead of
   adding its own gap under it. */
.ksa-page-section .ksa-service-block__list li:last-child {
  margin-bottom: 0;
}

/* ---- Contact page: contact details + form side by side ----
   "Contact Us" and "Keep Up-to-Date" used to be two separate
   full-width bands, which left the page as four stacked sections for
   not much content. They are one row now: details and the newsletter
   blurb stacked in the left column, the HubSpot form beside them.

   align-items: start so the form sits at the top of the row rather
   than stretching to the height of the left column. */
.ksa-contact-layout {
  display: grid;
  grid-template-columns: 1fr minmax(300px, 420px);
  gap: var(--sp-8);
  align-items: start;
}

/* The second heading in the left column needs the space a section
   break used to give it — without this, "Keep Up-to-Date" sits right
   under the social icons. */
.ksa-page-section .ksa-contact-layout__second-heading {
  margin-top: var(--sp-7);
}

/* The form gets the same callout box the About/PD/Services pages use.
   The Keep Up-to-Date band it came from was tinted, so without
   something here the form would float unanchored on plain white now
   that the tint is gone. */
.ksa-contact-layout__form {
  background: var(--ksa-blue-light);
  border-left: 4px solid var(--accent);
  padding: var(--sp-5) var(--sp-6);
}

/* HubSpot renders its own markup with its own font stack; pull the
   fields into the site's type and control sizing. */
.ksa-contact-layout__form .hs-form-field label,
.ksa-contact-layout__form form label {
  font-family: var(--font-sans);
  font-size: var(--type-small-size);
  font-weight: var(--fw-medium);
  color: var(--fg);
}

.ksa-contact-layout__form input[type="text"],
.ksa-contact-layout__form input[type="email"],
.ksa-contact-layout__form input[type="tel"],
.ksa-contact-layout__form select,
.ksa-contact-layout__form textarea {
  width: 100%;
  min-height: 44px;
  padding: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.ksa-contact-layout__form input[type="submit"],
.ksa-contact-layout__form .hs-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--sp-3) var(--sp-5);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: var(--cta);
  color: var(--cta-text);
  border: 1px solid var(--cta);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color 200ms ease-out, border-color 200ms ease-out;
}

.ksa-contact-layout__form input[type="submit"]:hover,
.ksa-contact-layout__form .hs-button:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  color: var(--cta-text);
}

@media (max-width: 900px) {
  .ksa-contact-layout {
    grid-template-columns: 1fr;
    gap: var(--sp-6);
  }
}

/* ---- My Account: heading hierarchy ----
   Final hierarchy, per feedback: "Account Details" at the h1 scale
   leads the page, "Your Courses" at h2 under it, and the individual
   course names at h4. A clean descending 45 / 35 / 18 with no two
   levels sharing a size.

   These are size overrides only — the underlying markup is left alone.
   LearnDash emits "Your Courses" as an <h3> and WordPress emits the
   other two as <h2>, and rewriting either would mean filtering plugin
   output for a purely visual change. ⚠️ Worth knowing: this page has
   no <h1> at all (page-my-account.php renders the_content(), not the
   title), so "Your Courses" is now the visual h1 without being the
   semantic one. */
/* "Account Details" leads the page. page-my-account.php renders no
   title, so this is the page's visual h1 (see the note about the
   missing semantic h1).
   DIRECT CHILD (>) on purpose: WooCommerce also emits <h2> for
   "Billing address" / "Shipping address" on the edit-address screen,
   nested inside .woocommerce-Address-title. A descendant selector swept
   those up and rendered them at 45px too. */
.ksa-page-section .ksa-account__content > h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-lh);
}

/* "Dashboard" / "Orders" / "Address" / "Account Details" -- printed by
   page-my-account.php above the nav/content box so that column has a
   heading of its own, matching "Your Courses" beside it at the same
   h2 scale. Also a direct child of .ksa-account__content, so it needs
   its own higher-specificity override here rather than inheriting the
   45px h1-scale rule above. */
.ksa-page-section .ksa-account__content > h2.ksa-account__heading {
  font-weight: var(--fw-bold);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}

/* ONLY the LearnDash section heading ("Your Courses"). An earlier
   version of this rule also matched `.ksa-account__content h3`, which
   swept up WooCommerce's own h3s — "Billing address" and "Shipping
   address" on the edit-address screen would have rendered at 45px
   too. Those keep the ordinary h3 scale.

   margin-top: 0 on both the heading and the list wrapper -- same class
   of LearnDash-default-top-margin fix as .ld-item-list.ld-lesson-list
   elsewhere in this file. Without it, "Your Courses" sits noticeably
   lower than the dashboard panel beside it even though the two grid
   columns share the same top edge (.ksa-account__columns' align-items:
   start only aligns the columns themselves, not content pushed down by
   a child's own margin). */
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list {
  margin-top: 0;
}

.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-section-heading h3 {
  margin-top: 0;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-lh);
  color: var(--fg);
}

/* Course names to the h3 scale. Needs the long chain for the same
   reason as their colour: LearnDash styles this element through
   .ld-item-list .ld-item-list-item a.ld-item-name. */
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name,
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item a.ld-item-name .ld-item-title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  line-height: var(--type-h4-lh);
}

/* A 1px stroke around each course row, with room between rows so the
   new borders read as separate cards instead of a packed stack.
   LearnDash's own ld30 CSS is what actually shapes .ld-item-list-item
   (padding, radius) — this just adds the border and gap on top,
   !important because that CSS loads after this file and already sets
   its own border value. */
.ksa-page-section .ksa-account .learndash-wrapper .ld-item-list .ld-item-list-item {
  border: 1px solid var(--border) !important;
  margin-bottom: var(--sp-3) !important;
}

/* "Search Your Courses" is an h4 inside the same block and would
   otherwise inherit the h1 treatment above from the h3 rule's
   neighbours — keep it small, it's a control label. */
.ksa-page-section .ksa-account .ld-item-search-heading {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
}

/* ---- My Account: saved addresses ----
   The address blocks on /my-account/edit-address/ were floating on
   plain white with nothing holding them. Same light 1px stroke as the
   FAQ so they read as cards. Two of them (billing / shipping) sit side
   by side in WooCommerce's own .u-columns grid, so the padding also
   stops them touching. */
.ksa-account .woocommerce-Address {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--sp-5);
}

.ksa-account .woocommerce-Address address {
  font-style: normal;
  font-size: var(--type-body-size);
  line-height: var(--type-body-lh);
  color: var(--fg);
  margin: 0;
}

/* Woo puts the "Edit" link inside the title block; keep it from
   colliding with the heading above it. The heading is an <h2> here,
   not an h3 as an earlier version of this rule assumed. */
.ksa-page-section .ksa-account .woocommerce-Address-title h2 {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-lh);
  color: var(--fg);
  margin: 0 0 var(--sp-3);
}

.ksa-account .woocommerce-Address-title {
  margin-bottom: var(--sp-3);
}

/* ---- My Account: contain the account area ----
   The nav column and the panel beside it were floating loose on white.
   A light 1px stroke around WooCommerce's own .woocommerce wrapper
   holds them together as one unit — same stroke as the FAQ.

   overflow: hidden does two jobs: it clips the nav's active grey row
   to the rounded corners, and it contains WooCommerce's floated
   two-column layout so the border wraps the full height rather than
   collapsing to nothing.

   The nav rows keep their full-bleed grey (no padding on the wrapper),
   so the padding goes on the content panel instead. */
.ksa-account .woocommerce {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Horizontal tab row instead of a side column. WooCommerce's own
   default CSS floats the nav and content side by side; nested inside
   this page's half-width .ksa-account__columns column, that squeezed
   the "Hello Lara..." panel into roughly a third of an already
   half-width column and wrapped its text awkwardly. Resetting both to
   full width stacks content under the nav instead of beside it. */
.ksa-account .woocommerce-MyAccount-navigation,
.ksa-account .woocommerce-MyAccount-content {
  float: none;
  width: 100%;
}

.ksa-account .woocommerce-MyAccount-navigation {
  padding: 0;
  border-bottom: 1px solid var(--border);
}

.ksa-account .woocommerce-MyAccount-navigation ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
}

/* More room below the dashboard's welcome text than above it -- the
   text sits right under the tab row already, so it only needed room
   to breathe at the bottom of the panel. */
.ksa-account .woocommerce-MyAccount-content {
  padding: var(--sp-5) var(--sp-6) var(--sp-7);
}

/* The "Edit Billing address" / "Edit Shipping address" action link.
   Orange rather than the navy the rest of this page's links use —
   it's an action, so it follows the same language as "Let's talk" on
   Services. (0,4,1) to beat the page-wide navy link rule at (0,3,1). */
.ksa-page-section .ksa-account .woocommerce-Address-title a {
  color: var(--cta);
  text-decoration: underline;
}

.ksa-page-section .ksa-account .woocommerce-Address-title a:hover {
  color: var(--cta-hover);
  text-decoration: underline;
}

/* Two columns instead of one stacked under the other: the WooCommerce
   nav/dashboard panel on the left, LearnDash's "Your Courses" list on
   the right. The welcome copy above (plain <p> tags typed in the page
   content, siblings of both shortcodes' output) stays full width by
   spanning every column. Both blocks keep their own internal layout —
   this only controls how the two of them sit next to each other. */
/* Two equal columns: WooCommerce's nav/dashboard panel and LearnDash's
   "Your Courses" list, wrapped together into .ksa-account__columns at
   runtime (see the script in page-my-account.php). Not done with CSS
   Grid directly on .ksa-account__content: the page content is plain
   HTML typed in the block editor, and a stray empty <p> that WordPress
   leaves behind between the two shortcodes (a side effect of wpautop
   wrapping a block-level shortcode output in a paragraph tag, which
   the browser then has to break out of) auto-spans the full grid row
   and pushes the second column onto its own row underneath instead of
   beside the first — the two blocks stacked instead of sitting side by
   side. Wrapping them in their own container at runtime sidesteps that
   entirely: nothing else can land in between the two anymore. */
.ksa-account__columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-8);
  align-items: start;
}

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

.ksa-account .learndash-wrapper.ld-profile,
.ksa-account .ld-profile {
  margin-top: 0;
}

/* WooCommerce ships these tables with no border/padding of its own —
   left at defaults they render cramped, especially in a half-width
   column. */
.ksa-account .woocommerce-MyAccount-content table.shop_table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--sp-4) 0;
}

.ksa-account .woocommerce-MyAccount-content table.shop_table th,
.ksa-account .woocommerce-MyAccount-content table.shop_table td {
  padding: var(--sp-3);
  border-bottom: 1px solid var(--border);
  text-align: left;
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg);
}

.ksa-account .woocommerce-MyAccount-content table.shop_table th {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-caps-size);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.ksa-account .woocommerce-MyAccount-content table.shop_table tr:last-child td {
  border-bottom: 0;
}

@media (max-width: 480px) {
  .ksa-account .woocommerce-MyAccount-content table.shop_table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

/* ============================================================
   Design Guidelines — page-design-guidelines.php
   Rebuilt Aug 10, 2026. Swatches/scale render inline colours the
   template already computed from colors_and_type.css values, so this
   block is layout only — spacing, grid, borders — not colour.
   ============================================================ */

.ksa-page-section .ksa-dg-eyebrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-caps-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--sp-3);
}

.ksa-page-section .ksa-dg-subhead {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  margin: var(--sp-7) 0 var(--sp-4);
}

.ksa-page-section .ksa-dg-note {
  font-size: var(--type-small-size);
  color: var(--fg-muted);
  margin: var(--sp-4) 0 0;
  max-width: 720px;
}

/* ---- Foundation: Purpose / Vision / Mission + Voice & mood, added
   Aug 30, 2026. Left border accent in brand blue, matching the LKI and
   ALNA treatment of the same section.

   The label is a real <h3>, not a <p> styled to look like one — noted
   in the playbook after ALNA, where a styled <p> did not inherit the
   sitewide heading rule and rendered as slightly-larger body text.

   ---- */
.ksa-dg-foundation-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-5);
}

.ksa-dg-foundation-card {
  border-left: 1px solid var(--border);
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-4);
}

.ksa-page-section .ksa-dg-foundation-card__label {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--ksa-navy);
}

.ksa-page-section .ksa-dg-foundation-card__text {
  margin: 0;
  color: var(--ksa-grey-1);
}

.ksa-dg-mood-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

.ksa-dg-mood-tag {
  display: inline-block;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--ksa-grey-3);
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: var(--type-small-size);
  color: var(--ksa-navy);
}

@media (max-width: 900px) {
  .ksa-dg-foundation-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
}

/* ---- Logo: all four light/dark combinations in one row (Primary and
   Professional Development). Was two stacked ksa-dg-logo-row pairs,
   each with its own explanatory note; both the row wrapper and the
   notes were removed Aug 29, 2026 so this is just the cards now.

   Grid, not flex, since Aug 29: the cards were a fixed 220px inside a
   flex row, so they bunched at the left and left dead space against
   the right margin. A 4-column track makes them divide the full
   content width the way every other card row on this page does. ---- */
.ksa-dg-logo-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-5);
}

.ksa-dg-logo-card {
  text-align: left;
}

/* Title and download link sit below the box as plain page text, not
   inside it — only the box itself needs to demonstrate light/dark
   contrast, so caption/link stay one style regardless of variant. */
.ksa-dg-logo-card__box {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--sp-4) var(--sp-3);
  margin-bottom: var(--sp-3);
}

/* Same file as .ksa-dg-logo-card__box, shown on navy instead of white
   — the mark is a flattened .jpg with its own opaque square baked in,
   so it renders identically either way. This proves that rather than
   implying a second, reversed file exists. */
.ksa-dg-logo-card__box--dark {
  background: var(--ksa-navy);
  border-color: var(--ksa-navy);
}

.ksa-dg-logo-card__img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
}

.ksa-page-section .ksa-dg-logo-card__caption {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg-muted);
  margin: 0 0 var(--sp-2);
}

.ksa-page-section .ksa-dg-logo-card__link {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--link);
  text-decoration: none;
}

.ksa-page-section .ksa-dg-logo-card__link:hover {
  color: var(--link-hover);
}

/* ---- Colour cards: matches Lara Kroeker Interactive's own
   design-guidelines chip pattern exactly (Website/lki-child/
   page-design-guidelines.php, .dg-chip) — colour fill on top, then
   name, hex, token, a divider, and a usage line below. Replaces the
   Aug 10 2026 originals (a separate divided surface strip, plus a
   kicker-first swatch with no hex) so every colour group on this page
   — Surface, Primary, CTA, Greys, Status — now uses one card system,
   shared with LKI rather than KSA-specific. Every group uses the same
   fixed 5-column track rather than sizing to its own item count, so a
   3-swatch group (Primary, CTA) renders cards exactly as wide as a
   4-swatch one (Surface, Greys, Semantic). Short rows therefore end
   early instead of stretching — the uniform card is the point.

   Widened 5 -> 6 columns Aug 30, 2026 when the Additional group (three
   category pairs = six swatches) was added: six is now the largest
   group, so it fills exactly one row and every other group still
   measures the same card. ---- */
.ksa-dg-swatch-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-3);
}

/* Surface and Primary opt out of the uniform 6-column track above —
   their swatches stretch to fill the row instead of ending early.
   The 180px floor matters: minmax(0, 1fr) lets auto-fit compute an
   unbounded number of zero-width tracks at narrow widths, so only the
   first few items ever get real width instead of the row's actual
   item count stretching evenly. */
.ksa-dg-swatch-row.ksa-dg-swatch-row--full {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.ksa-dg-swatch {
  display: block;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.ksa-dg-swatch__color {
  display: block;
  width: 100%;
  height: 132px;
  position: relative;
}

/* Inset hairline so a pale swatch (Pure, Blue light, Orange light)
   still reads as a filled area against the white card instead of
   dissolving into it — same fix LKI's chip uses. */
.ksa-dg-swatch__color::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px rgba(1, 31, 65, 0.06);
}

.ksa-dg-swatch__body {
  display: block;
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
}

.ksa-page-section .ksa-dg-swatch__name {
  display: block;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
  margin-bottom: var(--sp-1);
}

.ksa-page-section .ksa-dg-swatch__hex {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--type-caps-size);
  color: var(--fg);
  margin-bottom: var(--sp-1);
}

.ksa-page-section .ksa-dg-swatch__token {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
  word-break: break-all;
}

.ksa-page-section .ksa-dg-swatch__role {
  display: block;
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
  font-family: var(--font-condensed);
  font-weight: var(--fw-black);
  font-size: var(--type-micro-size);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}

/* ---- Type: family specimen cards, big glyph + name + weight range.
   Two columns, side by side with a single dividing line — deliberately
   not a bordered card per column, since the two families are read as
   one continuous system rather than separate components. ---- */
.ksa-dg-font-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-top: var(--sp-6);
}

.ksa-dg-font-card {
  padding: var(--sp-6) var(--sp-7);
}

.ksa-dg-font-card + .ksa-dg-font-card {
  border-left: 1px solid var(--border);
}

.ksa-page-section .ksa-dg-font-card__label {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 var(--sp-4);
}

.ksa-dg-font-card__glyphs {
  display: flex;
  align-items: baseline;
  gap: var(--sp-6);
  margin: 0 0 var(--sp-4);
}

.ksa-dg-font-card__glyph {
  font-size: 96px;
  line-height: 1;
  color: var(--fg);
}

.ksa-page-section .ksa-dg-font-card__meta {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
  margin: 0;
}

@media (max-width: 600px) {
  .ksa-dg-font-cards {
    grid-template-columns: 1fr;
  }

  .ksa-dg-font-card + .ksa-dg-font-card {
    border-left: none;
    border-top: 1px solid var(--border);
  }
}

/* ---- Type scale ---- */
.ksa-dg-type-scale {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  margin-top: var(--sp-6);
}

/* A 160px column only ever fit an "Aa" glyph, not a real word — and a
   glyph tells nobody what the role looks like in actual use. Wide enough
   now for the real specimen text set in page-design-guidelines.php to
   wrap naturally at every size from Hero (60px) down to Eyebrow (13px). */
.ksa-dg-type-row {
  display: grid;
  grid-template-columns: minmax(280px, 1.1fr) minmax(280px, 1fr);
  align-items: start;
  gap: var(--sp-6);
  padding: var(--sp-4) 0;
}

.ksa-dg-type-sample {
  color: var(--fg);
}

.ksa-page-section .ksa-dg-type-meta {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg-muted);
}

.ksa-page-section .ksa-dg-type-meta code {
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
}

/* ---- Spacing scale ---- */
/* Single row of vertical bars, each one's WIDTH the actual px value —
   not a horizontal bar chart. Widths sum to ~410px across 10 values
   plus gaps, comfortably inside the 1280px content column. */
.ksa-dg-spacing-row {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}

.ksa-dg-spacing-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
}

.ksa-dg-spacing-bar {
  display: block;
  height: 56px;
  background: var(--ksa-grey-4);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.ksa-page-section .ksa-dg-spacing-label {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
}

/* ---- Radius: plain filled box (no border/card), value + use-case +
   token stacked below — matches the reference's box-then-two-lines
   read rather than a bordered swatch card. ---- */
.ksa-dg-radius-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-6);
  margin-top: var(--sp-5);
}

.ksa-dg-radius-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
}

.ksa-dg-radius-box {
  width: 120px;
  height: 90px;
  background: var(--ksa-grey-4);
}

.ksa-page-section .ksa-dg-radius-value {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
}

.ksa-page-section .ksa-dg-radius-use {
  font-size: var(--type-small-size);
  color: var(--fg-muted);
}

/* ---- Elevation: the shadow is applied to the CARD itself, not shown
   in a separate preview square beside a label — so what you see is
   literally the effect being described. ---- */
.ksa-dg-elevation-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-6);
  margin-top: var(--sp-5);
}

.ksa-dg-elevation-item {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  background: var(--ksa-white);
  border-radius: var(--radius-md);
  padding: var(--sp-6);
}

.ksa-page-section .ksa-dg-elevation-title {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-h4-size);
  color: var(--fg);
}

.ksa-page-section .ksa-dg-elevation-use {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
}

/* ---- Buttons showcase ---- */
.ksa-dg-button-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--sp-6);
  margin-top: var(--sp-6);
}

.ksa-dg-button-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ksa-page-section .ksa-dg-button-meta {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg-muted);
  margin: 0;
}

.ksa-page-section .ksa-dg-button-meta code {
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
}

/* Preview-only copy of .ksa-course-card__cart a.button — rendered as a
   <span>, not a real WooCommerce add-to-cart control, since this page
   isn't a product loop. Kept visually identical on purpose. */
.ksa-dg-cart-btn-preview.button {
  display: inline-block;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--fg);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
}

/* ---- Icons: animated (GIF) ---- */
.ksa-dg-gif-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-6);
  margin-top: var(--sp-5);
}

.ksa-dg-gif-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-align: center;
}

.ksa-dg-gif-item__img {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}

/* Caption under each GIF icon. Re-added here Aug 13, 2026 — the
   original .ksa-dg-swatch__label rule this class relied on was removed
   when the Colour swatches were rebuilt into unified cards, which
   silently unstyled these three captions since they share the class
   name. */
.ksa-page-section .ksa-dg-swatch__label {
  font-size: var(--type-small-size);
  line-height: var(--type-small-lh);
  color: var(--fg-muted);
}

/* ---- Icons: static (Phosphor) ----
   Fixed 9-column grid, not flex-wrap. flex-wrap breaks rows unevenly
   depending on each label's width; a real grid with a fixed column
   count keeps every row equal by construction — 45 icons divides
   cleanly into 5 rows of 9. */
.ksa-dg-icon-grid {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding: var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ksa-dg-icon-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-2);
}

.ksa-dg-icon-cell img {
  width: 22px;
  height: 22px;
}

.ksa-page-section .ksa-dg-icon-cell__name {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
  text-align: center;
  line-height: var(--type-micro-lh);
  word-break: break-word;
}

.ksa-page-section .ksa-dg-link-arrow {
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  font-size: var(--type-small-size);
  color: var(--link);
  text-decoration: none;
}

.ksa-page-section .ksa-dg-link-arrow:hover {
  color: var(--link-hover);
}

@media (max-width: 900px) {
  .ksa-dg-icon-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

@media (max-width: 560px) {
  .ksa-dg-icon-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* A token listed on the page but absent from colors_and_type.css. Made
   loud on purpose: the failure mode this replaced was a page silently
   showing a stale colour, so a missing value must be impossible to
   miss rather than degrading into an empty white card. ---- */
.ksa-dg-swatch--missing {
  border-color: var(--ksa-error);
}

.ksa-dg-swatch--missing .ksa-dg-swatch__color {
  background-image: repeating-linear-gradient(45deg, var(--ksa-error-light) 0 8px, var(--ksa-white) 8px 16px);
}

.ksa-page-section .ksa-dg-swatch--missing .ksa-dg-swatch__hex {
  color: var(--ksa-error);
  font-weight: var(--fw-bold);
}

/* ---- Hero metadata bar: Draft / Built by / Sources. The documented
   house pattern (WORKSPACE-design-guidelines-playbook.md, "The
   header"), added to KSA Aug 30, 2026. Sits on the navy hero, so every
   colour here is an on-dark token.

   The labels deliberately do NOT reuse the brand eyebrow's treatment —
   the playbook calls that out specifically: one names the brand, these
   are a data row, and giving unrelated roles the same type reads as
   templated. Smaller, lighter, wider tracking. ---- */
.ksa-dg-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-6);
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.ksa-page-hero .ksa-dg-meta__label {
  margin: 0 0 2px;
  font-family: var(--font-sans);
  font-size: var(--type-micro-size);
  font-weight: var(--fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-on-dark);
}

.ksa-page-hero .ksa-dg-meta__value {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--type-small-size);
  color: var(--fg-on-dark);
}

.ksa-page-hero .ksa-dg-meta__value a {
  color: var(--fg-on-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ksa-page-hero .ksa-dg-meta__value a:hover {
  color: var(--cta);
}

/* The AI/provenance line under the lede — same column, one step down in
   size but NOT in colour. It was --fg-on-dark-muted until Aug 30, 2026;
   at 15px on navy that read as greyed-out rather than secondary, and it
   carries the only route to the machine-readable version, so it has to
   be legible. Size does the hierarchy here, not opacity. */
.ksa-page-hero .ksa-page-hero__text--small {
  margin-top: var(--sp-3);
  font-size: var(--type-small-size);
  color: var(--fg-on-dark);
}

.ksa-page-hero .ksa-page-hero__text--small a {
  color: var(--fg-on-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 560px) {
  .ksa-dg-meta {
    gap: var(--sp-4);
  }
}

/* ---- Draft sections (Logo usage, Photography direction, Voice & tone,
   Don'ts), added Aug 30, 2026. Deliberately NOT styled to blend in: a
   warning-coloured rail down the left, so nobody mistakes a proposal
   for a decision. They render only while $ksa_dg_show_drafts is true
   in page-design-guidelines.php. They sit outside the plain/tinted
   alternation of the real sections on purpose -- they are meant to
   read as interruptions. The eyebrow badge that used to sit alongside
   this rail was removed per feedback; the rail alone carries the
   signal now. ---- */
.ksa-dg-draft {
  border-left: 3px solid var(--ksa-warning);
  background: var(--ksa-warning-light);
}

.ksa-dg-deflist {
  margin: var(--sp-5) 0 0;
  display: grid;
  grid-template-columns: minmax(160px, 220px) 1fr;
  gap: var(--sp-3) var(--sp-5);
}

.ksa-page-section .ksa-dg-deflist dt {
  margin: 0;
  font-family: var(--font-condensed);
  font-weight: var(--fw-bold);
  color: var(--ksa-navy);
  line-height: 1.4;
}

.ksa-page-section .ksa-dg-deflist dd {
  margin: 0;
  color: var(--ksa-grey-1);
  line-height: 1.6;
}

.ksa-page-section .ksa-dg-deflist dt em {
  display: block;
  font-family: var(--font-sans);
  font-style: normal;
  font-weight: var(--fw-regular);
  font-size: var(--type-micro-size);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ksa-warning-dark);
}

@media (max-width: 768px) {
  .ksa-dg-deflist {
    grid-template-columns: 1fr;
    gap: var(--sp-2) 0;
  }
  .ksa-page-section .ksa-dg-deflist dd {
    margin-bottom: var(--sp-4);
  }
}

/* ---- Stock photography: every stock photo pulled live from Services
   and About's own ACF fields (see page-design-guidelines.php) -- a
   plain image grid, no captions. Same crop-and-hover-zoom treatment as
   LKI's dg-mood-grid (Website/lki-child/page-design-guidelines.php). ---- */
.ksa-dg-photo-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: var(--sp-4);
  margin-top: var(--sp-5);
}

.ksa-dg-photo-cell {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
}

.ksa-dg-photo-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 400ms ease;
}

.ksa-dg-photo-cell:hover img {
  transform: scale(1.04);
}

@media (max-width: 900px) {
  .ksa-dg-photo-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (max-width: 560px) {
  .ksa-dg-photo-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ============================================================
   Icon Library — page-icon-library.php
   ============================================================ */

.ksa-il-searchbar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  background: var(--ksa-white);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  padding: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-2);
  position: sticky;
  top: 0;
  z-index: 5;
  box-shadow: var(--shadow-sm);
}

.ksa-il-searchbar input {
  flex: 1;
  border: none;
  outline: none;
  background: none;
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  color: var(--fg);
}

.ksa-il-searchbar input::placeholder {
  color: var(--fg-subtle);
}

.ksa-page-section .ksa-il-count {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
  white-space: nowrap;
}

.ksa-il-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}

.ksa-il-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-5) var(--sp-2);
  background: var(--ksa-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: box-shadow 200ms ease-out, transform 200ms ease-out, border-color 200ms ease-out;
}

.ksa-il-cell:hover {
  box-shadow: var(--shadow-sm);
  transform: translateY(-2px);
  border-color: var(--cta);
}

.ksa-il-cell img {
  width: 22px;
  height: 22px;
}

.ksa-page-section .ksa-il-cell__name {
  font-family: var(--font-mono);
  font-size: var(--type-micro-size);
  color: var(--fg-muted);
  text-align: center;
  line-height: var(--type-micro-lh);
  word-break: break-word;
}

.ksa-il-cell.is-copied {
  border-color: var(--ksa-success);
}

.ksa-il-cell.is-copied .ksa-il-cell__name {
  color: var(--ksa-success-dark);
}

.ksa-page-section .ksa-il-empty {
  display: none;
  text-align: center;
  padding: var(--sp-9) 0;
  color: var(--fg-muted);
  font-size: var(--type-body-size);
}

.ksa-il-toast {
  position: fixed;
  bottom: var(--sp-6);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--ksa-navy);
  color: var(--ksa-white);
  font-family: var(--font-mono);
  font-size: var(--type-small-size);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--radius-pill);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease-out, transform 180ms ease-out;
  z-index: 50;
}

.ksa-il-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

@media (max-width: 1200px) {
  .ksa-il-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

@media (max-width: 900px) {
  .ksa-il-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (max-width: 560px) {
  .ksa-il-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .ksa-dg-swatch-row {
    grid-template-columns: repeat(3, 1fr);
  }

  .ksa-dg-logo-cards {
    grid-template-columns: repeat(2, 1fr);
  }

  .ksa-dg-type-row {
    grid-template-columns: 1fr;
    gap: var(--sp-3);
  }
}

@media (max-width: 480px) {
  .ksa-dg-swatch-row,
  .ksa-dg-logo-cards {
    grid-template-columns: 1fr;
  }
}

/* Supplied Lordicon animations, shown at small display size. */
.ksa-dg-lordicons { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: var(--sp-3); margin: var(--sp-6) 0 var(--sp-8); }
.ksa-dg-lordicon { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); text-align: center; }
.ksa-dg-lordicon .ksa-dg-lordicon__preview { display: grid; place-items: center; width: 100%; min-height: 88px; padding: 14px; box-sizing: border-box; border: 1px solid var(--border); background: var(--bg); border-radius: var(--radius-sm); }
.ksa-dg-lordicon .ksa-dg-lordicon__preview:hover { background: var(--bg); border-color: var(--accent); }
.ksa-dg-lordicon .ksa-dg-lordicon__preview:focus-visible { outline: var(--ksa-focus-width) solid var(--ksa-focus-color); outline-offset: var(--ksa-focus-offset); }
/* 56px, no stroke-width override (reverted — Lottie draws each shape
   in its own internal viewBox coordinate space, so a flat CSS
   stroke-width doesn't scale consistently with it: 1.25px landed at a
   fraction of a real pixel once the SVG scaled down to display size,
   washing every icon out instead of making them read as finer). */
.ksa-dg-lordicon__animation { display: block; width: 56px; height: 56px; }
.ksa-dg-lordicon__label { font-family: var(--font-condensed); color: var(--fg); }
.ksa-dg-lordicon a { font-size: var(--type-body-size); }

@media (max-width: 900px) { .ksa-dg-lordicons { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (max-width: 480px) { .ksa-dg-lordicons { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.ksa-dg-lordicon__animation { max-width: 100%; }

/* Pattern swatches: a shared grey surface, consistent scale, no fades. */
.ksa-dg-patterns { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--sp-6); }
.ksa-dg-pattern { margin: 0; min-width: 0; }
.ksa-dg-pattern__preview { position: relative; height: 160px; overflow: hidden; background: #F4F5F6; border-radius: var(--radius-sm); isolation: isolate; }
.ksa-dg-pattern__preview img { position: absolute; width: 500px; height: 500px; max-width: none; left: 50%; top: 50%; transform: translate(-50%, -50%); mix-blend-mode: multiply; }
.ksa-dg-pattern figcaption { margin-top: var(--sp-2); color: var(--fg); font-family: var(--font-condensed); }
@media (max-width: 900px) { .ksa-dg-patterns { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 480px) { .ksa-dg-patterns { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.ksa-dg-pattern--subtle .ksa-dg-pattern__preview img { opacity: 0.45; }

/* These are small source tiles meant to repeat, not artwork scaled
   to fill the box like the library above. */
.ksa-dg-pattern__preview--tiled {
  background-repeat: repeat;
}

/* Shared product/course artwork. Original featured JPEGs remain in the media library. */
/* Icon + copy are a 2-column grid, not a centred flex pair: with flex,
   a fixed-size icon centred against the FULL (padded) box only lined
   up with the text by coincidence, and visibly didn't on the taller
   detail banner. Grid's row height comes from the copy block's own
   content (the icon has no intrinsic height of its own to contribute),
   so align-items:stretch (the grid default) makes the icon's top and
   bottom land exactly on the text block's top and bottom instead of
   just floating near its middle. align-content:center keeps that row
   centred in the banner when --art-height leaves extra space, without
   inflating the row itself. */
.ksa-course-art { position:relative; isolation:isolate; overflow:hidden; background:var(--art-bg); min-height:var(--art-height); padding:var(--art-padding); display:grid; grid-template-columns:var(--art-icon) 1fr; column-gap:var(--art-padding); align-content:center; box-sizing:border-box; }
.ksa-course-art__pattern { position:absolute; inset:0; opacity:var(--art-opacity); z-index:-1; pointer-events:none; }
.ksa-course-art__pattern > svg { position:absolute; width:400px; height:400px; max-width:none; top:50%; left:50%; transform:translate(-50%,-50%); }
.ksa-course-art__pattern path { stroke:#011F41; stroke-width:12; }
.ksa-course-art__copy { grid-column:2; grid-row:1; }
.ksa-course-art__title { margin:0!important; font-family:var(--font-condensed); font-size:var(--art-title)!important; line-height:1.25; font-weight:var(--fw-bold); color:var(--ksa-navy); overflow-wrap:anywhere; }
.ksa-course-art__title a { color:inherit; text-decoration:none; transition:color 200ms ease-out; }
.ksa-course-art__title a:hover { color:var(--art-accent); }
.ksa-course-art__title a::after { content:''; position:absolute; inset:0; }
.ksa-course-art__icon { grid-column:1; grid-row:1; width:var(--art-icon); height:auto; pointer-events:none; }
.ksa-course-art--detail { min-height:180px; border-radius:var(--radius-sm); }
.ksa-course-art--detail .ksa-course-art__title { font-size:calc(var(--art-title) * 2)!important; }
.ksa-product__header .ksa-course-art { margin-bottom:24px; }

.ksa-course-art__pattern{background-repeat:repeat;background-size:400px 400px;}

/* Category artwork and preview placement. */
.ksa-course-art{border-top:4px solid var(--art-accent);background:color-mix(in srgb,var(--art-bg) 55%,white);}
.ksa-course-art__category{margin:0 0 10px;font-family:var(--font-condensed);font-size:var(--type-caps-size);line-height:var(--type-caps-lh);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;color:var(--art-accent);}
.ksa-product__buy-card>.ksa-course-art{margin-bottom:24px;}
.ksa-course-video{border:1px solid #D2D7DC;border-radius:var(--radius-lg);overflow:hidden;margin-bottom:28px;}
.ksa-course-video iframe,.ksa-course-video video{display:block;width:100%;aspect-ratio:16/9;height:auto;}

.ksa-course-heading{padding-bottom:16px;}
.ksa-course-details{padding-top:0;}
.ksa-course-details .ksa-page-section__inner{padding-top:16px;}
.ksa-course-details .ksa-course-content__columns{grid-template-columns:minmax(0,1.7fr) minmax(260px,1fr);gap:32px;}
.ksa-course-details .ksa-course-content__col{min-width:0;}
.ksa-course-details .ksa-course-content__col+ .ksa-course-content__col{border:1px solid #D2D7DC;border-radius:var(--radius-lg);padding:24px;}
@media(max-width:760px){.ksa-course-details .ksa-course-content__columns{grid-template-columns:1fr;}}

.ksa-product__main{min-width:0;}
.ksa-page-section .ksa-course-video{position:relative;width:100%;max-width:100%;box-sizing:border-box;border:1px solid #D2D7DC;border-radius:var(--radius-lg);overflow:hidden;isolation:isolate;}
.ksa-page-section .ksa-course-video>iframe,.ksa-page-section .ksa-course-video>video{position:static!important;display:block!important;width:100%!important;max-width:100%!important;height:auto!important;aspect-ratio:16/9;margin:0!important;border:0;box-sizing:border-box;}
.ksa-page-section .ksa-course-video--placeholder{display:flex;align-items:center;justify-content:center;aspect-ratio:16/9;background:var(--bg);color:var(--fg-subtle);font-family:var(--font-condensed);font-weight:var(--fw-bold);font-size:var(--type-small-size);text-transform:uppercase;letter-spacing:.04em;}

/* Click-to-play video poster facade -- see ksa_render_video_facade() in functions.php. */
.ksa-video-facade{position:relative;display:block;width:100%;aspect-ratio:16/9;cursor:pointer;overflow:hidden;}
.ksa-video-facade__poster{display:block;width:100%;height:100%;object-fit:cover;transition:transform .25s ease,filter .25s ease;}
.ksa-video-facade:hover .ksa-video-facade__poster,.ksa-video-facade:focus-visible .ksa-video-facade__poster{transform:scale(1.03);filter:brightness(.92);}
.ksa-video-facade:focus-visible{outline:2px solid var(--ksa-blue);outline-offset:2px;}
.ksa-video-facade template{display:none;}

