/*
Theme Name: Telos Wellness
Theme URI: https://teloswellnesscoach.com
Author: Bolly Enterprises
Description: Custom block theme for Telos Wellness. Evidence-informed metabolic health coaching for women 40-65. Design system lives in theme.json; this file carries only what theme.json cannot express.
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.1
Version: 1.0.0-beta.3
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: telos
Tags: block-theme, full-site-editing, one-column, accessibility-ready
*/

/* ---------------------------------------------------------------------------
   Almost nothing belongs here. Colour, type, and spacing are defined in
   theme.json so the block editor enforces them for Bo. Add CSS here ONLY for
   things theme.json has no expression for.
   --------------------------------------------------------------------------- */

/* Skip link - the staging site had none, which made keyboard entry impossible. */
.telos-skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  padding: 0.75rem 1.25rem;
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--paper);
  font-family: var(--wp--preset--font-family--ui);
  font-weight: 700;
  text-decoration: none;
}
.telos-skip-link:focus {
  left: 1rem;
  top: 1rem;
}

/* Visible focus for every interactive element. The staging build shipped no
   :focus styles at all - this is the floor, not a nicety.

   Two-tone ring on purpose: a single colour cannot meet WCAG 2.2 non-text
   contrast (3:1) on both the navy sections and the off-white ones. Gold against
   white measures 2.17:1 and would fail. Navy inner + off-white outer stays
   visible on every brand surface. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--wp--preset--color--ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--wp--preset--color--paper);
}

/* Eyebrow: the small uppercase label above a heading.
   Registered as a block style variation in functions.php so Bo picks it from
   the editor rather than typing a class. Rationed by design - see README.

   NOT teal. The brand guide restricts teal to large surfaces and warns it fails
   contrast below 18pt; measured, teal on off-white is 2.59:1 and fails AA at
   every size. The staging site shipped this violation. Navy Light is 6.19:1. */
.is-style-telos-eyebrow {
  font-family: var(--wp--preset--font-family--ui);
  font-size: var(--wp--preset--font-size--eyebrow);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wp--preset--color--ink-muted);
  line-height: 1.5;
}

/* Teal panels take navy text, never white: white on teal is 2.82:1 and fails. */
.has-teal-background-color,
.has-teal-mid-background-color {
  color: var(--wp--preset--color--ink);
}

/* Display italics clip descenders (y g j p q) at tight leading. Charis SIL's
   italic is particularly prone to it. Reserve the space. */
:where(h1, h2, h3) em,
:where(h1, h2, h3) i {
  line-height: 1.15;
  padding-bottom: 0.08em;
}

/* Measure cap for prose. theme.json contentSize governs blocks, not inline text. */
.telos-prose :where(p, li) {
  max-width: 65ch;
}

/* For ranges and figures that must not be split across a line break. */
.telos-nowrap {
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   SECTION SEAMS

   Every pattern is an alignfull group with its own background colour, and the
   flow layout was putting a blockGap margin between each pair — a 16px stripe
   of page background showing through between the hero and the method band, the
   method band and the evidence band, and so on down the homepage. Against two
   saturated surfaces it reads as a rendering fault rather than as spacing.

   Sections own their own vertical padding, so the gap between them should be
   zero. Same for the header/main/footer joins.
   --------------------------------------------------------------------------- */

.wp-site-blocks > header + main,
.wp-site-blocks > main + footer {
  margin-block-start: 0;
}

.entry-content > .alignfull + .alignfull {
  margin-block-start: 0;
}

/* ---------------------------------------------------------------------------
   HEADER

   These classes were in parts/header.html from the start but had no rules at
   all, which is why the mobile header fell apart: at 390px "Start Here" was
   being squeezed onto THREE lines (a 75px-tall button) and the site title onto
   two. The flex row lets the nav wrap steal width from the button, so the
   button has to refuse to shrink and refuse to wrap.
   --------------------------------------------------------------------------- */

.telos-header .wp-block-site-title a {
  text-decoration: none;
}

.telos-founder-credit {
  white-space: nowrap;
}

.telos-nav-wrap {
  flex-shrink: 0;
}

.telos-cta {
  flex-shrink: 0;
}

.telos-cta .wp-block-button__link {
  white-space: nowrap;
}

/* Sticky, on every page. Solid navy always — the brief permits a transparent-
   over-media variant, but a solid surface is legible over every background with
   zero scroll-listener JS, and the brief's own first principle is clarity over
   novelty. The admin-bar var keeps it from hiding under WP's toolbar when Bo is
   logged in; it resolves to 0 for visitors. The journey stage reads the header's
   real height into --telos-header-offset so the pinned film starts below this
   bar rather than under it. */
.telos-header {
  position: sticky;
  top: var(--wp-admin--admin-bar--height, 0px);
  z-index: 90;
}

/* Nav links: paper on ink is 12.6:1. The gold underline is the hover/active
   voice — text colour never changes, so contrast never dips. 44px minimum
   target height per WCAG 2.5.8 / brief §6. */
.telos-header .wp-block-navigation a,
.telos-header .wp-block-navigation .wp-block-navigation-submenu__toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
  text-underline-offset: 0.35em;
}

