/* ==========================================================================
   Estudio Digital — page-level components for the services, service-detail,
   portfolio and blog layouts.

   The reference stylesheet already carries the structural rules for these
   sections (.lc-card, .faq-wrap, .industries-card, .blog-wrapper …). What
   follows is only what the WordPress build adds on top: native <details>
   accordions, client-side filter states, and a few missing niceties.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Filter tabs
   -------------------------------------------------------------------------- */

.ed-filter-tabs { flex-wrap: wrap; }

/* These are <button> elements where the reference used <a>, so only the parts
   a button gets for free need resetting. Everything visual — the outline, the
   pill radius, the padding, the type size — is already on `.tab-menu` in the
   compiled stylesheet, and resetting `border` and `font` here was what flattened
   them into plain text. */
.ed-filter-tabs .tab-menu {
  appearance: none;
  font-family: inherit;
  font-weight: inherit;
  cursor: pointer;
}

.ed-filter-tabs .tab-menu.is-active,
.ed-filter-tabs .tab-menu.w--current {
  background-color: var(--ed-ink);
  color: #fff;
  border-color: var(--ed-ink);
}

.ed-filter-empty {
  font-family: var(--ed-font-body);
  color: var(--ed-muted);
  padding: 3rem 0;
  font-size: 1.05rem;
}

.ed-filter-item[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   FAQ — native <details>, so it works with no JavaScript
   -------------------------------------------------------------------------- */

details.faq-wrap { cursor: pointer; }

details.faq-wrap > summary {
  list-style: none;
  cursor: pointer;
}
details.faq-wrap > summary::-webkit-details-marker { display: none; }
details.faq-wrap > summary::marker { content: ''; }

/* The plus turns into a cross. Both declarations are !important because the
   compiled interaction runtime writes its own rotation into the style
   attribute off its own click counter; tying the icon to [open] with a weight
   that beats an inline style is what keeps it honest even if that handler ever
   fires. */
.faq-question .faq-icon {
  flex: 0 0 auto;
  display: inline-flex;
  transition: transform .35s var(--ed-ease);
  transform: rotate(0deg) !important;
}
details.faq-wrap[open] .faq-question .faq-icon { transform: rotate(45deg) !important; }

/* The panel height is animated from JavaScript (initFaq), because <details>
   cannot transition its own open state and a max-height cap only looks right
   for one particular answer length. With JavaScript off, <details> still shows
   and hides the panel on its own — it just does it instantly. */
details.faq-wrap .faq-answer-wrap { overflow: hidden; }

.faq-answer-inner-wrap { padding-top: 1rem; }
.faq-answer-inner-wrap .paragraph { color: var(--ed-muted); }

@media (prefers-reduced-motion: reduce) {
  details.faq-wrap[open] .faq-question .faq-icon { transition: none; }
}

/* --------------------------------------------------------------------------
   Lifecycle track

   The track moves sideways as the page scrolls down, so it must not also be a
   scrollbox — the reference hides its overflow and drives the movement from
   scroll position. See initLifecycleTrack() in assets/js/app.js, which pins the
   section while the cards travel, so a card is never half-shown when the
   section leaves the viewport.
   -------------------------------------------------------------------------- */

.lc-cards-wrap {
  overflow: hidden;
}

/* The reference pads the start of the track. Matching that at the end stops the
   last card finishing hard against the edge, which is what made the arrival
   feel forced rather than settled. */
.lc-cards-inner { padding-right: 60px; }

@media screen and (max-width: 991px) {
  .lc-cards-inner { padding-right: 20px; }
}

/* Without JavaScript, and on phones where pinning is more annoying than it is
   useful, the track falls back to an ordinary swipeable row with no visible
   scrollbar. */
.lc-cards-wrap.ed-track-fallback {
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.lc-cards-wrap.ed-track-fallback::-webkit-scrollbar { display: none; }
.lc-cards-wrap.ed-track-fallback > .lc-cards-inner > .lc-card { scroll-snap-align: center; }

/* Each card fades its tinted panel in as it reaches the middle of the viewport
   and back out on the way past, which is what the reference interaction does. */
.lc-card-bg {
  opacity: 0;
  transition: opacity .45s var(--ed-ease), background-color .45s var(--ed-ease);
}
.lc-cards-wrap.ed-track-fallback .lc-card-bg { opacity: 1; }

.lc-card-img-wrap svg,
.lc-card-img-wrap img { width: 64px; height: 64px; }

.lc-card-content { position: relative; z-index: 1; }
.lc-card-content .paragraph { color: var(--ed-muted); }

/* --------------------------------------------------------------------------
   Industries
   -------------------------------------------------------------------------- */

.industries-card-wrap { cursor: pointer; }
.industries-arrow-wrap svg { width: 60%; height: 60%; }

/* --------------------------------------------------------------------------
   Feature rows
   -------------------------------------------------------------------------- */

.services-image-wrap {
  border-radius: clamp(16px, 2vw, 40px);
  overflow: hidden;
  aspect-ratio: 4 / 3;
}
.services-image-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }

.service-content-wrap .heading-h3 { display: block; }
.service-content-wrap a.heading-h3 { text-decoration: none; color: inherit; }
.service-content-wrap a.heading-h3:hover { color: var(--ed-accent); }

/* --------------------------------------------------------------------------
   Blog cards
   -------------------------------------------------------------------------- */

.blog-wrapper { display: flex; flex-direction: column; height: 100%; }
.blog-content-wrap { display: flex; flex-direction: column; flex: 1; }

/* --------------------------------------------------------------------------
   Portfolio cards
   -------------------------------------------------------------------------- */

.main-portfolio-card { display: block; position: relative; }
.main-portfolio-card .image { width: 100%; height: 100%; object-fit: cover; }

.rel-wrap a.portfolio-card { text-decoration: none; color: inherit; display: block; }

/* --------------------------------------------------------------------------
   Service-detail sticky headline
   -------------------------------------------------------------------------- */

.h-section-wrap .button { margin-top: 2rem; }

/* The glass overlay is decorative; never let it eat pointer events. */
.ab-bg-wrap, .glass-wrap { pointer-events: none; }

/* --------------------------------------------------------------------------
   Homepage service cards — one per row on phones

   The compiled stylesheet drops the sticky horizontal track into a two-column
   grid below 767px, which squeezes each card too narrow to read. The reference
   shows one card per row at this size.
   -------------------------------------------------------------------------- */

@media screen and (max-width: 767px) {
  .services-card-inner {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: 1rem;
  }
  .services-card { width: 100% !important; }
}

/* --------------------------------------------------------------------------
   About page

   The hero is headline-only: no kicker, no breadcrumb, matching the reference.
   -------------------------------------------------------------------------- */

.ed-about-hero { padding-top: 0; }

.ed-about-hero .image-wrapper {
  border-radius: clamp(16px, 2vw, 40px);
  overflow: hidden;
}
.ed-about-hero .image-wrapper img { width: 100%; height: auto; display: block; }

/* Counters row */
.counter-wrap .p-count-wrap { display: flex; align-items: baseline; }
.counter-wrap.center { text-align: center; }
.counter-wrap.center .p-count-wrap { justify-content: center; }
.counter-wrap.right { text-align: right; }
.counter-wrap.right .p-count-wrap { justify-content: flex-end; }

@media screen and (max-width: 767px) {
  .grid-3x1.less-gap { display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
  .counter-wrap,
  .counter-wrap.center,
  .counter-wrap.right { text-align: left; }
  .counter-wrap .p-count-wrap { justify-content: flex-start; }
}

/* --------------------------------------------------------------------------
   Closing sticky phrase

   .wl-z-1/2/3 carry no rules in the compiled stylesheet — they are positioned
   entirely by the interaction data. Give them a sane resting state so they are
   not stranded mid-line if the runtime has not bound yet.
   -------------------------------------------------------------------------- */

.ed-sticky-words .us-wl-buzz-wrapper { justify-content: center; }

.wl-z-1, .wl-z-2, .wl-z-3 {
  position: absolute;
  top: 0;
  right: 0;
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .ed-sticky-words .us-sticky-wrap { position: static; }
}

/* On the service detail rows the image keeps its own proportions inside the
   60px-radius wrapper, rather than the fixed 4:3 crop the services index uses. */
.grid-2x1 > .image-wrapper img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Below the two-column breakpoint the reference pins the image of a flipped row
   into the first grid cell, so every row reads image-then-text on a phone
   instead of alternating. It does that with generated node ids; this is the
   same rule expressed once. */
@media screen and (max-width: 991px) {
  .grid-2x1 > .image-wrapper:last-child,
  .grid-2x1 > .services-image-wrap:last-child {
    grid-area: 1 / 1 / 2 / 2;
  }
}

/* --------------------------------------------------------------------------
   Related work — sticky stacking cards

   The reference gives these two variants its own clients' branding: one card
   is painted that brand's red, the other loads a piece of their artwork as a
   background image. The sticky stacking is the part worth keeping, so the
   positioning below repeats it and the surfaces are ours.
   -------------------------------------------------------------------------- */

.ed-rel-card {
  border-radius: clamp(24px, 3vw, 60px);
  overflow: hidden;
}

.ed-rel-card--ink {
  background-color: var(--ed-ink);
  background-image: var(--ed-gradient-diag);
  position: sticky;
  top: 2vw;
}

.ed-rel-card--paper {
  background-color: var(--ed-paper-soft);
  position: sticky;
  top: 4vw;
}

@media screen and (max-width: 991px) {
  /* Stacking a full-height card under a fixed header is more confusing than
     helpful on a phone, so the cards simply follow one another. */
  .ed-rel-card--ink,
  .ed-rel-card--paper { position: relative; top: auto; }
}

/* --------------------------------------------------------------------------
   Contact — reach us directly

   One studio, so this is three cards rather than a row of offices: where we
   are, what to call, what to email. Same treatment as the lifecycle cards —
   soft tint, generous radius, icon over a heading — but sitting in a plain
   grid, because nothing on this page should scroll sideways.
   -------------------------------------------------------------------------- */

.ed-contact-direct { margin-top: clamp(3rem, 6vw, 6rem); }

.ed-contact-direct__grid {
  display: grid;
  gap: clamp(1rem, 1.6vw, 1.5rem);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-top: clamp(1.75rem, 3vw, 2.75rem);
}

.ed-contact-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(.7rem, 1vw, 1rem);
  padding: clamp(1.5rem, 2.4vw, 2.4rem);
  border-radius: clamp(24px, 3vw, 40px);
  transition: transform .4s var(--ed-ease), box-shadow .4s var(--ed-ease);
}

/* The same tints the lifecycle cards use, in the same order. */
.ed-contact-card._1 { background-color: rgba(236, 132, 34, .16); }
.ed-contact-card._2 { background-color: rgba(217, 32, 192, .14); }
.ed-contact-card._3 { background-color: rgba(107, 32, 208, .14); }

.ed-contact-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 24px 55px -22px rgba(0, 0, 0, .35);
}

