/* components.css
 * The whole component vocabulary. Nothing else exists.
 *
 *   .btn        primary, ghost and large call to action
 *   .eyebrow    small gold uppercase kicker above a heading
 *   .checklist  green tick list
 *   .card       surface panel used inside .grid-3
 *   .quote      testimonial block, real testimonials only
 *   details / summary  the FAQ accordion, works with JS disabled
 *   .trust-bar  slim strip of short reassurance items
 *   .bio        small round portrait beside a short credibility paragraph
 *   .media      a framed photograph, never cropped through a face
 *
 * Plus the lead form and the video frame, which every page reuses through
 * partials/form.njk and partials/video.njk.
 */

/* ---------- .btn ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.85rem 1.6rem;
  min-height: 48px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 1px solid var(--accent);
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
  transition: background var(--speed) var(--ease), transform var(--speed) var(--ease),
    box-shadow var(--speed) var(--ease);
}

.btn:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--accent-ink);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn:active {
  transform: translateY(0);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.btn--ghost {
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
  box-shadow: none;
}

.btn--ghost:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn--gold {
  background: var(--gold);
  border-color: var(--gold);
  color: #26210f;
}

.btn--gold:hover {
  background: #b28f3d;
  border-color: #b28f3d;
  color: #26210f;
}

.btn--lg {
  padding: 1.05rem 2.2rem;
  font-size: var(--step-1);
  min-height: 56px;
}

.btn--block {
  display: flex;
  width: 100%;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: center;
}

.btn-note {
  font-size: var(--step--1);
  color: var(--ink-muted);
}

.section--accent .btn,
.section--dark .btn {
  background: #fff;
  border-color: #fff;
  color: var(--accent-dark);
}

.section--accent .btn:hover,
.section--dark .btn:hover {
  background: var(--surface-alt);
  border-color: var(--surface-alt);
  color: var(--accent-dark);
}

.section--accent .btn-note,
.section--dark .btn-note {
  color: rgba(255, 255, 255, 0.8);
}

/* ---------- .eyebrow ---------- */

.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--space-2xs);
}

.eyebrow--green {
  color: var(--accent);
}

.section--accent .eyebrow,
.section--dark .eyebrow {
  color: var(--gold);
}

/* ---------- .checklist ---------- */

/* margin-inline, not margin. A blanket "margin: 0" here has the same
   specificity as ".stack > * + *" and wins on source order, so a checklist
   dropped into a .stack silently loses its vertical rhythm and collides with
   the paragraph above it. */
.checklist {
  list-style: none;
  margin-inline: 0;
  padding: 0;
  display: grid;
  gap: var(--space-xs);
  max-width: var(--measure);
}

.checklist li {
  position: relative;
  padding-left: 2rem;
  line-height: 1.6;
}

.checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 1.1rem;
  height: 0.6rem;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

.checklist--gold li::before {
  border-color: var(--gold);
}

.section--accent .checklist li::before,
.section--dark .checklist li::before {
  border-color: var(--gold);
}

/* A plain dot list, for the rare place a tick would overclaim. */
.dotlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-2xs);
}

.dotlist li {
  position: relative;
  padding-left: 1.25rem;
}

.dotlist li::before {
  content: "";
  position: absolute;
  left: 0.25rem;
  top: 0.75em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-muted);
}

/* ---------- .card ---------- */

.card {
  background: var(--surface);
  border: var(--border);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 2rem);
  box-shadow: var(--shadow-sm);
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.card h3,
.card h4 {
  margin: 0;
}

.card p {
  color: var(--ink-muted);
  margin: 0;
}

.card--warm {
  background: var(--surface-alt);
  border-color: transparent;
}

.card--accent {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
}

.card--accent h3,
.card--accent h4 {
  color: var(--accent-ink);
}

.card--accent p {
  color: rgba(255, 255, 255, 0.86);
}

.card--flat {
  box-shadow: none;
}

.card__num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--gold);
  line-height: 1;
}

.card__foot {
  margin-top: auto;
  padding-top: var(--space-s);
  font-size: var(--step--1);
  color: var(--ink-muted);
}

/* ---------- .quote ---------- */
/* Real testimonials only. Never invent a quote, a name or a result. */

.quote {
  background: var(--surface);
  border: var(--border);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 2rem);
  margin: 0;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  height: 100%;
}

.quote p {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ink);
  margin: 0;
  max-width: none;
}