.telos-header .wp-block-navigation a:hover,
.telos-header .wp-block-navigation a:focus-visible,
.telos-header .wp-block-navigation .wp-block-navigation-submenu__toggle:hover,
.telos-header .wp-block-navigation .wp-block-navigation-submenu__toggle:focus-visible {
  text-decoration: underline;
  text-decoration-color: var(--wp--preset--color--gold);
  text-decoration-thickness: 2px;
}

/* WordPress stamps aria-current="page" on the matching link — the active state
   rides the semantic attribute instead of a maintained class list. */
.telos-header .wp-block-navigation a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-color: var(--wp--preset--color--gold);
  text-decoration-thickness: 2px;
}

/* The Resources toggle is a real <button>; make it read as a nav item. */
.telos-header .wp-block-navigation-submenu__toggle {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

/* The dropdown panel. Paper surface, ink links (12.6:1), square corners per the
   brand's 2px radius language. Core positions and toggles it; this only skins it. */
.telos-header .wp-block-navigation__submenu-container {
  background: var(--wp--preset--color--paper) !important;
  border: 1px solid var(--wp--preset--color--teal-light);
  border-radius: 2px;
  box-shadow: 0 12px 32px rgba(37, 60, 82, 0.18);
  min-width: 16rem;
  padding: 0.5rem;
}

.telos-header .wp-block-navigation__submenu-container a {
  color: var(--wp--preset--color--ink) !important;
  padding: 0.625rem 0.875rem;
  width: 100%;
}

.telos-header .wp-block-navigation__submenu-container a:hover,
.telos-header .wp-block-navigation__submenu-container a:focus-visible {
  background: var(--wp--preset--color--teal-pale);
  text-decoration-color: var(--wp--preset--color--ink);
}

/* Mobile overlay: 44px hamburger/close targets; the drawer itself is branded
   navy via the block's overlay colour attributes.

   SCOPED to core's own overlay breakpoint, and the lesson is why: an earlier
   version set display:inline-flex on the open button UNSCOPED. Core hides that
   button on desktop with display:none at min-width:600px — equal specificity —
   so the later-loading theme sheet won and the hamburger rendered on desktop
   alongside the full menu, wrapping the nav onto two rows. Never set display
   on these buttons outside this media query. */
@media (max-width: 599px) {
  .telos-header .wp-block-navigation__responsive-container-open,
  .telos-header .wp-block-navigation__responsive-container-close {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

@media (max-width: 782px) {
  /* Charis SIL at display-sm plus 0.08em tracking does not fit "TELOS WELLNESS"
     on one line on a 390px screen — it measured 209px against a column that also
     has to hold the nav toggle and the CTA.

     Note the mechanism. WordPress emits its font-size preset classes as
     `.has-display-sm-font-size { font-size: ... !important }`, so a plain
     override here loses no matter how specific it is. Rather than answer
     !important with !important, redefine the custom property in this scope: the
     preset rule still wins, it just now resolves to a smaller value. Scoped to
     the site title so nothing else inherits the change. */
  .telos-header .wp-block-site-title {
    --wp--preset--font-size--display-sm: 1.125rem;
  }
  .telos-founder-credit {
    font-size: 0.5625rem;
    letter-spacing: 0.12em;
  }
  .telos-cta .wp-block-button__link {
    padding: 0.75rem 1rem;
    font-size: 0.8125rem;
  }
}

/* ---------------------------------------------------------------------------
   Assessment form. Not a plugin - posts to the Arise API. Contrast values here
   were measured, not guessed: ink #253C52 on teal-pale #DBEAEB is 9.19:1, and
   ink on gold #E7A339 is 5.25:1. Both pass AA comfortably, which matters for a
   40-65 audience the brand guide explicitly flags as needing high contrast.
   --------------------------------------------------------------------------- */

.telos-assessment-form {
  margin-top: var(--wp--preset--spacing--50);
}

.telos-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: var(--wp--preset--spacing--40);
}

.telos-field label {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--wp--preset--color--ink);
}

.telos-optional,
.telos-req {
  font-weight: 400;
  color: var(--wp--preset--color--ink-muted);
}

.telos-field input,
.telos-field textarea {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 1rem;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--wp--preset--color--ink-muted);
  border-radius: 2px;
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--ink);
  width: 100%;
}