.ed-contact-card__icon {
  width: clamp(40px, 4vw, 56px);
  height: clamp(40px, 4vw, 56px);
  margin-bottom: clamp(.5rem, 1.5vw, 1.5rem);
}
.ed-contact-card__icon svg { width: 100%; height: 100%; display: block; }

.ed-contact-card__label {
  font-family: var(--ed-font-body);
  font-size: clamp(1.35rem, 2vw, 1.9rem);
  line-height: 1.1;
  font-weight: 400;
  margin: 0;
  color: var(--ed-ink);
}

.ed-contact-card__value {
  font-family: var(--ed-font-body);
  font-size: clamp(.98rem, 1.1vw, 1.08rem);
  line-height: 1.7;
  color: var(--ed-muted);
  text-decoration: none;
  margin: 0;
}

a.ed-contact-card__value:hover { color: var(--ed-accent); }

/* --------------------------------------------------------------------------
   Article detail — two columns with a sidebar

   Follows the supplied blog-detail reference: article on the left with its
   featured image, meta row and body; search, categories, recent posts and tags
   on the right. The sidebar drops under the article below the tablet
   breakpoint rather than squeezing into a second column.
   -------------------------------------------------------------------------- */

.ed-article__layout {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}

@media screen and (max-width: 991px) {
  .ed-article__layout { grid-template-columns: minmax(0, 1fr); }
}

.ed-article__media {
  border-radius: clamp(16px, 2vw, 30px);
  overflow: hidden;
  margin-bottom: clamp(1.25rem, 2vw, 1.75rem);
}
.ed-article__media img { width: 100%; height: auto; display: block; }

.ed-article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(.9rem, 2vw, 1.75rem);
  padding-bottom: clamp(1.25rem, 2vw, 1.75rem);
  margin-bottom: clamp(1.5rem, 2.5vw, 2.25rem);
  border-bottom: 1px solid rgba(0, 0, 0, .1);
  font-family: var(--ed-font-body);
  font-size: .92rem;
  color: var(--ed-muted);
}