.quote figcaption,
.quote__by {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
  margin-top: auto;
}

/* Star row above a real review. Decorative only, the row carries an aria-label
   so a screen reader hears the rating once instead of five glyphs. */
.quote__stars {
  color: var(--gold);
  font-size: var(--step-0);
  letter-spacing: 0.12em;
  line-height: 1;
}

.quote--plain {
  background: transparent;
  border: 0;
  border-left: 3px solid var(--gold);
  box-shadow: none;
  border-radius: 0;
  padding-block: 0.25rem;
}

/* ---------- FAQ, details and summary ---------- */
/* Native disclosure. No JavaScript, works with JS disabled, keyboard friendly. */

.faq {
  display: grid;
  gap: var(--space-xs);
  max-width: 800px;
}

.faq details {
  background: var(--surface);
  border: var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-s);
  padding: 1.1rem clamp(1rem, 3vw, 1.5rem);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}

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

.faq summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.65rem;
  height: 0.65rem;
  margin-top: 0.4em;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform var(--speed) var(--ease);
}

.faq details[open] summary::after {
  transform: rotate(-135deg);
}

.faq details[open] summary {
  color: var(--accent-dark);
}

.faq summary:hover {
  background: var(--surface-alt);
}

.faq__body {
  padding: 0 clamp(1rem, 3vw, 1.5rem) 1.25rem;
  color: var(--ink-muted);
}

.faq__body > * + * {
  margin-top: var(--space-xs);
}

.faq__body p {
  max-width: none;
}

/* ---------- .trust-bar ---------- */

/* Selector is ul.trust-bar, not .trust-bar, on purpose. The primitives reset
   uses ul[class] to strip list padding, and ul[class] out-specifies a bare
   class, so a plain .trust-bar rule loses its padding-block and the rules sit
   on top of the text. Margin is inline only, so .stack keeps control of the
   vertical rhythm above the bar. */
ul.trust-bar,
.trust-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-xs) var(--space-l);
  padding-inline: 0;
  padding-block: var(--space-s);
  border-top: var(--border);
  border-bottom: var(--border);
  list-style: none;
  margin-inline: 0;
}

.trust-bar li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-muted);
  text-transform: none;
}

.trust-bar li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  flex: 0 0 auto;
}

.section--accent .trust-bar,
.section--dark .trust-bar {
  border-color: rgba(255, 255, 255, 0.22);
}

.section--accent .trust-bar li,
.section--dark .trust-bar li {
  color: rgba(255, 255, 255, 0.88);
}

/* ---------- lead form, partials/form.njk ---------- */

.lead-form {
  background: var(--surface);
  border: var(--border);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 2rem);
  box-shadow: var(--shadow-md);
  display: grid;
  gap: var(--space-s);
  max-width: 520px;
}

.lead-form--wide {
  max-width: none;
}

.lead-form__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  margin: 0;
}

.lead-form__note {
  font-size: var(--step--1);
  color: var(--ink-muted);
  margin: 0;
  max-width: none;
}

.lead-form__note a {
  color: var(--accent);
}

/* Shown only when lead.php bounced an incomplete submission back with ?error=1.
   The [hidden] rule is repeated here because `display: grid` on .lead-form
   would otherwise beat the browser default styling for the hidden attribute and
   the banner would show on every page load. */
.lead-form__error {
  margin: 0;
  padding: var(--space-xs) var(--space-s);
  border-left: 3px solid #a03530;
  border-radius: 6px;
  background: #fbeceb;
  color: #7a2723;
  font-size: var(--step--1);
}

.lead-form__error[hidden] {
  display: none;
}

/* The form is a white card even when it sits on a dark or green band. Without
   this the section rule paints the title white on white and it vanishes. */
.section--dark .lead-form__title,
.section--accent .lead-form__title {
  color: var(--ink);
}

.section--dark .lead-form__note,
.section--accent .lead-form__note {
  color: var(--ink-muted);
}

.section--dark .lead-form__note a,
.section--accent .lead-form__note a {
  color: var(--accent);
}

/* .section--dark .btn and .section--accent .btn invert the button to white so
   it reads on a coloured band. The submit button is NOT on the band, it is on
   the white form card, so the inversion would paint it white on white. Put the
   normal green button back. Without this the primary conversion control on
   /healthcare-burnout/ is invisible. */
.section--dark .lead-form .btn,
.section--accent .lead-form .btn {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.section--dark .lead-form .btn:hover,
.section--accent .lead-form .btn:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--accent-ink);
}

