/* Atomic utilities: buttons, pills, eyebrows, lists, cards, rows, stats. Reusable in widgets, editor and menus. */

/* Buttons */
/* Live buttons: 14px mono, 12px/24px padding, 20px line-height => 44px tall pill. */
.hbd-btn { display: inline-flex; align-items: center; gap: .5rem; font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-btn); letter-spacing: normal; text-transform: uppercase; text-decoration: none; line-height: var(--hbd-lh-btn); padding: .75rem 1.5rem; border-radius: var(--hbd-radius-pill); border: 1px solid transparent; cursor: pointer; transition: background-color var(--hbd-dur) var(--hbd-ease), color var(--hbd-dur) var(--hbd-ease), border-color var(--hbd-dur) var(--hbd-ease), transform var(--hbd-dur) var(--hbd-ease); }
/* Live buttons: `transition-all duration-200`, no lift/shadow on hover — hover only recolours (measured 2026-09-17). */
.hbd-btn:hover { transform: none; }
/* Astra repaints a focused <a> in its own link colour, which turns a navy button's white label navy
   on navy — measured on the provider page's CTA (docs/audit/templates/provider.md §10.3) and true of
   every .hbd-btn in the theme. A button's label belongs to its variant, not to the link colour, so
   focus keeps whatever the variant set. The ring is the rule below. */
.hbd-btn:focus, .hbd-btn:focus-visible { color: inherit; }
.hbd-btn--primary:focus, .hbd-btn--primary:focus-visible { color: var(--hbd-white); }
.hbd-btn--outline:focus, .hbd-btn--outline:focus-visible,
.hbd-btn--white:focus, .hbd-btn--white:focus-visible,
.hbd-btn--ghost:focus, .hbd-btn--ghost:focus-visible { color: var(--hbd-ink); }
.hbd-on-dark .hbd-btn--outline:focus, .hbd-on-dark .hbd-btn--outline:focus-visible { color: var(--hbd-white); }
/* …and the ring itself, for the same reason. base.css sets the theme ring on `:focus-visible`, but
   Astra's `a:focus { outline: thin dotted }` is a plain `:focus` rule that wins the cascade on every
   button that is a link — so --primary/--white/--outline/--arrow drew a 1px dotted ring in their own
   text colour while the few buttons a widget had patched drew the real one. One theme-wide rule, the
   same declaration base.css uses, so every .hbd-btn variant rings identically and no widget needs a
   patch of its own (the CTA banner's white-on-navy ring stays: contrast, not cascade). */
.hbd-btn:focus-visible { outline: 2px solid var(--hbd-blue); outline-offset: 3px; }
.hbd-btn--primary { background: var(--hbd-navy); color: var(--hbd-white); }
.hbd-btn--primary:hover { background: var(--hbd-slate); color: var(--hbd-white); } /* live: navy → #456C8F */
.hbd-btn--outline { background: transparent; color: var(--hbd-ink); border-color: currentColor; }
.hbd-btn--outline:hover { background: var(--hbd-white); color: var(--hbd-ink); } /* live: outline pills only fill white on hover; border unchanged */
.hbd-btn--white { background: var(--hbd-white); color: var(--hbd-ink); }
.hbd-btn--white:hover { background: var(--hbd-slate); color: var(--hbd-white); } /* live: white → #456C8F, white text */
.hbd-btn--ghost { background: transparent; color: var(--hbd-ink); padding-left: .5rem; padding-right: .5rem; }
.hbd-btn--ghost:hover { color: var(--hbd-blue); }
/* --sm: 40px tall (live drawer/panel pills). --lg: 52px (hero/section CTAs). */
.hbd-btn--sm { padding: .625rem 1.25rem; } .hbd-btn--lg { padding: 1rem 2rem; }
.hbd-btn--block { display: flex; width: 100%; justify-content: center; }
.hbd-btn--arrow svg { width: 1rem; height: 1rem; transition: transform var(--hbd-dur) var(--hbd-ease); }
.hbd-btn--arrow:hover svg { transform: translateX(3px); }
.hbd-btn--icon { width: 3rem; height: 3rem; padding: 0; justify-content: center; }
.hbd-on-dark .hbd-btn--outline { color: var(--hbd-white); } .hbd-on-dark .hbd-btn--outline:hover { background: var(--hbd-white); color: var(--hbd-ink); }

/* Pills */
.hbd-pill { display: inline-flex; align-items: center; font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-mono); letter-spacing: var(--hbd-tracking-mono); text-transform: uppercase; line-height: 1; padding: .55rem .875rem; border-radius: var(--hbd-radius-pill); white-space: nowrap; }
.hbd-pill--dotted { border: 1px dashed var(--hbd-ink-a55); color: var(--hbd-ink); background: transparent; }
.hbd-on-dark .hbd-pill--dotted { border-color: var(--hbd-white-a70); color: var(--hbd-white); }
.hbd-pill--sky { background: var(--hbd-sky); color: var(--hbd-navy); font-family: var(--hbd-font-body); text-transform: none; font-size: .8125rem; }
.hbd-pill--orange { background: var(--hbd-orange); color: var(--hbd-white); }
.hbd-pill--pink { background: var(--hbd-pink); color: var(--hbd-ink); }
.hbd-pill--navy { background: var(--hbd-navy); color: var(--hbd-white); }
.hbd-pill--white { background: var(--hbd-white); color: var(--hbd-ink); }
.hbd-pills { display: flex; flex-wrap: wrap; gap: .5rem; }