.ed-article__meta-item {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: inherit;
  text-decoration: none;
}
.ed-article__meta-item svg { width: 1.05em; height: 1.05em; color: var(--ed-accent); }
a.ed-article__meta-item:hover { color: var(--ed-accent); }

/* ---- Body furniture the posts use ---------------------------------------- */

.ed-prose blockquote {
  position: relative;
  margin: clamp(1.75rem, 3vw, 2.75rem) 0;
  padding: clamp(1.5rem, 3vw, 2.5rem);
  border-radius: clamp(16px, 2vw, 28px);
  background: linear-gradient(135deg, rgba(236, 132, 34, .10), rgba(217, 32, 192, .10) 55%, rgba(107, 32, 208, .10));
  border-left: 3px solid var(--ed-accent);
  font-family: var(--ed-font-body);
  font-weight: 500;
  font-size: clamp(1.1rem, 1.7vw, 1.45rem);
  line-height: 1.45;
}
.ed-prose blockquote p { margin: 0; }
.ed-prose blockquote cite {
  display: block;
  margin-top: 1rem;
  font-family: var(--ed-font-body);
  font-size: .9rem;
  font-style: normal;
  color: var(--ed-muted);
}

/* The checklist box: a tinted panel with a marked list, as the reference has. */
.ed-prose .ed-checklist {
  margin: clamp(1.75rem, 3vw, 2.75rem) 0;
  padding: clamp(1.4rem, 2.6vw, 2.25rem);
  border-radius: clamp(16px, 2vw, 28px);
  background: var(--ed-paper-soft);
}
.ed-prose .ed-checklist ul { list-style: none; padding: 0; margin: 0; }
.ed-prose .ed-checklist li {
  position: relative;
  padding-left: 2rem;
  margin: 0 0 .8rem;
  line-height: 1.6;
}
.ed-prose .ed-checklist li:last-child { margin-bottom: 0; }
.ed-prose .ed-checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .45em;
  width: .95rem;
  height: .55rem;
  border-left: 2.5px solid var(--ed-accent);
  border-bottom: 2.5px solid var(--ed-accent);
  transform: rotate(-45deg);
}

.ed-prose figure { margin: clamp(1.75rem, 3vw, 2.75rem) 0; }
.ed-prose figure img { border-radius: clamp(14px, 1.8vw, 24px); }

.ed-article__tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-top: clamp(2rem, 3.5vw, 3rem);
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid rgba(0, 0, 0, .1);
}
.ed-article__tags-label {
  font-family: var(--ed-font-body);
  font-weight: 600;
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-right: .35rem;
}
.ed-article__tags a {
  font-family: var(--ed-font-body);
  font-size: .88rem;
  padding: .4em 1em;
  border: 1px solid rgba(0, 0, 0, .18);
  border-radius: 999px;
  color: inherit;
  text-decoration: none;
  transition: border-color .25s var(--ed-ease), background-color .25s var(--ed-ease), color .25s var(--ed-ease);
}
.ed-article__tags a:hover {
  background: var(--ed-ink);
  border-color: var(--ed-ink);
  color: #fff;
}

/* ---- Sidebar ------------------------------------------------------------- */

.ed-article__aside {
  display: flex;
  flex-direction: column;
  gap: clamp(1.25rem, 2vw, 1.75rem);
  position: sticky;
  top: 2rem;
  font-family: var(--ed-font-body);
}

@media screen and (max-width: 991px) {
  .ed-article__aside { position: static; }
}

.ed-widget {
  padding: clamp(1.25rem, 2vw, 1.75rem);
  border-radius: clamp(14px, 1.8vw, 24px);
  background: var(--ed-paper-soft);
}

.ed-widget__title {
  font-family: var(--ed-font-body);
  font-size: 1.15rem;
  line-height: 1.2;
  margin: 0 0 1.1rem;
}

.ed-widget__search { display: flex; gap: .5rem; }
.ed-widget__search input {
  flex: 1;
  min-width: 0;
  padding: .7rem .9rem;
  font: inherit;
  border: 1px solid rgba(0, 0, 0, .14);
  border-radius: .6rem;
  background: #fff;
}
.ed-widget__search input:focus {
  outline: none;
  border-color: var(--ed-accent);
}
.ed-widget__search button {
  flex: 0 0 auto;
  width: 2.75rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: .6rem;
  background: var(--ed-ink);
  color: #fff;
  cursor: pointer;
  transition: background-color .25s var(--ed-ease);
}
.ed-widget__search button:hover { background: var(--ed-accent); }
.ed-widget__search svg { width: 1.1rem; height: 1.1rem; }

.ed-widget__cats { list-style: none; margin: 0; padding: 0; }
.ed-widget__cats li + li { border-top: 1px solid rgba(0, 0, 0, .08); }
.ed-widget__cats a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .7rem 0;
  color: inherit;
  text-decoration: none;
  transition: color .25s var(--ed-ease);
}
.ed-widget__cats a:hover { color: var(--ed-accent); }
.ed-widget__cat-count { color: var(--ed-muted); font-size: .88rem; }

.ed-widget__posts { list-style: none; margin: 0; padding: 0; }
.ed-widget__posts li + li { margin-top: 1rem; }
.ed-widget__posts a {
  display: flex;
  gap: .85rem;
  align-items: center;
  color: inherit;
  text-decoration: none;
}
.ed-widget__post-media {
  flex: 0 0 auto;
  width: 68px;
  height: 68px;
  border-radius: .7rem;
  overflow: hidden;
}
.ed-widget__post-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ed-widget__post-text { display: flex; flex-direction: column; gap: .25rem; }
.ed-widget__post-date { font-size: .8rem; color: var(--ed-muted); }
.ed-widget__post-title { font-size: .95rem; line-height: 1.35; }
.ed-widget__posts a:hover .ed-widget__post-title { color: var(--ed-accent); }

.ed-widget__tags { display: flex; flex-wrap: wrap; gap: .45rem; }
.ed-widget__tags a {
  font-size: .85rem;
  padding: .35em .9em;
  border: 1px solid rgba(0, 0, 0, .16);
  border-radius: 999px;
  color: inherit;
  text-decoration: none;
  transition: background-color .25s var(--ed-ease), border-color .25s var(--ed-ease), color .25s var(--ed-ease);
}
.ed-widget__tags a:hover {
  background: var(--ed-ink);
  border-color: var(--ed-ink);
  color: #fff;
}