/* Help text at 4.5:1 minimum. Light grey helper text is the usual failure here and
   it is exactly the audience least able to absorb it. */
.telos-help {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.875rem;
  color: var(--wp--preset--color--ink-muted);
  margin: 0;
}

/* Errors sit BELOW the input, never as placeholder text. Colour is not the only
   signal - the message itself carries the meaning. */
.telos-error {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.875rem;
  font-weight: 700;
  color: #8a2a1f;
  margin: 0;
}

.telos-submit {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 1rem;
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  background: var(--wp--preset--color--gold);
  border: 0;
  border-radius: 2px;
  padding: 1rem 1.75rem;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.12s ease;
}

.telos-submit:hover {
  background: #d89426;
}

.telos-submit:active {
  transform: translateY(1px);
}

.telos-submit[disabled] {
  opacity: 0.7;
  cursor: progress;
}

.telos-form-note {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.8125rem;
  color: var(--wp--preset--color--ink-muted);
  margin-top: var(--wp--preset--spacing--30);
  max-width: 55ch;
}

.telos-form-status:not(:empty) {
  font-family: var(--wp--preset--font-family--ui);
  font-weight: 700;
  color: #8a2a1f;
  margin-top: var(--wp--preset--spacing--30);
}

.telos-form-success {
  border-left: 4px solid var(--wp--preset--color--gold);
  padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
  background: var(--wp--preset--color--white);
}

.telos-form-success:focus {
  outline: 3px solid var(--wp--preset--color--ink);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   CINEMATIC HERO

   The copy sits on an opaque paper card. That is a contrast decision, not a
   style one: the previous version put white text straight on the photograph
   and leaned on a 100deg scrim, but the scrim decays to 0.18-0.10 alpha on the
   right-hand side, which is exactly where the 01-05 rail lived. Measured
   against the real composited pixels, the rail ran 2.22:1 to 4.01:1 — worse
   than the 2.82:1 CTA this pattern was originally written to fix.

   Ink on paper is 12.6:1 and does not depend on the photograph at all. Swap
   the image, swap in the video, change the crop: the copy stays legible. Keep
   the card opaque.

   The rail is numbers only now, each in a filled navy disc so its contrast is
   likewise independent of what is behind it. The pillar names moved down into
   the journey section, which gives each one a full card.
   --------------------------------------------------------------------------- */

.telos-hero {
  position: relative;
  isolation: isolate;
  min-height: min(92dvh, 860px);
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--wp--preset--color--ink);
}

.telos-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-size: cover;
  background-position: 68% center;
}

/* Two washes with different jobs. The 100deg one gives the card something to sit
   on and keeps the left side brand-navy rather than whatever the photo happens to
   be. The 270deg one darkens the right edge so the rail discs read against a
   consistent field instead of against sunlit grass. */
.telos-hero__wash {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(270deg,
      rgba(37, 60, 82, 0.58) 0%,
      rgba(37, 60, 82, 0.00) 24%),
    linear-gradient(100deg,
      rgba(37, 60, 82, 0.96) 0%,
      rgba(37, 60, 82, 0.88) 34%,
      rgba(37, 60, 82, 0.46) 58%,
      rgba(37, 60, 82, 0.12) 80%,
      rgba(37, 60, 82, 0.08) 100%);
}