.field {
  display: grid;
  gap: 0.35rem;
}

.field label {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink);
}

.field input {
  width: 100%;
  padding: 0.85rem 1rem;
  min-height: 48px;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

.field input::placeholder {
  color: #9aa79f;
}

.field input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: var(--focus-ring);
}

.field input:user-invalid {
  border-color: #a5462f;
}

/* Honeypot. Hidden from humans and from screen readers, visible to bots. */
.hp-field {
  position: absolute;
  left: -5000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ---------- video frame, partials/video.njk ---------- */

.video {
  width: 100%;
  max-width: 900px;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--accent-dark);
  box-shadow: var(--shadow-lg);
}

.video wistia-player {
  display: block;
  width: 100%;
}

.video__caption {
  margin-top: var(--space-2xs);
  text-align: center;
  font-size: var(--step--1);
  color: var(--ink-muted);
}

.section--accent .video__caption,
.section--dark .video__caption {
  color: rgba(255, 255, 255, 0.78);
}

/* ---------- site footer ---------- */

.site-footer {
  background: var(--accent-dark);
  color: rgba(255, 255, 255, 0.82);
  padding-block: var(--space-xl);
  font-size: var(--step--1);
}

.site-footer a {
  color: #fff;
  text-decoration: none;
}

.site-footer a:hover {
  text-decoration: underline;
}

.site-footer__brand {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: #fff;
}

.site-footer__meta {
  color: rgba(255, 255, 255, 0.72);
  max-width: 60ch;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-m);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer__disclaimer {
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  padding-top: var(--space-s);
  color: rgba(255, 255, 255, 0.74);
  max-width: 70ch;
}

.site-footer__legal {
  color: rgba(255, 255, 255, 0.6);
}

/* ---------- .bio ---------- */
/* A small round portrait beside a short credibility paragraph. One per page.
 *
 *   <div class="bio">
 *     <img class="bio__photo" src="..." alt="..." width="968" height="968" />
 *     <div class="bio__body stack stack--s"> ... </div>
 *   </div>
 *
 * The photo box is square and the source is square, so object-fit never has
 * anything to crop. If a future portrait is not square, fix the file, not this.
 */

.bio {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-m);
  background: var(--surface-alt);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 2rem);
}

.bio__photo {
  flex: 0 0 auto;
  width: 118px;
  height: 118px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--shadow-sm);
}

.bio__body {
  flex: 1 1 20rem;
  min-width: 0;
}

.bio__body p {
  max-width: none;
}

/* ---------- .media ---------- */
/* A framed photograph. Used inside .split so a section photo matches the
 * rounding, shadow and background of .card and .video instead of sitting on
 * the page as a raw rectangle. Always give the <img> real alt text.
 *
 *   <figure class="media">
 *     <img src="..." alt="..." width="1014" height="676" loading="lazy" />
 *   </figure>
 */

.media {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-alt);
  box-shadow: var(--shadow-md);
}

.media img {
  display: block;
  width: 100%;
  height: auto;
}

.media figcaption {
  padding: var(--space-xs) var(--space-s);
  background: var(--surface);
  font-size: var(--step--1);
  color: var(--ink-muted);
}

/* ---------- .hero-photo ---------- */
/* A hero whose background is a photograph. Used by / (the home page).
 *
 *   <section class="section hero-photo" id="hero">
 *     <img class="hero-photo__img" src="..." alt="" aria-hidden="true" />
 *     <div class="container">...</div>
 *   </section>
 *
 * WHY THE PHOTO IS AN <img> AND NOT A background-image: this is the LCP element
 * on the page. A real element gets width, height, fetchpriority and the same
 * responsive handling as every other image, and it never disappears when a
 * printer or a data-saver mode drops background images. The scrim is the
 * pseudo element instead.
 *
 * WHY THE SCRIM EXISTS: the source photograph is a sunrise. Its brightest area
 * is a near white sky sitting exactly where the headline goes. White text on
 * that photo raw is unreadable, and text-on-photo has already failed once on
 * this account. The gradient below is not a taste decision, it is the contrast
 * budget:
 *
 *   scrim colour  #0b1a14 at 0.66 alpha over the brightest sky pixel (255,245,215)
 *   composite     rgb(94, 100, 86), relative luminance 0.123
 *   white text    6.0:1   passes WCAG AA for body text
 *   pale gold     4.9:1   passes AA, which is why the eyebrow is recoloured
 *                         below. Brand gold #c6a24a only reaches 2.5:1 here
 *                         and would fail.
 *
 * If you change the photograph or the alpha, redo that arithmetic. Do not
 * lighten the scrim because the picture looks nicer.
 */