.ed-widget--cta {
  background: var(--ed-ink);
  background-image: var(--ed-gradient-diag);
  color: #fff;
}
.ed-widget--cta .ed-widget__title { color: #fff; }
.ed-widget--cta p { margin: 0 0 1.25rem; line-height: 1.6; color: rgba(255, 255, 255, .86); }
.ed-widget__button {
  display: inline-block;
  padding: .8em 1.6em;
  border-radius: 999px;
  background: #fff;
  color: var(--ed-ink);
  font-weight: 600;
  text-decoration: none;
  transition: transform .25s var(--ed-ease);
}
.ed-widget__button:hover { transform: translateY(-2px); }

/* ==========================================================================
   Brand strategy sections

   Rendered from inc/brand-strategy.php by inc/sections-brand.php.

   These reuse the lifecycle card wholesale — .lc-card, .lc-card-img-wrap,
   .lc-card-content, .lc-card-bg — so the radius, padding, type scale and logo
   tints are the track's, not a second set that looks nearly the same. The only
   difference is the layout around them: a grid instead of a horizontal track,
   which means overriding the track's fixed card width and nothing else.
   ========================================================================== */

.ed-card-grid {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.ed-card-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.ed-card-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); }

/* The track sizes its cards at 34vw and lays them out in a row. In a grid the
   column does the sizing, so that has to come off. */
.ed-card-grid .lc-card {
  width: auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(1rem, 2vw, 1.75rem);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  border-radius: clamp(28px, 3.5vw, 44px);
}

/* The track fades its backgrounds in on scroll. These are static, so they are
   simply on, tinted by position from the shared logo palette. */
.ed-card-grid .lc-card-bg { opacity: 1; }

.ed-card-grid .lc-card:nth-child(4n + 1) .lc-card-bg { background-color: var(--ed-tint-1); }
.ed-card-grid .lc-card:nth-child(4n + 2) .lc-card-bg { background-color: var(--ed-tint-2); }
.ed-card-grid .lc-card:nth-child(4n + 3) .lc-card-bg { background-color: var(--ed-tint-3); }
.ed-card-grid .lc-card:nth-child(4n + 4) .lc-card-bg { background-color: var(--ed-tint-4); }

.ed-card-grid .lc-card-img-wrap { margin-bottom: 0; }

.ed-card-grid .lc-card-content { gap: clamp(.6rem, 1.2vw, 1rem); }

/* The card heading is 3vw in the track, sized for a 34vw card. In a narrower
   grid column that overflows, so it steps down to the same scale the track
   lands on at tablet width. */
/* Card type is set on the viewport ladder further down this file, with the
   theme's own breakpoint steps. Nothing sizes cards here. */

/* The number sits where the track puts its icon, at the icon's weight. */
.ed-card__num {
  display: block;
  font-family: var(--ed-font-body);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: .1em;
  color: var(--ed-ink);
  opacity: .45;
}

/* Pain points are quoted speech, so the heading carries the quote and drops the
   weight a little to read as a voice rather than a title. */
.ed-card--quote .heading-h3 {
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  line-height: 1.4;
}

/* ---- Mission and vision -------------------------------------------------- */

.ed-card--statement { justify-content: flex-start; }

.ed-card--statement .ed-kicker { margin-bottom: .35rem; }

.ed-card-grid .ed-card__statement {
  margin: 0;
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.25;
  color: var(--ed-ink);
  text-wrap: balance;
}

/* ---- The promise --------------------------------------------------------- */

.ed-promise {
  margin-top: clamp(1.25rem, 2.5vw, 2.25rem);
  padding: clamp(2rem, 4vw, 3.25rem);
  border-radius: clamp(28px, 3.5vw, 44px);
  background-color: var(--ed-ink);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}

.ed-promise .ed-kicker { color: var(--ed-accent-light); }

.ed-promise__title {
  margin: .5rem 0 0;
  font-size: clamp(1.35rem, 2.2vw, 1.9rem);
  line-height: 1.25;
  color: #fff;
  text-wrap: balance;
}

.ed-promise__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.ed-promise__list li {
  position: relative;
  padding-left: 1.6rem;
  font-family: var(--ed-font-body);
  font-size: 1.02rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, .9);
}

.ed-promise__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .62em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ed-accent);
}


/* ---- Section intros ------------------------------------------------------ */

.ed-difference__lede {
  margin-top: 1.25rem;
  max-width: 54ch;
}

@media (prefers-reduced-motion: reduce) {

}

/* ==========================================================================
   Brand sections — the repositioned site

   The card grid, promise panel and statement styles above are reused as-is.
   What follows is only the shapes this structure adds: the connected chain,
   the capability list, plans, add-ons and the FAQ.
   ========================================================================== */

.ed-section__lede {
  margin-top: 1.25rem;
  max-width: 56ch;
}

.ed-problem__kicker {
  margin-top: 1rem;
  max-width: 52ch;
  font-weight: 500;
  color: var(--ed-ink);
}

/* ---- 04. The system, as one connected chain ------------------------------ */

/*
 * Rendered as one connected system rather than a grid of separate cards, as
 * the client's note asks. See .ed-system further down for the rail itself.
 */
/* ---- 02. Proof ----------------------------------------------------------- */

.ed-proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

.ed-proof {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding-top: 1.1rem;
  border-top: 2px solid var(--ed-ink);
  text-decoration: none;
}

.ed-proof__value {
  font-family: var(--ed-font-body);
  font-size: clamp(2.2rem, 5vw, 3.4rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ed-ink);
  font-variant-numeric: tabular-nums;
}

.ed-proof__label {
  font-family: var(--ed-font-mono);
  font-size: .78rem;
  letter-spacing: .08em;
  color: var(--ed-muted);
}

/* ---- 06. What we manage -------------------------------------------------- */

.ed-capability-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 0 clamp(1.25rem, 3vw, 2.5rem);
}

.ed-capability-list li {
  padding: .9rem 0;
  border-bottom: 1px solid var(--ed-hairline);
  font-family: var(--ed-font-body);
  font-size: 1.02rem;
  color: var(--ed-ink);
}

/* ---- 10. Plans ----------------------------------------------------------- */

.ed-plan__from {
  margin: .35rem 0 0;
  font-family: var(--ed-font-mono);
  font-size: .9rem;
  color: var(--ed-accent-deep);
}

.ed-plans__note {
  margin-top: 1.5rem;
  color: var(--ed-muted);
}