/* Eyebrow */
.hbd-eyebrow { display: block; font-family: var(--hbd-font-body); font-size: 1rem; color: var(--hbd-ink); margin-bottom: var(--hbd-space-3); }
.hbd-eyebrow--pill { display: inline-flex; font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-mono); text-transform: uppercase; letter-spacing: var(--hbd-tracking-mono); border: 1px dashed var(--hbd-ink-a55); border-radius: var(--hbd-radius-pill); padding: .55rem .875rem; }
.hbd-eyebrow--mono { font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-mono); text-transform: uppercase; letter-spacing: var(--hbd-tracking-mono); }

/* Lists */
.hbd-list { list-style: none; margin: 0 0 var(--hbd-space-5); padding: 0; display: grid; gap: .875rem; }
.hbd-list__item { display: grid; grid-template-columns: 1.75rem 1fr; gap: .75rem; align-items: start; }
.hbd-list__marker { width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px dashed var(--hbd-ink-a50); display: inline-flex; align-items: center; justify-content: center; font-family: var(--hbd-font-mono); font-size: .75rem; }
.hbd-list__marker svg { width: .875rem; height: .875rem; }
.hbd-list--check .hbd-list__marker svg { color: var(--hbd-blue); }
.hbd-list--check-x .hbd-list__item--ok .hbd-list__marker svg { color: var(--hbd-blue); }
.hbd-list--check-x .hbd-list__item--no .hbd-list__marker { border-color: var(--hbd-orange-a50); }
.hbd-list--check-x .hbd-list__item--no .hbd-list__marker svg { color: var(--hbd-orange); }
.hbd-list--links .hbd-list__item { grid-template-columns: 1.25rem 1fr; }
.hbd-list--links a { color: var(--hbd-ink); }
.hbd-list--boxed { border: 1px dashed var(--hbd-ink-a40); border-radius: var(--hbd-radius-s); padding: var(--hbd-space-5); }

/* Cards / surfaces */
.hbd-card { border-radius: var(--hbd-radius-m); padding: var(--hbd-space-6); background: var(--hbd-white); }
.hbd-card--sky { background: var(--hbd-sky); } .hbd-card--cream { background: var(--hbd-cream); }
.hbd-card--white-shadow { background: var(--hbd-white); box-shadow: var(--hbd-shadow-card); }
.hbd-card--grad-orange { background: var(--hbd-grad-orange); color: var(--hbd-white); }
.hbd-card--grad-sky { background: var(--hbd-grad-sky-rings); }
.hbd-card--lavender { background: var(--hbd-lavender); }
.hbd-img--rounded { border-radius: var(--hbd-radius-m); overflow: hidden; }
.hbd-img--rounded img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hbd-divider { border: 0; border-top: var(--hbd-hairline); margin: var(--hbd-space-6) 0; }
.hbd-hairline-top { border-top: var(--hbd-hairline); padding-top: var(--hbd-space-5); }
.hbd-on-dark { color: var(--hbd-white); } .hbd-on-dark h1, .hbd-on-dark h2, .hbd-on-dark h3, .hbd-on-dark .hbd-eyebrow { color: var(--hbd-white); }

/* Rows (apply as SiteOrigin row classes) */
/* `width: 100vw` includes the vertical scrollbar's own width on Windows, so it overshoots the true
   viewport by the scrollbar's ~15-17px and adds horizontal overflow; `width: auto` with symmetric
   inline margins pulls the row to the viewport edges without depending on 100vw at all. */
.hbd-row--full { width: auto; margin-inline: calc(50% - 50vw); }
.hbd-row--sky { background: var(--hbd-sky); } .hbd-row--cream { background: var(--hbd-cream); }
.hbd-row--grad-peach-sky { background: var(--hbd-grad-peach-sky); } .hbd-row--grad-sky-rings { background: var(--hbd-grad-sky-rings); }
.hbd-row--pad-s { padding-top: var(--hbd-space-7); padding-bottom: var(--hbd-space-7); }
.hbd-row--pad-m { padding-top: var(--hbd-space-8); padding-bottom: var(--hbd-space-8); }
.hbd-row--pad-l { padding-top: var(--hbd-space-9); padding-bottom: var(--hbd-space-9); }
@media (max-width: 767px) { .hbd-row--pad-m { padding-top: var(--hbd-space-7); padding-bottom: var(--hbd-space-7); } .hbd-row--pad-l { padding-top: var(--hbd-space-8); padding-bottom: var(--hbd-space-8); } }

/* Stats */
.hbd-stat { display: grid; gap: .25rem; } .hbd-stat__value { font-family: var(--hbd-font-display); font-size: var(--hbd-fs-h2); line-height: 1; } .hbd-stat__label { font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-mono); text-transform: uppercase; letter-spacing: var(--hbd-tracking-mono); }

