/* ---------------------------------------------------------------------------
   Article

   The layout, top to bottom:

     dark band     breadcrumb, category, centred title, lead, date
     lead image    wide, straddling the edge between the band and the page
     two columns   a rail carrying the contents and the share row, then prose

   The rail is the part that earns its place. These pieces run to six or seven
   sections, and a reader who arrives from search wants to know what is in one
   before committing to it. It also gives the prose a left edge to sit against,
   which is what stops a single centred column reading as a bare document.

   Everything uses the site's own tokens, so an article inherits the same type
   scale, colours and spacing as every other page rather than becoming a second
   design.

   Loaded on every page since 2.3.1: five kilobytes is not worth a conditional
   that can fail, and this class of fault has already cost several rounds.
   --------------------------------------------------------------------------- */

:root {
  /* The article section's own padding, and how far the lead image lifts up
     into the dark band above it. Both are needed in two places -- the band has
     to reserve room for the lift, and the image has to cancel the padding
     before applying it -- so they are declared once, here. */
  --article-pad:  clamp(2.5rem, 6vw, 4.5rem);
  --article-pull: clamp(2.5rem, 5vw, 4.5rem);
}

/* ---------------------------------------------------------------- header -- */

/* Centred, unlike every other page head on the site. A marketing page is
   scanned, so its heading sits left where the eye starts; an article is read
   from the top, and centring the title is the convention that signals which of
   the two this is before a word has been read. */
.page-head--article {
  text-align: center;
}

.page-head--article .breadcrumb {
  justify-content: center;
}

.page-head--article .article__kicker {
  margin: 0 0 var(--sp-4, 1rem);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--violet-bright);
}

/* The page-head display size is set for two or three words. An article title
   is a sentence, so it steps down a little and is allowed more of them. */
.page-head--article .article__title {
  font-size: clamp(2.1rem, 1.25rem + 3.2vw, 3.5rem);
  max-width: 20ch;
  margin-inline: auto;
  margin-bottom: var(--sp-5);
  text-wrap: balance;
}

.page-head--article .article__lead {
  max-width: 56ch;
  margin-inline: auto;
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin: var(--sp-6, 1.5rem) 0 0;
  font-size: var(--fs-sm);
  color: var(--t-on-dark-muted);
}

.article__meta-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
}

/* Room for the lead image to lift into. Only applied when there is one, so a
   post with no image does not open with a band of empty violet. */
.page-head--overlap {
  padding-bottom: calc(clamp(3rem, 2rem + 4vw, 5rem) + var(--article-pull));
}

/* ---------------------------------------------------------------- shell -- */

.article {
  padding-block: var(--article-pad);
}

/* Narrower than a marketing section. With the rail taking the left, a full
   1280 leaves the prose sitting in the middle of a lot of nothing. */
.article > .container {
  max-width: 1160px;
}

/* Lifts up over the dark band, so the image bridges the two halves of the page
   rather than sitting below a hard edge.

   position/z-index are load-bearing, not decoration: .page-head::after is an
   absolutely positioned gradient overlay, and a positioned element paints above
   an unpositioned one regardless of document order. Without this the overlay
   would tint the top of the image. */
.article__hero {
  position: relative;
  z-index: 1;
  margin: calc(-1 * (var(--article-pad) + var(--article-pull))) 0 clamp(2.25rem, 4vw, 3.25rem);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--paper-2);
  box-shadow: 0 24px 60px -28px rgba(17, 17, 28, 0.55);
}

.article__hero img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* --------------------------------------------------------------- layout -- */

.article__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 2.75rem);
}

@media (min-width: 64rem) {
  .article__layout {
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: clamp(2rem, 3.5vw, 3.5rem);
    align-items: start;
  }

  /* Follows the reader down the page. 96px clears the sticky site header,
     which is 74px, and matches .aside-sticky elsewhere on the site. */
  .article__rail {
    position: sticky;
    top: 96px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* Below the breakpoint the rail sits above the prose as a card, so it still
   reads as a thing you can use rather than a stray list of links. */
@media (max-width: 63.99rem) {
  .article__rail {
    padding: 1.25rem 1.35rem 1.4rem;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    background: #fff;
  }
}

.rail__label {
  margin: 0 0 0.85rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--t-muted);
}

/* ------------------------------------------------------------ contents -- */

.toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 2px solid var(--line);
}