/* ---- 11. Add-ons, deliberately subordinate ------------------------------- */

.ed-addons {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
}

.ed-addon {
  padding-top: .9rem;
  border-top: 1px solid var(--ed-hairline);
}

.ed-addon dt {
  font-family: var(--ed-font-body);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ed-ink);
}

.ed-addon dd {
  margin: .3rem 0 0;
  font-family: var(--ed-font-body);
  font-size: .93rem;
  line-height: 1.6;
  color: var(--ed-muted);
}

/* ---- 12. FAQ ------------------------------------------------------------- */

.ed-faq {
  display: flex;
  flex-direction: column;
}

.ed-faq__item {
  border-bottom: 1px solid var(--ed-hairline);
}

.ed-faq__q {
  list-style: none;
  cursor: pointer;
  padding: 1.25rem 2.5rem 1.25rem 0;
  position: relative;
  font-family: var(--ed-font-body);
  font-size: clamp(1.02rem, 1.6vw, 1.15rem);
  font-weight: 600;
  color: var(--ed-ink);
}

.ed-faq__q::-webkit-details-marker { display: none; }

/* A plus that becomes a minus, drawn rather than iconed so it inherits colour. */
.ed-faq__q::after,
.ed-faq__q::before {
  content: '';
  position: absolute;
  right: .5rem;
  top: 50%;
  background: var(--ed-ink);
  transition: transform .3s var(--ed-ease), opacity .3s var(--ed-ease);
}

.ed-faq__q::before { width: 14px; height: 2px; transform: translateY(-50%); }
.ed-faq__q::after  { width: 2px; height: 14px; right: 1.1rem; transform: translateY(-50%); }

.ed-faq__item[open] .ed-faq__q::after { opacity: 0; transform: translateY(-50%) rotate(90deg); }

.ed-faq__a {
  margin: 0;
  padding: 0 3rem 1.4rem 0;
  font-family: var(--ed-font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ed-muted);
  max-width: 62ch;
}

/* ---- The promise panel gains an aside on the About page ------------------ */

.ed-promise__phrase {
  margin: 0;
  font-family: var(--ed-font-mono);
  font-size: .95rem;
  line-height: 1.7;
  letter-spacing: .04em;
  color: var(--ed-accent-light);
}

@media (prefers-reduced-motion: reduce) {
  .ed-faq__q::after,
  .ed-faq__q::before { transition: none; }
}

/* ---- Contact form: consent ----------------------------------------------
   The consent row is deliberately quiet — it is a condition of sending, not a
   sales point — but it stays legible, and the link to the policy is a real
   link rather than plain text a reader has to go hunting for.
   ------------------------------------------------------------------------ */

.form-consent-wrap {
  margin-top: 1.25rem;
  max-width: 46ch;
}

.ed-consent {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  cursor: pointer;
}

.ed-consent__label {
  font-family: var(--ed-font-body);
  font-size: .9rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, .78);
}

.ed-consent__label a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ed-consent__label a:hover { color: var(--ed-accent-light); }

/* On the light contact page the same row sits on paper, not ink. */
.ed-contact-form .ed-consent__label,
.section:not(.ed-cta-band) .ed-contact-form .ed-consent__label { color: var(--ed-muted); }

/* ---- Hero trust line ------------------------------------------------------
   Two facts a qualified visitor checks in the first five seconds. Small, mono,
   and separated by a rule rather than a bullet so it reads as data.
   ------------------------------------------------------------------------ */

.ed-hero-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1.25rem;
  margin: clamp(1.5rem, 3vw, 2.5rem) 0 0;
  font-family: var(--ed-font-mono);
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ed-muted);
}

.ed-hero-trust span + span {
  padding-left: 1.25rem;
  border-left: 1px solid var(--ed-hairline);
}

@media screen and (max-width: 559px) {
  .ed-hero-trust span + span { padding-left: 0; border-left: 0; }
}

/* ==========================================================================
   Brand sections — typography on the theme's own ladder

   These sections were built with fixed rem sizes and 1.55–1.65 leading. The
   theme is a viewport-scaled design: .heading-h3 is 3vw, .paragraph is 1.5vw
   at line-height 2, and everything steps down at 991 / 767 / 479. Next to that,
   fixed 16px type with tight leading reads as a different, smaller site.

   So nothing here sets a fixed size. Every value is vw with the theme's own
   breakpoint steps underneath, and the leading matches .paragraph's.

   Where a section already uses a theme class (.heading-h3, .paragraph.s-small)
   the class is left to do its job — the overrides that were flattening those
   to 28px and 16px are gone.
   ========================================================================== */

/* ---- Cards ---------------------------------------------------------------
   .heading-h3 is 3vw, sized for the full-width lifecycle track. In a
   three-column grid that overflows, so the card title steps down a notch while
   staying on the same vw system rather than dropping to a fixed rem.
   ------------------------------------------------------------------------ */

.ed-card-grid .heading-h3 {
  font-size: 2.6vw;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.ed-card-grid--2 .heading-h3 { font-size: 2.9vw; }

/* Body copy inside a card keeps .paragraph.s-small's own 1.25vw. Only the
   colour and leading are set here. */
.ed-card-grid .paragraph.s-small {
  font-size: 1.35vw;
  line-height: 1.6;
  color: var(--ed-muted);
}

.ed-card__num {
  font-family: var(--ed-font-mono);
  font-size: 1.1vw;
  font-weight: 500;
  letter-spacing: .12em;
  color: var(--ed-ink);
  opacity: .5;
}

.ed-card--quote .heading-h3 { font-size: 2vw; line-height: 1.35; }

.ed-card-grid .ed-card__statement {
  margin: 0;
  font-size: 2.9vw;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ed-ink);
  text-wrap: balance;
}

/* ---- Section intros ----------------------------------------------------- */

.ed-section__lede {
  margin-top: 1.5vw;
  max-width: 46ch;
}

.ed-problem__kicker {
  margin-top: 1.25vw;
  max-width: 42ch;
  font-weight: 500;
  color: var(--ed-ink);
}


/* ---- Proof -------------------------------------------------------------- */

.ed-proof__value { font-size: 4vw; line-height: 1; letter-spacing: -0.03em; }
.ed-proof__label { font-family: var(--ed-font-mono); font-size: .95vw; letter-spacing: .08em; }

/* ---- What we manage ----------------------------------------------------- */