/* Section header pattern: heading left, text/button right */
.hbd-section-head { display: grid; gap: var(--hbd-space-5); align-items: end; margin-bottom: var(--hbd-space-6); }
@media (min-width: 900px) { .hbd-section-head { grid-template-columns: 1fr 1fr; } .hbd-section-head > :last-child { justify-self: end; max-width: 34rem; } }

/* Stars (hbd_stars(), inc/template-tags.php) — every rating on the site.
   Two layers of the same five glyphs, both absolutely positioned at the same origin so they
   superimpose exactly; the coloured one is clipped by width to the score. The row's size comes from
   --hbd-star-size / --hbd-star-gap (per instance, or the defaults in tokens.css) and never from the
   surrounding font, so two cards side by side cannot disagree. The glyph is scaled inside its own box
   because the theme's star carries more padding in its 24 × 24 viewBox than live's art does. */
.hbd-stars { --hbd-stars-on: var(--hbd-gold); --hbd-stars-off: var(--hbd-grey-300); position: relative; display: block; flex: none; width: calc(var(--hbd-star-count, 5) * var(--hbd-star-size) + (var(--hbd-star-count, 5) - 1) * var(--hbd-star-gap)); height: var(--hbd-star-size); line-height: 0; }
.hbd-stars__track,
.hbd-stars__fill { position: absolute; top: 0; left: 0; height: 100%; display: flex; align-items: center; gap: var(--hbd-star-gap); }
.hbd-stars__track { width: 100%; color: var(--hbd-stars-off); }
.hbd-stars__fill { width: var(--hbd-stars, 100%); overflow: hidden; color: var(--hbd-stars-on); }
.hbd-stars svg { flex: none; display: block; width: var(--hbd-star-size); height: var(--hbd-star-size); transform: scale(var(--hbd-star-scale)); }
.hbd-stars--navy { --hbd-stars-on: var(--hbd-navy); --hbd-stars-off: var(--hbd-navy-a20); }
.hbd-stars--orange { --hbd-stars-on: var(--hbd-orange); --hbd-stars-off: var(--hbd-grey-300); }

/* Video facade (hbd_video_facade(), inc/template-tags.php) — the one video component in the theme.
   The box is the provider's: `--hbd-video-aspect` (16/9 unless a caller overrides it per instance),
   the caller's own radius and any shadow it wants on top. What is inside it before the click is ours:
   the poster frame under a centred round play button, because live draws no site-style control to
   measure (docs/audit/widgets/stats.md §6). After the click assets/js/video-facade.js swaps in the
   iframe, which fills exactly the same box. */
.hbd-video { position: relative; display: block; width: 100%; aspect-ratio: var(--hbd-video-aspect); overflow: hidden; border-radius: var(--hbd-video-radius); }
/* The dark box is the *no-poster* state, not a backdrop every facade paints: a poster fills the frame
   edge to edge (`inset: 0; object-fit: cover`), so with one there is nothing to see behind it. */
.hbd-video--no-poster { background: var(--hbd-video-bg); }
.hbd-video__poster,
.hbd-video__frame { position: absolute; inset: 0; display: block; width: 100%; height: 100%; border: 0; }
.hbd-video__poster { object-fit: cover; }
/* The control: centred, and its own size rather than the surrounding font's, so two facades on a page
   cannot disagree. `.hbd-btn` is deliberately not reused — this is a round glyph button, not a pill. */
.hbd-video__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: inline-flex; align-items: center; justify-content: center; width: var(--hbd-video-play); height: var(--hbd-video-play); padding: 0; border: 0; border-radius: 50%; background: var(--hbd-video-play-bg); color: var(--hbd-video-play-color); box-shadow: var(--hbd-video-play-shadow); cursor: pointer; transition: background-color var(--hbd-dur) var(--hbd-ease), color var(--hbd-dur) var(--hbd-ease); }
.hbd-video__play:hover { background: var(--hbd-video-play-bg-hover); color: var(--hbd-video-play-color-hover); }
.hbd-video__play:focus-visible { outline: 2px solid var(--hbd-navy); outline-offset: 3px; }
.hbd-video__play-icon { display: block; width: var(--hbd-video-play-glyph); height: var(--hbd-video-play-glyph); margin-left: var(--hbd-video-play-glyph-nudge); }
/* The <noscript> fallback: with JavaScript the block never renders at all, so this only styles the
   link a no-JS visitor sees — the whole frame, centred, over the poster. */
.hbd-video__fallback { position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end; flex-direction: column; gap: var(--hbd-space-4); padding: var(--hbd-space-5); font-family: var(--hbd-font-mono); font-size: var(--hbd-fs-btn); text-transform: uppercase; text-align: center; color: var(--hbd-white); text-decoration: underline; }
/* Once the player is in, the poster, the control and the fallback link are done — hidden rather than
   deleted, so the script never rewrites the facade's DOM from a string. `display: none` also takes the
   button out of the tab order, which is why there is no second control behind a playing video. */
.hbd-video--playing .hbd-video__poster,
.hbd-video--playing .hbd-video__play,
.hbd-video--playing noscript { display: none; }