.telos-hero__inner {
  position: relative;
  width: 100%;
  max-width: 1152px;
  margin-inline: auto;
  padding: var(--wp--preset--spacing--70) var(--wp--preset--spacing--40);
}

.telos-hero__card {
  background: var(--wp--preset--color--paper);
  max-width: 36rem;
  padding: clamp(1.75rem, 1rem + 2.6vw, 3rem);
  border-radius: 2px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.5);
}

.telos-hero__eyebrow {
  font-family: var(--wp--preset--font-family--ui);
  font-size: var(--wp--preset--font-size--eyebrow);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wp--preset--color--ink-muted);
  margin: 0 0 var(--wp--preset--spacing--40);
}

.telos-hero__title {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  font-size: clamp(2rem, 1.4rem + 2.1vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--wp--preset--color--ink);
  margin: 0;
}

.telos-hero__rule {
  width: 88px;
  height: 3px;
  background: var(--wp--preset--color--gold);
  border: 0;
  margin: var(--wp--preset--spacing--40) 0;
}

.telos-hero__sub {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--wp--preset--color--ink-muted);
  margin: 0 0 var(--wp--preset--spacing--50);
  max-width: 30rem;
}

/* Gold, not teal. White-on-teal is 2.82:1 and navy-on-teal is 4.03:1 — both fail
   AA at button size. Navy on gold is 5.25:1, and the brand guide specifies gold
   for CTAs anyway. */
.telos-hero__cta {
  display: inline-block;
  font-family: var(--wp--preset--font-family--ui);
  font-size: 1rem;
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  background: var(--wp--preset--color--gold);
  text-decoration: none;
  padding: 1rem 1.75rem;
  border-radius: 2px;
  transition: transform 0.12s ease, background-color 0.12s ease;
}
.telos-hero__cta:hover { background: #d89426; color: var(--wp--preset--color--ink); }
.telos-hero__cta:active { transform: translateY(1px); }

/* Ink-muted, NOT teal. Teal on paper is 2.59:1 and fails at every size — the
   staging site shipped that violation and the mock-up reintroduced it. 6.19:1. */
.telos-hero__tagline {
  font-family: var(--wp--preset--font-family--display);
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.15;
  padding-bottom: 0.08em; /* descender clearance for the italic 'g' */
  color: var(--wp--preset--color--ink-muted);
  margin: var(--wp--preset--spacing--40) 0 0;
}

/* --- The path rail -------------------------------------------------------- */

.telos-hero__rail {
  position: absolute;
  right: clamp(0.75rem, 1.6vw, 2rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--wp--preset--spacing--40);
}

/* Paper, not gold. Gold is a light accent (relative luminance ~0.42) and against
   the darkened right edge it measured 3.07:1 — the one thing on this hero that
   still failed after the card landed. Paper on the same backdrop is 6.2:1.
   Gold stays reserved for the active disc, which passes at 5.25:1 and now reads
   as "you are here" rather than competing with the caption. */
.telos-hero__rail-label {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--wp--preset--color--paper);
  margin: 0;
}

.telos-hero__rail-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}

.telos-hero__rail-list li {
  position: relative;
  padding: 0.45rem 0;
}

/* connector between discs */
.telos-hero__rail-list li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% - 0.45rem);
  height: 0.9rem;
  width: 1px;
  background: rgba(247, 245, 242, 0.35);
}

/* Solid fill, not a translucent one. This is what makes the number's contrast
   independent of the photograph behind it. */
.telos-hero__rail-list span {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: rgba(37, 60, 82, 0.92);
  border: 1px solid rgba(247, 245, 242, 0.5);
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.625rem;
  font-weight: 700;
  color: var(--wp--preset--color--paper);
}

.telos-hero__rail-list li.is-current span {
  background: var(--wp--preset--color--gold);
  border-color: var(--wp--preset--color--gold);
  color: var(--wp--preset--color--ink);
}