.ed-capability-list li {
  padding: 1.1vw 0;
  font-family: var(--ed-font-body);
  font-size: 1.6vw;
  line-height: 1.6;
  color: var(--ed-ink);
}

/* ---- Plans -------------------------------------------------------------- */

.ed-plan__from { font-family: var(--ed-font-mono); font-size: 1.1vw; color: var(--ed-accent-deep); }
.ed-plans__note { margin-top: 2vw; }

/* ---- Add-ons ------------------------------------------------------------ */

.ed-addon dt { font-family: var(--ed-font-body); font-size: 1.8vw; font-weight: 600; line-height: 1.3; color: var(--ed-ink); }
.ed-addon dd { margin: .5vw 0 0; font-family: var(--ed-font-body); font-size: 1.35vw; line-height: 1.75; color: var(--ed-muted); }

/* ---- FAQ ---------------------------------------------------------------- */

.ed-faq__q {
  padding: 1.6vw 3.5vw 1.6vw 0;
  font-family: var(--ed-font-body);
  font-size: 2vw;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ed-ink);
}

.ed-faq__q::before { width: 18px; height: 2px; }
.ed-faq__q::after  { width: 2px; height: 18px; right: 1.5vw; }
.ed-faq__q::after, .ed-faq__q::before { right: .8vw; }
.ed-faq__q::after  { right: 1.5vw; }

.ed-faq__a {
  padding: 0 4vw 1.8vw 0;
  font-family: var(--ed-font-body);
  font-size: 1.35vw;
  line-height: 1.9;
  color: var(--ed-muted);
  max-width: 58ch;
}

/* ---- The promise panel -------------------------------------------------- */

.ed-promise__title { margin: .6vw 0 0; font-size: 2.5vw; line-height: 1.3; color: #fff; text-wrap: balance; }
.ed-promise__list { gap: 1.2vw; }
.ed-promise__list li { padding-left: 2vw; font-family: var(--ed-font-body); font-size: 1.35vw; line-height: 1.75; color: rgba(255,255,255,.9); }
.ed-promise__list li::before { width: 10px; height: 10px; top: .7em; }
.ed-promise__phrase { font-family: var(--ed-font-mono); font-size: 1.1vw; line-height: 1.9; letter-spacing: .04em; color: var(--ed-accent-light); }


/* ---- Hero trust line ---------------------------------------------------- */

.ed-hero-trust { margin-top: 2.5vw; font-size: 1.05vw; line-height: 1.6; letter-spacing: .12em; }

/* ---- Consent row -------------------------------------------------------- */

.ed-consent__label { font-size: 1.3vw; line-height: 1.7; }

/* ==========================================================================
   The theme's own breakpoints. Below 992 it stops scaling by viewport and
   uses fixed sizes, exactly as .heading-h2 and .heading-h3 do, so the type
   does not collapse on a phone.
   ========================================================================== */

@media screen and (max-width: 991px) {
  .ed-card-grid .heading-h3,
  .ed-card-grid--2 .heading-h3 { font-size: 24px; }
  .ed-card-grid .ed-card__statement { font-size: 26px; }
  .ed-card--quote .heading-h3 { font-size: 20px; }
  .ed-card__num { font-size: 13px; }


  .ed-proof__value { font-size: 44px; }
  .ed-proof__label { font-size: 12px; }

  .ed-capability-list li { font-size: 17px; padding: 14px 0; }

  .ed-addon dt { font-size: 18px; }
  .ed-addon dd { font-size: 16px; margin-top: 6px; }

  .ed-faq__q { font-size: 20px; padding: 20px 44px 20px 0; }
  .ed-faq__q::after { right: 18px; }
  .ed-faq__q::before { right: 10px; }
  .ed-faq__a { font-size: 16px; padding: 0 44px 22px 0; }

  .ed-promise__title { font-size: 24px; margin-top: 8px; }
  .ed-promise__list { gap: 14px; }
  .ed-promise__list li { font-size: 16px; padding-left: 24px; }
  .ed-promise__phrase { font-size: 14px; }


  .ed-plan__from { font-size: 15px; }
  .ed-plans__note { margin-top: 24px; }

  .ed-hero-trust { font-size: 12px; margin-top: 28px; }
  .ed-section__lede { margin-top: 20px; }
  .ed-problem__kicker { margin-top: 16px; }
  .ed-consent__label { font-size: 15px; }
}

@media screen and (max-width: 767px) {
  .ed-card-grid .heading-h3,
  .ed-card-grid--2 .heading-h3 { font-size: 22px; }
  .ed-card-grid .ed-card__statement { font-size: 23px; }
  .ed-card--quote .heading-h3 { font-size: 19px; }


  .ed-proof__value { font-size: 38px; }
  .ed-faq__q { font-size: 18px; }
  .ed-promise__title { font-size: 21px; }

}

@media screen and (max-width: 479px) {
  .ed-card-grid .heading-h3,
  .ed-card-grid--2 .heading-h3 { font-size: 20px; }
  .ed-card-grid .ed-card__statement { font-size: 21px; }
  .ed-proof__value { font-size: 34px; }
  .ed-capability-list li { font-size: 16px; }
}

/* ---- Hero clipping --------------------------------------------------------
   The entrance interaction scales .leading to 2x before settling. With the old
   one-word headline that stayed inside the viewport; "We turn your" at 168px
   does not, and it put a real 141px horizontal scroll on the homepage.

   overflow-x: clip rather than hidden, deliberately: hidden would make this a
   scroll container and break the position: sticky the hero track relies on when
   a showreel is set. clip does the same visual job without that side effect —
   it is what the theme already does on .sticky-section.
   ------------------------------------------------------------------------ */

.ed-hero-section { overflow-x: clip; }

/* Long headlines break rather than run off the edge, at any viewport. */
.heading-h1.home { overflow-wrap: break-word; }

/* ---- Card and list reveal -------------------------------------------------
   The start state for initCardReveal(). The class is added by JS only after
   GSAP is confirmed present, so nothing here can hide content on a page where
   the script failed to load.
   ------------------------------------------------------------------------ */

/* Grids and lists: children arrive in order, indexed by JS. */
.ed-card-grid.is-revealing > *,
.ed-capability-list.is-revealing > *,
.ed-addons.is-revealing > *,
.ed-faq.is-revealing > *,
.ed-proof-grid.is-revealing > * {
  opacity: 0;
  transform: translateY(34px);
}

.ed-card-grid.is-revealed > *,
.ed-capability-list.is-revealed > *,
.ed-addons.is-revealed > *,
.ed-faq.is-revealed > *,
.ed-proof-grid.is-revealed > * {
  opacity: 1;
  transform: none;
  transition: opacity .6s ease calc(var(--ed-reveal-i, 0) * .07s),
              transform .75s cubic-bezier(.16, .84, .28, 1) calc(var(--ed-reveal-i, 0) * .07s);
}

/* Single blocks: one quiet lift, no stagger. */
.ed-empty.is-revealing,
.ed-promise.is-revealing {
  opacity: 0;
  transform: translateY(22px);
}

.ed-empty.is-revealed,
.ed-promise.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity .6s ease, transform .75s cubic-bezier(.16, .84, .28, 1);
}