.toc__list a {
  display: block;
  padding: 0.45rem 0 0.45rem 0.9rem;
  margin-left: -2px;
  border-left: 2px solid transparent;
  font-size: 0.9375rem;
  line-height: 1.35;
  color: var(--t-muted);
  text-decoration: none;
  transition: color var(--d-fast, 0.15s) var(--e-both, ease),
              border-color var(--d-fast, 0.15s) var(--e-both, ease);
}

.toc__list a:hover {
  color: var(--ink);
}

/* Set by the rail script as the reader moves. Also the plain :target state, so
   the marker is correct after a jump even if the script never ran. */
.toc__list a[aria-current='true'] {
  color: var(--violet);
  border-left-color: var(--violet);
  font-weight: 600;
}

.toc + .share {
  margin-top: 1.75rem;
}

/* --------------------------------------------------------------- share -- */

.share__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.share__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.375rem;
  height: 2.375rem;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--t-muted);
  cursor: pointer;
  transition: color var(--d-fast, 0.15s) var(--e-both, ease),
              border-color var(--d-fast, 0.15s) var(--e-both, ease),
              background var(--d-fast, 0.15s) var(--e-both, ease);
}

.share__btn svg {
  width: 17px;
  height: 17px;
}

.share__btn:hover {
  color: #fff;
  background: var(--violet);
  border-color: var(--violet);
}

.share__said {
  margin: 0.7rem 0 0;
  font-size: var(--fs-xs);
  color: var(--violet);
}

/* ---------------------------------------------------------------- prose -- */

/* One column with a measure, not a breakout grid.

   The earlier version outdented headings into the left margin. That works on a
   centred column with nothing beside it; with a rail there, the outdent runs
   into it. The rail is the better use of the space -- it is navigation rather
   than rhythm -- so the prose keeps a single, consistent left edge and the
   width variation comes from images and prompts running wider instead. */
.article__body {
  font-size: var(--fs-lg);
  line-height: var(--lh-body);
  color: var(--ink);
}

/* 19px is set for a desktop reading column. On a phone the column is about
   350px wide, and at 19px that is roughly 37 characters a line -- short enough
   that the eye returns to the left edge more often than it reads. A step down
   buys back several characters without the text becoming small. */
@media (max-width: 30rem) {
  .article__body {
    font-size: 1.0625rem;
  }
}

/* The reset and the rhythm are set on the same selector on purpose.
 *
 * The previous version reset spacing with `.article__body p { margin: 0 }` and
 * set it with `.article__body > * + * { margin-top: 1.15em }`. A class plus a
 * type selector out-specifies a class plus two universals, so the reset won and
 * every paragraph in every article sat flush against the one above it. It is
 * visible in any screenshot of the page and easy to read past, because the text
 * is not broken, only unbroken.
 *
 * Both rules are `.article__body > *` now, so the later one wins by order. */
.article__body > * {
  min-width: 0;
  margin-block: 0;
}

/* The measure. Everything that is read line by line is capped; everything that
   is looked at rather than read is not. */
.article__body > p,
.article__body > ul,
.article__body > ol,
.article__body > dl,
.article__body > h2,
.article__body > h3,
.article__body > h4,
.article__body > hr {
  max-width: 46rem;
}

.article__body > * + * {
  margin-top: 1.15em;
}

.article__body h2 {
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
  margin-top: 2.4em;
  margin-bottom: 0.55em;
  text-wrap: balance;

  /* The contents links jump to these. Without this the target lands under the
     sticky header. */
  scroll-margin-top: 96px;
}

.article__body h3 {
  font-size: var(--fs-h4);
  line-height: var(--lh-snug);
  margin-top: 1.9em;
  margin-bottom: 0.45em;
  scroll-margin-top: 96px;
}

.article__body h2:first-child,
.article__body h3:first-child {
  margin-top: 0;
}

.article__body strong { font-weight: 650; }

.article__body a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.article__body ul,
.article__body ol {
  padding-left: 1.35rem;
}

.article__body li + li {
  margin-top: 0.4em;
}

.article__body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--r-card);
}

.article__body figure {
  margin: 2.25em 0;
}

.article__body figcaption {
  margin-top: 0.7rem;
  font-size: var(--fs-sm);
  color: var(--t-muted);
}

/* A pull quote should read as someone speaking, not as a styled paragraph.
   Set the way the rest of the site sets a quote: curly marks and a size step,
   no rule down the side. The testimonial cards already establish that
   convention, and a bordered variant here would be a second one. */