@media (max-width: 900px) {
  .telos-hero__wash {
    background: linear-gradient(180deg,
      rgba(37, 60, 82, 0.92) 0%, rgba(37, 60, 82, 0.80) 55%, rgba(37, 60, 82, 0.68) 100%);
  }
  .telos-hero__card { max-width: none; }
  /* The rail would crowd the card at this width, and the five stages are spelled
     out in full immediately below. */
  .telos-hero__rail { display: none; }
}

/* ---------------------------------------------------------------------------
   THE JOURNEY — the trail video section.

   Read the enhancement contract before touching this.

   The BASE state (no .is-enhanced) is the real content: five waypoint cards in
   document order over a still image. It is what ships in the HTML, what a
   phone gets, what someone with prefers-reduced-motion gets, and what a
   visitor with JS off gets. It must stay readable on its own.

   Everything sticky or scrubbed is nested under .is-enhanced, which only
   assets/js/journey-scroll.js adds, and only above 900px with reduced-motion
   unset. Keeping the nesting strict means a CSS edit alone cannot leave the
   section stuck in a broken half-enhanced state.
   --------------------------------------------------------------------------- */

.telos-journey {
  position: relative;
  background: var(--wp--preset--color--ink);
}

.telos-journey__stage {
  position: relative;
  overflow: hidden;
}

.telos-journey__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Each card carries its own scene in the base state, so a phone, a reduced-motion
   reader and a JS-off reader all get the five places rather than five text blocks
   on one background. 410KB for the set, lazy-loaded, and it is the whole mobile
   experience. */
.telos-journey__card-img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin-bottom: var(--wp--preset--spacing--40);
}

/* Enhanced, the canvas is the imagery and the per-card stills would be a second
   copy of the same five scenes. */
.telos-journey.is-enhanced .telos-journey__card-img { display: none; }

/* No object-fit here: cover framing happens in the draw call, because the backing
   store is sized in device pixels and object-fit would fight it. */
.telos-journey__canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  display: block;
}
.telos-journey.is-enhanced .telos-journey__canvas { opacity: 1; }

.telos-journey__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(90deg,
      rgba(37, 60, 82, 0.90) 0%,
      rgba(37, 60, 82, 0.62) 42%,
      rgba(37, 60, 82, 0.30) 70%,
      rgba(37, 60, 82, 0.55) 100%);
}

.telos-journey__frame {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: 1152px;
  margin-inline: auto;
  padding: var(--wp--preset--spacing--70) var(--wp--preset--spacing--40);
}

.telos-journey__eyebrow {
  font-family: var(--wp--preset--font-family--ui);
  font-size: var(--wp--preset--font-size--eyebrow);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wp--preset--color--gold);
  margin: 0 0 var(--wp--preset--spacing--30);
}

.telos-journey__title {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  font-size: var(--wp--preset--font-size--display-md);
  line-height: 1.15;
  color: var(--wp--preset--color--paper);
  margin: 0 0 var(--wp--preset--spacing--60);
  max-width: 22ch;
}

.telos-journey__cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--wp--preset--spacing--40);
}

/* 0.94 alpha is effectively opaque: worst case over a blown-out highlight it
   composites to about rgb(50,72,92), which still puts paper text near 8.9:1. */
.telos-journey__card {
  background: rgba(37, 60, 82, 0.94);
  border-left: 3px solid var(--wp--preset--color--gold);
  padding: var(--wp--preset--spacing--50);
  max-width: 34rem;
}

.telos-journey__waypoint {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--wp--preset--spacing--30);
  font-family: var(--wp--preset--font-family--ui);
  font-size: var(--wp--preset--font-size--eyebrow);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wp--preset--color--gold);
  margin: 0 0 var(--wp--preset--spacing--30);
}
.telos-journey__waypoint-of { color: rgba(247, 245, 242, 0.75); }

.telos-journey__name {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  font-size: var(--wp--preset--font-size--display-sm);
  line-height: 1.2;
  color: var(--wp--preset--color--paper);
  margin: 0;
}

.telos-journey__tag {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.875rem;
  color: var(--wp--preset--color--teal-light);
  margin: 0.25rem 0 var(--wp--preset--spacing--30);
}