@media (prefers-reduced-motion: reduce) {
  .ed-card-grid.is-revealing > *,
  .ed-capability-list.is-revealing > *,
  .ed-addons.is-revealing > *,
  .ed-faq.is-revealing > *,
  .ed-proof-grid.is-revealing > *,
  .ed-empty.is-revealing,
  .ed-promise.is-revealing { opacity: 1; transform: none; }
}

/* ==========================================================================
   Empty archives

   Sized off the same vw ladder as every other new section, so an archive that
   is waiting for content still reads as part of the design rather than as a
   page that failed to load.
   ========================================================================== */

.ed-empty {
  margin-top: clamp(1.25rem, 2.5vw, 2.25rem);
  padding: clamp(2rem, 4vw, 3.25rem);
  border: 1px solid var(--ed-hairline);
  border-radius: clamp(28px, 3.5vw, 44px);
  background-color: var(--ed-paper-soft);
  /*
   * The panel spans the row. It used to be capped at 46rem so the paragraph
   * kept a readable measure, but that put the cap on the wrong element: on a
   * wide screen it left a 736px card against the left edge of a 1905px
   * container, under a full-width heading, with a bare 1100px beside it. The
   * section read as one that had failed to load rather than one deliberately
   * saying it has nothing yet. The measure is kept on the text below instead.
   */
}

.ed-empty__kicker { margin: 0; }

.ed-empty__title {
  margin: .6vw 0 0;
  max-width: 22ch;
  font-size: 2.1vw;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ed-ink);
  text-wrap: balance;
}

.ed-empty__body {
  margin: 1vw 0 0;
  font-family: var(--ed-font-body);
  font-size: 1.25vw;
  line-height: 1.8;
  color: var(--ed-muted);
  max-width: 46ch;
}

.ed-empty__cta {
  display: inline-block;
  margin-top: 1.6vw;
  padding-bottom: .25em;
  font-family: var(--ed-font-body);
  font-size: 1.15vw;
  font-weight: 600;
  color: var(--ed-accent-deep);
  border-bottom: 2px solid currentColor;
  text-decoration: none;
  transition: color .25s ease, border-color .25s ease;
}

.ed-empty__cta:hover { color: var(--ed-ink); }

@media screen and (max-width: 991px) {
  .ed-empty__title { font-size: 24px; margin-top: 8px; }
  .ed-empty__body { font-size: 16px; margin-top: 12px; }
  .ed-empty__cta { font-size: 15px; margin-top: 20px; }
}

@media screen and (max-width: 767px) {
  .ed-empty__title { font-size: 21px; }
}

/* --------------------------------------------------------------------------
   Card body copy below 992

   .ed-card-grid .paragraph.s-small is more specific than the theme's own
   breakpoint rule, so it kept its viewport size all the way down and measured
   5px on a 375 phone. These restore the step-down the theme intends.
   -------------------------------------------------------------------------- */

@media screen and (max-width: 991px) {
  .ed-card-grid .paragraph.s-small { font-size: 16px; line-height: 1.7; }
}

@media screen and (max-width: 479px) {
  .ed-card-grid .paragraph.s-small { font-size: 15px; }
}

/* --------------------------------------------------------------------------
   Card grids: cap the column count

   auto-fit with a 19rem minimum gives five columns on a 1920 screen, so a
   six-card section lands as a row of five and one orphan with four columns of
   empty space beside it. Capping the track count keeps the same responsive
   behaviour on narrow screens and gives 3 x 2 on a wide one.
   -------------------------------------------------------------------------- */

@media screen and (min-width: 1200px) {
  .ed-card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ed-card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media screen and (min-width: 768px) and (max-width: 1199px) {
  .ed-card-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   04 — The system

   Seven steps on one rail. The rail is a scaled pseudo-element so it can be
   drawn from the left, and each node carries its index as a custom property so
   the stagger is CSS rather than seven separate rules.
   ========================================================================== */

.ed-system {
  list-style: none;
  margin: 0;
  padding: 3.2vw 0 0;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--ed-system-count, 7), minmax(0, 1fr));
  gap: 0;
}

/* The rail, sitting on the node centres. */
/*
 * The rail runs between the first and last node, not the full width. Each
 * dot sits at the left edge of its column, so the last one is exactly one
 * column short of the right edge; the 7px is the dot's own radius.
 */
.ed-system__rail {
  position: absolute;
  left: 7px;
  right: calc(100% / var(--ed-system-count, 7) - 7px);
  top: calc(3.2vw + 1.62rem);
  height: 3px;
  background-image: var(--ed-gradient);
  border-radius: 3px;
  transform-origin: left center;
  opacity: .8;
}

.ed-system__step {
  display: grid;
  grid-template-rows: auto auto auto;
  justify-items: start;
  gap: .45rem;
  padding-right: 1rem;
  position: relative;
}

.ed-system__num {
  font-family: var(--ed-font-mono);
  font-size: .8rem;
  font-weight: 500;
  letter-spacing: .12em;
  color: var(--ed-muted);
}

.ed-system__dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-image: var(--ed-gradient);
  box-shadow: 0 0 0 5px var(--ed-paper);
  position: relative;
  z-index: 1;
}

/*
 * The first and last carry the accent, so the loop reads as a loop.
 *
 * :first-of-type rather than :first-child — the rail is the list's first child,
 * so :first-child never matched a step and only the last dot was styled.
 */
.ed-system__step:first-of-type .ed-system__dot,
.ed-system__step:last-of-type .ed-system__dot {
  width: 18px;
  height: 18px;
  background-image: none;
  background-color: var(--ed-accent);
  box-shadow: 0 0 0 4px var(--ed-paper), 0 0 0 6px rgba(var(--ed-accent-rgb), .3);
}