.article__body blockquote {
  max-width: 48rem;
  margin: 2em 0;
  padding: 0;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  text-wrap: pretty;
}

.article__body blockquote p { margin: 0; }

/* Literal curly quotes rather than C escapes, matching sections.css: the
   escape has to be terminated, and the terminator is invisible in a
   stylesheet. */
.article__body blockquote p:first-child::before { content: '“'; }
.article__body blockquote p:last-child::after   { content: '”'; }

.article__body blockquote cite {
  display: block;
  margin-top: 0.7em;
  font-size: var(--fs-sm);
  font-style: normal;
  color: var(--t-muted, inherit);
}

.article__body hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 2.6em 0;
}

.article__body code {
  font-size: 0.9em;
  background: var(--paper-2);
  padding: 0.12em 0.35em;
  border-radius: var(--r-ctl);
}

.article__body table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-base);
}

.article__body th,
.article__body td {
  text-align: left;
  padding: 0.6rem 0.9rem 0.6rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

/* Wide content must scroll inside itself rather than widening the page. */
.article__body .scroll,
.article__body pre {
  overflow-x: auto;
}

/* ------------------------------------------------------- inline prompts -- */

/* A quote prompt at a section break. Runs the full width of the prose column,
   wider than the text itself, so it reads as a pause in the article rather
   than a paragraph, and sits on the brand violet so it is unmistakably an
   offer and not part of the argument. Kept to one line and one button:
   anything more competes with the piece it interrupts. */
.article__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  margin-block: clamp(2.5rem, 5vw, 3.5rem);
  padding: clamp(1.5rem, 3vw, 2rem) clamp(1.5rem, 3vw, 2.25rem);
  border-radius: var(--r-card);
  background: var(--grad-violet, var(--violet-bright));
  color: #fff;
}

.article__cta-text {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  font-weight: 500;
  max-width: 34ch;
  text-wrap: balance;
}

/* ------------------------------------------------------------ end matter -- */

.article__back {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: clamp(1.75rem, 4vw, 2.5rem);
  border-top: 1px solid var(--line);
}

/* ----------------------------------------------------------- pagination -- */

.pagination {
  margin-top: clamp(2rem, 5vw, 3.25rem);
}

.pagination__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pagination__list a,
.pagination__list span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0 0.85rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-ctl);
  font-size: var(--fs-sm);
  text-decoration: none;
  color: inherit;
}

.pagination__list .current {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.pagination__list a:hover {
  border-color: var(--ink);
}

/* @astra-undo -- build/preview-article.mjs splits the file here to render a
   control page without this block. Do not remove or reword this marker. */

/* ---------------------------------------------------------------------------
   Undo the parent theme's post layout.

   Astra lays its content area out with flexbox, so that #primary and #secondary
   can sit side by side. A template that puts several sections straight into
   that wrapper gets them laid out as columns rather than stacked: the page
   head, the article and the closing band standing beside each other, each
   squeezed to whatever width was left.

   display:block is therefore the single most important declaration in this
   file. Everything else here is width and padding, which only matters once the
   sections are stacked in the first place.

   It is !important, which is worth justifying. Astra's own rule is a plain
   pair of classes, which this would out-specify -- but Astra Pro and the
   customiser both emit generated CSS with an #id in the selector, and a site
   that gains one later would silently go back to three columns. The failure
   mode is a page that reads as destroyed, on the one template nobody looks at
   after a plugin update. Losing the specificity argument is not worth the
   tidiness.

   Scoped to .single-post, and to the content area rather than .ast-container
   generally, so the header and footer containers are untouched.
   --------------------------------------------------------------------------- */

.single-post .site-content > .ast-container,
.single-post #content.site-content > .ast-container {
  display: block !important;
}

.single-post .site-content > .ast-container,
.single-post #primary,
.single-post .site-main,
.single-post .ast-article-single {
  display: block;
  max-width: none;
  width: 100%;
  margin-inline: 0;
  padding-inline: 0;
  float: none;
}

.single-post #secondary,
.single-post .widget-area {
  display: none;
}

/* Astra adds its own article padding and entry header; the design supplies
   both, and doubling them leaves an odd gap above the title. */
.single-post .ast-article-single {
  padding: 0;
  border: 0;
  background: none;
}

.single-post .site-content {
  padding: 0;
}

/* --------------------------------------------------------------- motion -- */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}