.hero-photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* The fallback under the photo, so the band is never a white flash while the
     image decodes and never bare cream if the file 404s. */
  background: var(--accent-dark);
  color: #fff;
}

.hero-photo__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  /* Bias down the frame. The interesting half of the shoreline is low in the
     source and the sky is empty, so a centred crop wastes the picture on phones. */
  object-position: 50% 60%;
  z-index: 0;
}

.hero-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    180deg,
    rgba(11, 26, 20, 0.72) 0%,
    rgba(11, 26, 20, 0.66) 45%,
    rgba(11, 26, 20, 0.8) 100%
  );
}

.hero-photo > .container {
  position: relative;
  z-index: 2;
}

.hero-photo h1,
.hero-photo h2 {
  color: #fff;
}

.hero-photo p,
.hero-photo .lead {
  color: rgba(255, 255, 255, 0.92);
}

/* Pale gold, not brand gold. See the contrast note above. */
.hero-photo .eyebrow {
  color: #f7e6b8;
}

/* Mirrors the .section--dark .btn rule. The green button is only 1.2:1 against
   the scrim, so the primary call to action would all but vanish into the
   photograph. Invert it the same way every other dark band on the site does. */
.hero-photo .btn {
  background: #fff;
  border-color: #fff;
  color: var(--accent-dark);
}

.hero-photo .btn:hover {
  background: var(--surface-alt);
  border-color: var(--surface-alt);
  color: var(--accent-dark);
}

.hero-photo .btn-note {
  color: rgba(255, 255, 255, 0.85);
}

/* ---------- .brandmark ---------- */
/* The Here For You logo.
 *
 * hfy-logo.png is a gold mark with an OPAQUE BLACK RECTANGLE baked into the
 * file. Drop it onto a light band and you get a black box with a logo in it.
 * So the component gives it a black plate of its own: the baked background and
 * the plate are the same colour, the seam disappears, and the mark reads as a
 * deliberate badge on any background, light or dark.
 *
 * If a transparent PNG or an SVG ever replaces the file, delete the background
 * declaration here rather than working around it in a template.
 */

.brandmark {
  display: inline-block;
  background: #000;
  padding: 0.55rem 0.9rem;
  border-radius: var(--radius-sm);
  line-height: 0;
}

/* 350px is the file's native width. Rendered below about 200px the wordmark
   under the bird stops being readable, so this is a legibility floor rather
   than a taste call. */
.brandmark img {
  width: 220px;
  height: auto;
}

/* ---------- .pullquote ---------- */
/* A line of the brand's own copy set large. NOT .quote: .quote is reserved for
 * real third party testimonials, and reusing it here would dress a slogan up as
 * somebody's endorsement. */

.pullquote {
  margin: 0;
  padding-block: var(--space-s);
  border-top: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  text-align: center;
}

.pullquote p {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.25;
  color: var(--ink);
  margin-inline: auto;
  max-width: 22ch;
}

.section--accent .pullquote p,
.section--dark .pullquote p {
  color: var(--accent-ink);
}

/* ---------- review portrait, extends .quote ---------- */
/* Adds a round portrait beside the reviewer's name inside an existing .quote.
 *
 *   <figcaption class="quote__person">
 *     <img class="quote__avatar" src="..." alt="" aria-hidden="true" />
 *     <span class="quote__name">Name</span>
 *   </figcaption>
 *
 * The images are ILLUSTRATIVE, not photographs of the reviewers, so they carry
 * an empty alt and aria-hidden. A screen reader hears the review and the name,
 * which is all that is actually true. Never give one of these a name in alt
 * text: that would turn stock photography into invented proof.
 *
 * .quote figcaption already carries margin-top: auto, which is what keeps the
 * attribution pinned to the bottom of a card in a row of uneven quotes. These
 * rules only add the row layout on top of it. */

.quote__person {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.quote__avatar {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--shadow-sm);
}

.quote__name {
  min-width: 0;
}

/* ---------- skip link ---------- */

.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 999;
  padding: 0.75rem 1rem;
  background: var(--accent);
  color: #fff;
  border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
  left: 0;
  top: 0;
}