.telos-journey__body {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 1rem;
  line-height: 1.65;
  color: rgba(247, 245, 242, 0.90);
  margin: 0;
  max-width: 46ch;
}

.telos-journey__note {
  font-family: var(--wp--preset--font-family--display);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.15;
  padding-bottom: 0.08em;
  color: var(--wp--preset--color--gold);
  margin: var(--wp--preset--spacing--40) 0 0;
}

/* The rail and the progress bar mirror state the cards already carry, so they
   are decorative and hidden until there is scroll state to mirror. */
.telos-journey__rail,
.telos-journey__progress { display: none; }

/* --- enhanced: sticky scroll-scrub ---------------------------------------- */

.telos-journey.is-enhanced .telos-journey__scroll {
  height: calc((var(--telos-journey-steps, 5) + 1) * 100dvh);
}

/* The stage pins BELOW the sticky header, never under it. journey-scroll.js
   measures the real header height into --telos-header-offset at enable() and on
   resize, so no magic number can drift out of sync with the header's actual
   size. With JS off the var is unset, the fallback is 0, and nothing is sticky
   anyway because .is-enhanced never gets added. */
.telos-journey.is-enhanced .telos-journey__stage {
  position: sticky;
  top: var(--telos-header-offset, 0px);
  height: calc(100dvh - var(--telos-header-offset, 0px));
  display: flex;
  align-items: center;
}

.telos-journey.is-enhanced .telos-journey__frame {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--wp--preset--spacing--60);
  align-items: center;
}

.telos-journey.is-enhanced .telos-journey__head {
  grid-column: 1 / -1;
  align-self: start;
}

.telos-journey.is-enhanced .telos-journey__title {
  margin-bottom: 0;
  font-size: var(--wp--preset--font-size--display-sm);
}

/* All five cards occupy the same cell; only the current one is shown.
   visibility:hidden (not just opacity) keeps the other four out of the
   accessibility tree and out of the tab order. */
.telos-journey.is-enhanced .telos-journey__cards {
  display: grid;
  gap: 0;
}

.telos-journey.is-enhanced .telos-journey__card {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.75rem);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0.35s;
}

.telos-journey.is-enhanced .telos-journey__card.is-current {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.telos-journey.is-enhanced .telos-journey__rail {
  display: block;
  justify-self: end;
}

.telos-journey__rail-label {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--wp--preset--color--gold);
  margin: 0 0 var(--wp--preset--spacing--30);
}

.telos-journey__rail-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.telos-journey__rail-list li {
  display: grid;
  grid-template-columns: 1.75rem 1fr;
  align-items: center;
  gap: 0.75rem;
  position: relative;
  padding: 0.5rem 0;
}

.telos-journey__rail-list li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 0.875rem;
  top: 1.85rem;
  bottom: -0.35rem;
  width: 1px;
  background: rgba(247, 245, 242, 0.3);
}

.telos-journey__rail-num {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: rgba(37, 60, 82, 0.92);
  border: 1px solid rgba(247, 245, 242, 0.45);
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.5625rem;
  font-weight: 700;
  color: var(--wp--preset--color--paper);
}

.telos-journey__rail-name {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.8125rem;
  font-weight: 700;
  /* 0.72 alpha paper over the 0.55 right-edge scrim, not over bare photograph.
     This is the pairing the old hero rail got wrong. */
  color: rgba(247, 245, 242, 0.72);
  line-height: 1.2;
}

.telos-journey__rail-list li.is-done .telos-journey__rail-num {
  border-color: var(--wp--preset--color--gold);
  color: var(--wp--preset--color--gold);
}

.telos-journey__rail-list li.is-current .telos-journey__rail-num {
  background: var(--wp--preset--color--gold);
  border-color: var(--wp--preset--color--gold);
  color: var(--wp--preset--color--ink);
}

.telos-journey__rail-list li.is-current .telos-journey__rail-name {
  color: var(--wp--preset--color--paper);
}

.telos-journey.is-enhanced .telos-journey__progress {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  height: 3px;
  background: rgba(247, 245, 242, 0.16);
}

.telos-journey__progress span {
  display: block;
  height: 100%;
  background: var(--wp--preset--color--gold);
  transform: scaleX(0);
  transform-origin: left center;
}