.ed-system__name {
  font-family: var(--ed-font-body);
  font-size: 1.5vw;
  font-weight: 500;
  line-height: 1.25;
  color: var(--ed-ink);
  letter-spacing: -0.01em;
}

.ed-system__loop {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: 2.6vw 0 0;
  font-family: var(--ed-font-body);
  font-size: 1.15vw;
  line-height: 1.6;
  color: var(--ed-muted);
}

.ed-system__loop-arrow {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--ed-accent);
  border-right-color: transparent;
  border-radius: 50%;
  transform: rotate(-35deg);
}

/* ---- The reveal ----------------------------------------------------------
   Applied by JS once it has confirmed it can animate, so a script that fails
   to load leaves the section visible rather than blank.
   ------------------------------------------------------------------------ */

.ed-system.is-drawing .ed-system__rail { transform: scaleX(0); }

.ed-system.is-drawing .ed-system__step {
  opacity: 0;
  transform: translateY(14px);
}

.ed-system.is-drawn .ed-system__rail {
  transform: scaleX(1);
  transition: transform 1.1s cubic-bezier(.65, .05, .25, 1);
}

.ed-system.is-drawn .ed-system__step {
  opacity: 1;
  transform: none;
  transition: opacity .55s ease calc(.28s + var(--ed-system-i) * .11s),
              transform .55s cubic-bezier(.2, .8, .3, 1) calc(.28s + var(--ed-system-i) * .11s);
}

@media (prefers-reduced-motion: reduce) {
  .ed-system.is-drawing .ed-system__rail,
  .ed-system.is-drawing .ed-system__step { opacity: 1; transform: none; }
}

/* ---- Narrower --------------------------------------------------------- */

@media screen and (max-width: 1199px) {
  /* Seven columns stops fitting; two rows of the same rail treatment instead. */
  .ed-system { grid-template-columns: repeat(4, minmax(0, 1fr)); row-gap: 2.5rem; }
  .ed-system__rail { display: none; }
  .ed-system__name { font-size: 17px; }
  .ed-system__num { font-size: 12px; }

  .ed-system__step::before {
    content: '';
    position: absolute;
    left: 7px;
    right: -1rem;
    top: 1.55rem;
    height: 2px;
    background-image: var(--ed-gradient);
    opacity: .3;
  }

  .ed-system__step:nth-of-type(4n)::before,
  .ed-system__step:last-of-type::before { display: none; }

  .ed-system__loop { font-size: 15px; margin-top: 28px; }
}

@media screen and (max-width: 767px) {
  .ed-system { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2rem; }
  .ed-system__step:nth-of-type(4n)::before { display: block; }
  .ed-system__step:nth-of-type(2n)::before,
  .ed-system__step:last-of-type::before { display: none; }
  .ed-system__name { font-size: 16px; }
}

@media screen and (max-width: 479px) {
  .ed-system { grid-template-columns: 1fr; row-gap: 0; padding-top: 1.5rem; }
  .ed-system__step {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    gap: .2rem .9rem;
    padding: .9rem 0;
    border-bottom: 1px solid var(--ed-hairline);
  }
  .ed-system__step::before { display: none !important; }
  .ed-system__num { grid-column: 2; }
  .ed-system__dot { grid-row: 1 / span 2; grid-column: 1; box-shadow: none; }
  .ed-system__name { grid-column: 2; }
}

/* ==========================================================================
   Interaction states for the new sections

   The reference build responds to the pointer nearly everywhere — cards lift,
   tags fill, links slide. The sections added for the repositioning were inert,
   which is a quiet part of why they read as belonging to a different site.

   Everything here is a transform or a colour, so nothing reflows on hover, and
   every rule is paired with :focus-visible so the keyboard gets the same
   feedback as the mouse.
   ========================================================================== */

.ed-card-grid .lc-card {
  transition: transform .45s cubic-bezier(.16, .84, .28, 1),
              box-shadow .45s ease;
}

.ed-card-grid .lc-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 18px 40px -24px rgba(10, 14, 20, .35);
}

/* Whole-card links get the same treatment from the keyboard. */
.ed-card-grid a.lc-card:focus-visible {
  transform: translateY(-5px);
  outline: 2px solid var(--ed-accent);
  outline-offset: 4px;
}

/* ---- The FAQ ------------------------------------------------------------- */

.ed-faq__q {
  transition: color .25s ease;
}

.ed-faq__q:hover,
.ed-faq__item[open] .ed-faq__q {
  color: var(--ed-accent-deep);
}

.ed-faq__q:hover::after,
.ed-faq__q:hover::before {
  background-color: var(--ed-accent);
}

.ed-faq__q:focus-visible {
  outline: 2px solid var(--ed-accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---- What we manage ------------------------------------------------------ */

.ed-capability-list li {
  position: relative;
  padding-left: 0;
  transition: padding-left .35s cubic-bezier(.16, .84, .28, 1), color .25s ease;
}

/* A rule that grows out of the left edge, rather than a bullet that appears. */
.ed-capability-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 0;
  height: 2px;
  background-color: var(--ed-accent);
  transform: translateY(-50%);
  transition: width .35s cubic-bezier(.16, .84, .28, 1);
}

.ed-capability-list li:hover {
  padding-left: 1.6rem;
  color: var(--ed-accent-deep);
}

.ed-capability-list li:hover::before { width: 1.1rem; }

/* ---- Add-ons ------------------------------------------------------------- */

.ed-addon { transition: color .25s ease; }
.ed-addon:hover dt { color: var(--ed-accent-deep); }

/* ---- The system rail ----------------------------------------------------- */

.ed-system__step { transition: color .25s ease; }

.ed-system__dot {
  transition: transform .35s cubic-bezier(.16, .84, .28, 1),
              box-shadow .35s ease;
}

.ed-system__name { transition: color .25s ease; }

.ed-system__step:hover .ed-system__dot {
  transform: scale(1.45);
  box-shadow: 0 0 0 5px var(--ed-paper), 0 0 0 8px rgba(var(--ed-accent-rgb), .22);
}

.ed-system__step:hover .ed-system__name { color: var(--ed-accent-deep); }

@media (prefers-reduced-motion: reduce) {
  .ed-card-grid .lc-card,
  .ed-capability-list li,
  .ed-capability-list li::before,
  .ed-system__dot,
  .ed-system__name,
  .ed-faq__q { transition: none; }

  .ed-card-grid .lc-card:hover { transform: none; }
  .ed-capability-list li:hover { padding-left: 0; }
  .ed-system__step:hover .ed-system__dot { transform: none; }
}