/* ---------------------------------------------------------------------------
   REVIEW BOARD — TEMPORARY, DELETE BEFORE LAUNCH

   Styles for patterns/review-board.php, which exists only so the team can
   compare the two visual directions. Goes when the direction is chosen, along
   with the pattern, the /review page and assets/review/.
   --------------------------------------------------------------------------- */

.telos-review {
  background: var(--wp--preset--color--paper);
  padding: var(--wp--preset--spacing--70) var(--wp--preset--spacing--40);
}

.telos-review__intro,
.telos-review__panel {
  max-width: 1152px;
  margin-inline: auto;
}

.telos-review__panel {
  margin-top: var(--wp--preset--spacing--80);
  padding-top: var(--wp--preset--spacing--60);
  border-top: 1px solid var(--wp--preset--color--teal-light);
}

.telos-review__kicker,
.telos-review__label {
  font-family: var(--wp--preset--font-family--ui);
  font-size: var(--wp--preset--font-size--eyebrow);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wp--preset--color--ink-muted);
  margin: 0 0 var(--wp--preset--spacing--30);
}

.telos-review__title,
.telos-review__name {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  margin: 0 0 var(--wp--preset--spacing--30);
}
.telos-review__title { font-size: var(--wp--preset--font-size--display-md); line-height: 1.15; }
.telos-review__name  { font-size: var(--wp--preset--font-size--display-sm); line-height: 1.25; }

.telos-review__lede,
.telos-review__body {
  font-family: var(--wp--preset--font-family--ui);
  line-height: 1.65;
  color: var(--wp--preset--color--ink-muted);
  max-width: 62ch;
  margin: 0 0 var(--wp--preset--spacing--50);
}
.telos-review__lede { font-size: var(--wp--preset--font-size--lead); }

.telos-review__video,
.telos-review__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
  margin-bottom: var(--wp--preset--spacing--30);
}

.telos-review__note {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--wp--preset--color--ink-muted);
  max-width: 62ch;
  margin: 0 0 var(--wp--preset--spacing--60);
}
.telos-review__note strong { color: #8a2a1f; }

.telos-review__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--wp--preset--spacing--40);
}

.telos-review__cell { margin: 0; }
.telos-review__cell img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 2px;
}
.telos-review__cell figcaption {
  font-family: var(--wp--preset--font-family--ui);
  font-size: 0.875rem;
  color: var(--wp--preset--color--ink-muted);
  margin-top: var(--wp--preset--spacing--20);
}

.telos-review__decisions {
  font-family: var(--wp--preset--font-family--ui);
  line-height: 1.65;
  color: var(--wp--preset--color--ink-muted);
  max-width: 62ch;
  padding-left: 1.25rem;
}
.telos-review__decisions li { margin-bottom: var(--wp--preset--spacing--30); }
.telos-review__decisions strong { color: var(--wp--preset--color--ink); }

/* ---------------------------------------------------------------------------
   FAQ. Native <details>/<summary> — keyboard accessible, works with JS off.
   --------------------------------------------------------------------------- */

.telos-faq-item {
  border-bottom: 1px solid var(--wp--preset--color--teal-light);
}
.telos-faq-item:first-child {
  border-top: 1px solid var(--wp--preset--color--teal-light);
}

.telos-faq-item summary {
  font-family: var(--wp--preset--font-family--display);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--wp--preset--color--ink);
  padding: 1.25rem 2.5rem 1.25rem 0;
  cursor: pointer;
  list-style: none;
  position: relative;
}
/* Remove the default disclosure triangle; draw our own so we control its side and colour. */
.telos-faq-item summary::-webkit-details-marker { display: none; }
.telos-faq-item summary::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--wp--preset--color--ink-muted);
  transition: transform 0.15s ease;
}
.telos-faq-item[open] summary::after {
  content: "\2212"; /* minus */
}

.telos-faq-item summary:focus-visible {
  outline: 3px solid var(--wp--preset--color--ink);
  outline-offset: 2px;
}

.telos-faq-answer {
  padding: 0 0 1.5rem 0;
}
.telos-faq-answer p {
  color: var(--wp--preset--color--ink-muted);
  line-height: 1.65;
  max-width: 65ch;
  margin: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
