/**
 * Simple Section Component
 *
 * Styles for overline, lists, dividers, and responsive grids.
 */

/* Overline/eyebrow text
 *
 * FULL STRENGTH, DELIBERATELY. This carried
 * `color-mix(in oklch, var(--color-base-content) 60%, transparent)` until
 * 2026-09-18 — the same colour as the heading beside it, at 60% alpha and a third
 * of the size. Alpha is the wrong lever for de-emphasis on 12px text: WCAG holds
 * small text to 4.5:1, and throwing away 40% of the contrast before the ground is
 * even considered made the overline the worst element in the theme. Measured over
 * 3532 samples in four families: 10.2% cleared their threshold at 60% alpha and
 * 50.7% at full, with no plateau in between, so there is no intermediate value
 * worth keeping.
 *
 * The de-emphasis survives without it. Uppercase, 0.75rem, and 0.1em of tracking
 * already read as an eyebrow; they are typographic signals rather than contrast
 * ones, and they cost the reader nothing.
 *
 * Half of what remains is the ground, not this rule — 1729 of the samples still
 * fail at full opacity because the ground carries no ink at that size. That is
 * step 17b.
 */
.overline {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-base-content);
  margin-bottom: 0.5rem;
  /* The compiled Tailwind in theme.css ships a `.overline` UTILITY
     (`text-decoration-line: overline`) with the same name as this component
     class, so every eyebrow drew a rule over its own letters — the "stray tick
     marks" above "THE PEST YEAR" in the forms visual review, 2026-09-26
     (tests/forms/review-log.md, form-footer mobile (d)). This file loads after
     theme.css at equal specificity, so saying it here wins. */
  text-decoration-line: none;
}

/* Every content item after the first needs air above it, in EITHER wrapper
   render_content_item() gets rendered into — Simple_Section_Component's own
   `.simple-section__content`, and Media_Text_Component's `.media-text__content`
   (Media_Text extends Simple_Section and inherits render_content_item()
   unchanged, but renders into its own, differently-named wrapper, so a
   selector scoped to only the first one never reached it). Preflight zeroes
   every margin and nothing put one back:
   - a heading's first line sat on its own descenders at the tight
     line-heights the large sizes carry (`title` 1.15, `display` 1.1) —
     form-in-page, form-basic, form-collect, form-fields in the forms visual
     review, 2026-09-26;
   - two consecutive `text` items read as one run-on paragraph, and inside
     Media_Text_Component nothing here applied at all, so a whole section's
     heading, paragraph, list and button sat flush against each other —
     offer-detail-image-right, explain-narrative-half, step 14 revision,
     2026-09-28.
   One token, every pair, so heading-to-text spacing is exactly what it has
   always been — only the missing pairs (paragraph-to-paragraph, and every
   pair inside Media_Text_Component) are new. */
.simple-section__content > * + *,
.media-text__content > * + * {
  margin-top: var(--space-3, 0.75rem);
}

/* List styles */
.simple-section__list {
  padding-left: 1.5rem;
}

.list-none {
  list-style: none;
  padding-left: 0;
}

.list-check {
  list-style: none;
  padding-left: 0;
}

.list-check li::before {
  content: "✓";
  margin-right: 0.5rem;
  color: var(--color-primary);
}

/* Divider variants */
.divider--dashed {
  border-style: dashed;
}

.divider--thick {
  border-width: 3px 0 0 0;
}

/* Browser review round 1, finding #6: a `divider` content item
   (Simple_Section_Component::render_divider()) emits `<hr class="divider
   [divider--<style>]">` — a real `<hr>`, styled through ITS OWN native
   border by the two rules just above (preflight already turns a bare `<hr>`
   into a plain `border-top`, which `--dashed`/`--thick` then customise).
   DaisyUI's `.divider` (node_modules/daisyui) is a SECOND, independent line:
   it is built for a `<div>` holding text between two lines, drawn by
   `::before`/`::after` in `--divider-color`, regardless of what element
   carries the class. An `<hr>` cannot hold that text at all — it is a void
   element — so applying `.divider` to one never draws the two-halves-either-
   side-of-a-label look it exists for; it only ever adds a second, uninvited
   line under the hr's own: a visible dark-line-then-grey-line double rule
   (the capture: contact-editorial-desktop, "Write to us." lede). Since the
   line this theme actually wants IS the hr's own border — that is what
   `--dashed`/`--thick` already customise — daisyUI's decoration is turned
   off here, not the hr's border. */
hr.divider::before,
hr.divider::after {
  content: none;
}

/* Stat styling */
.simple-section__stat {
  text-align: center;
}

.simple-section__stat-value {
  display: block;
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.2;
}

/* A stat item that names a `size`: the type alias sets the font size, so this
   rule sets everything else and never a size of its own. */
.simple-section__stat-figure {
  display: block;
  font-weight: 700;
  line-height: 1;
}

/* The overline's twin, seventy lines down: 14px text at the same 60% alpha, and
 * the same defect. It is NOT in the gallery sweep so there is no measurement of
 * it, but nothing about the reasoning depends on one — small text held to 4.5:1,
 * giving away 40% of its contrast before the ground is considered. Fixing the
 * overline and leaving this would be fixing the instance that happened to be
 * measured. */
.simple-section__stat-label {
  display: block;
  font-size: 0.875rem;
  color: var(--color-base-content);
}

/* Text item styling */
.simple-section__text-item {
  text-align: center;
}

.simple-section__text-item i {
  font-size: 2rem;
  color: var(--color-primary);
  margin-bottom: 1rem;
}

/* Responsive grid for texts/images - mobile first */
.simple-section__texts,
.simple-section__images {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

@media (min-width: 768px) {
  .simple-section__texts.grid-cols-2,
  .simple-section__images.grid-cols-2 {
    grid-template-columns: repeat(2, 1fr);
  }

  .simple-section__texts.grid-cols-3,
  .simple-section__images.grid-cols-3 {
    grid-template-columns: repeat(3, 1fr);
  }

  .simple-section__texts.grid-cols-4,
  .simple-section__images.grid-cols-4 {
    grid-template-columns: repeat(4, 1fr);
  }

  .simple-section__texts.grid-cols-5,
  .simple-section__images.grid-cols-5 {
    grid-template-columns: repeat(5, 1fr);
  }

  .simple-section__texts.grid-cols-6,
  .simple-section__images.grid-cols-6 {
    grid-template-columns: repeat(6, 1fr);
  }
}

/* ==========================================================================
   Steps_Component, vertical layout.

   Steps has no stylesheet of its own; its markup is daisyUI's `.steps`, and
   these rules sit here, in the one component stylesheet every page loads,
   rather than in a new file for three declarations.

   Two defects, found on form-in-page and form-widths in the forms visual review
   (2026-09-26, tests/forms/review-log.md):
   - daisyUI's `.steps .step { text-align: center }` applies to the VERTICAL
     layout too, so each description sat centred under its title and off-axis
     to the numbered rail on its left;
   - the title is an `<h4>`, and took the page's global h4 size (the type
     scale's, not the step's), so three step titles out-shouted the section's
     own h2 while their descriptions stayed at text-sm.
   Title at the h6 step of the type scale, description at body size, both
   left-aligned to the rail. Tokens only.
   ========================================================================== */
.steps-vertical .step {
  text-align: start;
}

.steps-vertical .step-content {
  padding-block: 0.3rem 0.75rem;
}

.steps-vertical .step-content h4 {
  display: block;
  font-size: var(--text-h6-size, 1.1rem);
  line-height: 1.3;
}

.steps-vertical .step-content p {
  font-size: var(--text-body-size, 1rem);
  margin-top: 0.25rem;
}

/* `style: outline` — the secondary action of a pair, inside the palette: no
   fill, drawn in the colour of the text around it, so it reads on a light
   ground, a dark one and over a photograph alike (the family's `secondary`
   role is a second hue, bright blue on emerald — Open section review,
   2026-09-28). */
.simple-section__btn-outline {
  --btn-bg: transparent;
  --btn-fg: currentColor;
  --btn-border: currentColor;
  --btn-shadow: none;
  background-color: transparent;
  background-image: none;
  color: inherit;
  border-color: currentColor;
  box-shadow: none;
}

.simple-section__btn-outline:hover {
  --btn-bg: color-mix(in oklab, currentColor 12%, transparent);
  background-color: color-mix(in oklab, currentColor 12%, transparent);
}

/* `phone_width: full` on a buttons row: on a phone each button takes the row. */
@media (max-width: 767px) {
  .simple-section__buttons--phone-full > .btn {
    flex: 1 1 100%;
  }
}

/* `panel: true` — the content box is a padded card. */
.simple-section__panel {
  padding: 1.5rem;
}

@media (min-width: 768px) {
  .simple-section__panel {
    padding: 2rem;
  }
}

/* A sized stat (the figure-led opener) sits on the edge of the text around it,
   not centred in its column. */
.simple-section__stat--figure {
  text-align: inherit;
}

/* ==========================================================================
   PROOF — the testimonial, the star rating, the figure band and the card row.
   The prove research (2026-09-28) §2 is the spec for every number below; its
   gap names (G1 quote, G2 rating, G4 figures, G5 card grid) are cited where
   each rule answers one. Tokens only: every colour is the primary role or the
   text colour around it, so the same markup reads on any ground and mode.
   ========================================================================== */

/* G1 — one testimonial: <figure><blockquote/><figcaption/></figure>. */
.simple-section__quote {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
}

.simple-section__quote-body {
  margin: 0;
}

/* The quote is the content and the attribution its caption: the size alias on
   the text decides the size, this sets the rest. Upright, never italic (an
   italic display quote is a known AI tell, research §2.2). */
.simple-section__quote .simple-section__quote-text {
  max-inline-size: 34em;
  font-style: normal;
  font-weight: 400;
  text-wrap: pretty;
}

/* A featured quote (heading size or larger) is set in the display face with
   the loose leading three to five lines of a sentence need — the aliases'
   own 1.1 is for one-line headlines. */
/* Measure: about 45 characters at a featured size, 65 at card size — so a
   featured quote in a full-width column sits left with its own trailing
   space, and never runs a sentence across the whole container. */
.simple-section__quote--featured .simple-section__quote-text {
  max-inline-size: 23em;
  font-family: var(--text-h2-family, inherit);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

/* Stars and source, 12px above the quote they belong to. */
.simple-section__quote-rating {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.75rem;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25rem;
}

.simple-section__quote-source a,
.simple-section__rating-count[href] {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

/* Attribution: a separate group, so twice the in-group gap from the quote
   (24px against 12px, research §2.1), avatar leading, name over meta. */
.simple-section__quote-by {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
  text-align: start;
}

.text-center .simple-section__quote-by {
  justify-content: center;
}

.simple-section__quote-who {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

/* Full ink for both lines: de-emphasis by size and weight, never by alpha
   (the overline's lesson, top of this file). */
.simple-section__quote-name {
  font-style: normal;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.5rem;
}

.simple-section__quote-meta {
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.25rem;
}

.simple-section__quote-avatar {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  object-fit: cover;
}

.simple-section__quote--featured .simple-section__quote-avatar {
  width: 3rem;
  height: 3rem;
}

.simple-section__quote-initials {
  display: grid;
  place-items: center;
  font-size: 0.875rem;
  font-weight: 600;
  background-color: var(--color-base-200);
  color: var(--color-base-content);
}

/* The one typographic ornament: an opening mark in the primary role, drawn
   once per quote and hidden from assistive technology. Its box is cut to half
   an em so the glyph does not add a line of air above the quote. */
.simple-section__quote-mark {
  display: block;
  height: 0.5em;
  margin-bottom: 0.25rem;
  font-family: var(--text-h1-family, inherit);
  font-size: 4.5rem;
  font-weight: 700;
  line-height: 1;
  color: var(--simple-section-star, var(--color-primary));
}

/* `hung`: from 1024px the mark sits in its own gutter at the quote's leading
   edge, the text column starting beside it, not under it. Below that there
   is no room to hang it and it sits above, as `above` does. */
@media (min-width: 1024px) {
  .simple-section__quote--mark-hung {
    padding-inline-start: 5.5rem;
  }

  .simple-section__quote--mark-hung .simple-section__quote-mark {
    position: absolute;
    inset-inline-start: 0;
    top: 0;
    margin: 0;
    font-size: 6rem;
  }
}

/* A hairline between stacked reviews (research §2.6) is a group boundary:
   24px each side, not the 12px between lines of one review. */
.simple-section__quote + hr.divider,
hr.divider + .simple-section__quote {
  margin-top: 1.5rem;
}

/* G2 — stars. One colour: filled in the primary role, an empty star the
   outline of the same role; a half star is the fill clipped at its middle,
   mirrored in right-to-left text. */
.simple-section__stars {
  display: inline-flex;
  gap: 2px;
  line-height: 0;
  vertical-align: middle;
  color: var(--color-primary);
}

.simple-section__star {
  position: relative;
  display: inline-block;
  width: 1.125rem;
  height: 1.125rem;
}

.simple-section__quote--featured .simple-section__star {
  width: 1.25rem;
  height: 1.25rem;
}

.simple-section__stars--summary .simple-section__star {
  width: 1.5rem;
  height: 1.5rem;
}

.simple-section__star svg {
  display: block;
  width: 100%;
  height: 100%;
}

.simple-section__star-line svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.simple-section__star-fill {
  position: absolute;
  inset: 0;
}

.simple-section__star-fill svg {
  fill: currentColor;
}

.simple-section__star--empty .simple-section__star-fill {
  display: none;
}

.simple-section__star--half .simple-section__star-fill {
  clip-path: inset(0 50% 0 0);
}

[dir="rtl"] .simple-section__star--half .simple-section__star-fill {
  clip-path: inset(0 0 0 50%);
}

/* G2 — the platform summary: source, the average large in tabular figures,
   stars, the count as a link to the reviews, the date it was read. */
.simple-section__rating {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.text-center .simple-section__rating {
  align-items: center;
}

.simple-section__rating-source {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25rem;
  letter-spacing: 0.02em;
}

.simple-section__rating-value {
  display: block;
  font-family: var(--text-h1-family, inherit);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.simple-section__rating-count {
  font-size: 1rem;
  line-height: 1.5rem;
}

.simple-section__rating-asof {
  font-size: 0.75rem;
  line-height: 1rem;
}

/* G4 — the figure band. Two across on a phone (an odd first figure takes the
   whole first row). From 768px a band of `columns: 2|3` goes across, hairlines
   between cells in the text colour; `columns: 4` stays two by two until 1024px,
   where a 60px figure fits a quarter of the row. From 1024px every band puts
   all its figures on one row — as many cells as figures, so three in a band
   declared for four still fill it. */
.simple-section__stats--grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2rem 1.5rem;
}

.simple-section__stats--grid > .simple-section__stat {
  text-align: start;
  min-width: 0;
}

.simple-section__stats--grid > .simple-section__stat:first-child:nth-last-child(odd) {
  grid-column: 1 / -1;
}

.simple-section__stats--grid .simple-section__stat-value,
.simple-section__stat-figure {
  font-variant-numeric: tabular-nums;
}

.simple-section__stats--grid .simple-section__stat-label {
  margin-top: 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.5rem;
}

.simple-section__stat-source {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  line-height: 1rem;
}

@media (min-width: 768px) {
  .simple-section__stats--cols-2,
  .simple-section__stats--cols-3 {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
  }

  .simple-section__stats--cols-2 > .simple-section__stat,
  .simple-section__stats--cols-3 > .simple-section__stat {
    grid-column: auto;
    padding-inline: 1.5rem;
    border-inline-start: 1px solid color-mix(in oklab, currentColor 22%, transparent);
  }
}

@media (min-width: 1024px) {
  .simple-section__stats--cols-4 {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
  }

  .simple-section__stats--cols-4 > .simple-section__stat {
    grid-column: auto;
    padding-inline: 1.5rem;
    border-inline-start: 1px solid color-mix(in oklab, currentColor 22%, transparent);
  }
}

@media (min-width: 768px) {
  .simple-section__stats--grid > .simple-section__stat:first-child {
    padding-inline-start: 0;
    border-inline-start: 0;
  }
}

/* G5 — `stretch`: a card grid whose cards end level. The column item, this
   root and its content box fill the column (the column is already the row's
   height), and a quote inside pushes its attribution to the card's foot so
   names line up across the row. The card pads 24px, never more than the
   24px grid gutter beside it (internal <= external, research P-F5a). */
.column-item:has(> .simple-section--stretch) {
  flex: 1 1 auto;
}

.simple-section--stretch {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  width: 100%;
}

.simple-section--stretch > .simple-section__content {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}

.simple-section--stretch > .simple-section__panel,
.simple-section--stretch > .simple-section__panel.card {
  padding: 1.5rem;
}

.simple-section--stretch .simple-section__quote {
  flex: 1 1 auto;
}

.simple-section--stretch .simple-section__quote-by {
  margin-top: auto;
  padding-top: 1.5rem;
}

/* A full-width heading column leading a card grid: 40px to the cards, not
   the 24px the grid puts between two cards (a heading and its group are
   separate groups; research §2.6, P4 proportions). */
.grid-cols-12:has(> .md\:col-span-6 .simple-section--stretch) > .col-span-12:first-child:not(.md\:col-span-6) {
  margin-bottom: 1rem;
}

/* G5 — the tablet orphan. Every part column is half the row from 768px to
   1023px, so a row of three cards became two and one alone. The odd last card
   takes the row instead: counted from the first column, or from the second
   when a full-width heading column leads the section. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .grid-cols-12:not(:has(> .col-span-12:first-child:not(.md\:col-span-6))) > .md\:col-span-6:last-child:nth-child(odd):has(.simple-section--stretch),
  .grid-cols-12:has(> .col-span-12:first-child:not(.md\:col-span-6)) > .md\:col-span-6:last-child:nth-child(even):has(.simple-section--stretch) {
    grid-column: span 12 / span 12;
  }
}

/* `container: measure` — a reading width that keeps the section's edge: left
   (or right) with the text, centred only when the text is. */
.simple-section__content.container-measure,
.simple-section__content.container-measure-wide {
  width: 100%;
  max-width: 36rem;
  margin-left: 0;
  margin-right: auto;
}

.simple-section__content.container-measure-wide {
  max-width: 48rem;
}

.text-center > .simple-section__content.container-measure,
.text-center > .simple-section__content.container-measure-wide {
  margin-left: auto;
}

.text-right > .simple-section__content.container-measure,
.text-right > .simple-section__content.container-measure-wide {
  margin-left: auto;
  margin-right: 0;
}

/* Logo strip (Logo_Strip_Component; its sizing is in the part's own rules).
   One monochrome treatment for every mark: a silhouette in near-black ink on
   a light ground, white on a dark one — never the marks' mixed colours, never
   a 60% grey that fails on a tinted ground (prove research G9). */
.logo-strip__image {
  filter: brightness(0);
  opacity: 0.85;
}

[data-theme$="-dark"] .logo-strip__image,
[data-theme$="-brand"] .logo-strip__image,
[data-theme="dark"] .logo-strip__image {
  filter: brightness(0) invert(1);
}

/* A trust bar (`facts` row, prove research P1): each fact one unit — an icon
   in a tinted disc, the fact, the line that backs it — spread evenly across
   the row for any count: one column on a phone, two on a tablet, all on one
   row from 1024px with hairlines between. */
.simple-section__facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem 2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 640px) {
  .simple-section__facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .simple-section__facts {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
  }

  .simple-section__fact + .simple-section__fact {
    padding-inline-start: 1.5rem;
    border-inline-start: 1px solid color-mix(in oklab, currentColor 18%, transparent);
  }

  .simple-section__fact {
    padding-inline-end: 1.5rem;
  }
}

.simple-section__fact {
  display: flex;
  align-items: flex-start;
  gap: 0.875rem;
  text-align: start;
}

.simple-section__fact-icon {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 9999px;
  font-size: 1.125rem;
  color: var(--simple-section-star, var(--color-primary));
  background-color: color-mix(in oklab, var(--simple-section-star, var(--color-primary)) 14%, transparent);
}

.simple-section__fact-body {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding-top: 0.125rem;
}

.simple-section__fact-title {
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.5rem;
}

.simple-section__fact-note {
  font-size: 0.875rem;
  line-height: 1.25rem;
}

/* The proof accent: the family's brand role as the PAGE sets it, read once at
   the root so a muted or tinted section finish (which desaturates its own
   --color-primary) does not grey the stars in one band and not the next
   (Prove review, 2026-09-28), and mixed a fifth toward the text colour so a
   star or an underline clears 3:1 on white (WCAG 1.4.11). */
:root {
  --simple-section-star: color-mix(in oklch, var(--color-primary) 80%, var(--color-base-content));
}

.simple-section__stars {
  color: var(--simple-section-star, var(--color-primary));
}

/* A review inside a panel card: daisyUI styles `.card figure` as a centred
   image frame (flex, centred, clipped), which centred the stars and pushed
   the attribution in. A testimonial figure is a text column, left. */
figure.simple-section__quote {
  align-items: stretch;
  justify-content: flex-start;
  overflow: visible;
  border-radius: 0;
}

/* Link items read as links: the ground's own ink (so it passes wherever the
   text around it does), bold, underlined in the proof accent, and an arrow
   after any link that goes to a page rather than dialling or mailing. An
   inline-block so the item gap above it applies. */
a.simple-section__link {
  position: relative;
  display: inline-block;
  font-weight: 600;
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--simple-section-star, var(--color-primary));
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}

/* A 44x44 target at least (site pack finding 12: the service-card and map
   "Call" links measured 28px tall at 412). An invisible box centred on the
   link, never smaller than the link itself: the words, the underline and
   everything around the link stay where they were. */
a.simple-section__link::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  min-width: 2.75rem;
  min-height: 2.75rem;
  translate: -50% -50%;
}

/* Two link items in a row (a call line under a directions link, an email
   under a call): each on its own line, 12px apart, one group. Inline-block
   alone set them edge to edge on one line, the arrow of the first touching
   the second (answer review, 2026-09-28). Block at its own width, so the
   underline still spans only the words. */
a.simple-section__link:has(+ a.simple-section__link),
a.simple-section__link + a.simple-section__link {
  display: block;
  width: fit-content;
}

a.simple-section__link + a.simple-section__link {
  margin-top: 0.75rem;
}

a.simple-section__link:hover {
  text-decoration-thickness: 3px;
}

a.simple-section__link:not([href^="tel:"]):not([href^="mailto:"])::after {
  content: "\2192";
  display: inline-block;
  margin-inline-start: 0.375em;
  text-decoration: none;
  transition: transform 0.15s ease;
}

a.simple-section__link:hover::after {
  transform: translateX(0.2em);
}

[dir="rtl"] a.simple-section__link:not([href^="tel:"]):not([href^="mailto:"])::after {
  content: "\2190";
}

@media (prefers-reduced-motion: reduce) {
  a.simple-section__link::after {
    transition: none;
  }
}

/* A link after a quote belongs to the attribution group's rhythm (24px),
   and after a hung quote it starts where the quote's text does. */
.simple-section__quote + a.simple-section__link {
  margin-top: 1.5rem;
}

@media (min-width: 1024px) {
  .simple-section__quote--mark-hung + a.simple-section__link {
    margin-inline-start: 5.5rem;
  }
}

/* A centred testimonial (prove-featured-quote, Rick 2026-09-28): the stars
   row and the quote's own measure centre with the text; the mark above and
   the attribution already follow text-align. */
.text-center .simple-section__quote-rating {
  justify-content: center;
}

.text-center .simple-section__quote-text {
  margin-inline: auto;
}

/* ==========================================================================
   EXPLAIN — prose rhythm, ordered steps, parallel points, the two-column
   checklist, facts tables, the phone order of a zigzag row, a sticky aside.
   The explain research (2026-09-28) is the spec; its gap names (X1–X9) are
   cited where each rule answers one. Tokens only: every colour is the proof
   accent (--simple-section-star) or the text colour around it.
   ========================================================================== */

/* X1 — paragraph rhythm, opt-in (`rhythm: prose`, so every approved section
   keeps the 12px it was approved with). One 12px gap everywhere made two
   paragraphs read as one block, and is itself a tell. A heading keeps its
   12px to the text it heads; paragraph to paragraph is 20px, most of a body
   line; text to a list or a step row is 16px; an action after text is a
   group of its own, 24px; a sub-heading after text starts a new group, 32px. */
.simple-section--prose > .simple-section__content > p + p,
.simple-section--prose .media-text__content > p + p {
  margin-top: 1.25rem;
}

.simple-section--prose > .simple-section__content > p + .simple-section__list,
.simple-section--prose .media-text__content > p + .simple-section__list,
.simple-section--prose > .simple-section__content > p + .simple-section__steps-wrap,
.simple-section--prose > .simple-section__content > p + .simple-section__features-wrap {
  margin-top: 1rem;
}

.simple-section--prose > .simple-section__content > p + a.simple-section__link,
.simple-section--prose > .simple-section__content > p + .btn,
.simple-section--prose > .simple-section__content > .simple-section__list + a.simple-section__link,
.simple-section--prose > .simple-section__content > .simple-section__list + .btn,
.simple-section--prose > .simple-section__content > .simple-section__steps-wrap + .btn,
.simple-section--prose > .simple-section__content > .simple-section__features-wrap + .btn,
.simple-section--prose .media-text__content > p + .btn,
.simple-section--prose .media-text__content > .simple-section__list + .btn {
  margin-top: 1.5rem;
}

.simple-section--prose > .simple-section__content > p + h3.text-heading {
  margin-top: 2rem;
}

/* A figure inside a reading column takes the box radius, as an
   Image_Component beside the text would. */
.simple-section--prose > .simple-section__content > img.object-cover {
  border-radius: var(--radius-box, 0.5rem);
}

/* A check item that wraps hangs its second line under its first word, not
   under the tick. */
.simple-section--prose .simple-section__list.list-check > li {
  display: grid;
  grid-template-columns: 1.375rem minmax(0, 1fr);
}

.simple-section--prose .simple-section__list.list-check > li::before {
  margin-right: 0;
}

/* A plain list beside a checklist (explain-two-sides' "can wait" side):
   Preflight strips the bullet and left the indent, so the items read as
   broken beside the ticks. A short rule in the text colour, softened, hung
   the same way as a tick (Explain review, 2026-09-28). */
.simple-section--prose .simple-section__list.list-bullet {
  padding-left: 0;
  list-style: none;
}

.simple-section--prose .simple-section__list.list-bullet > li {
  display: grid;
  grid-template-columns: 1.375rem minmax(0, 1fr);
}

.simple-section--prose .simple-section__list.list-bullet > li::before {
  content: "\2013";
  color: color-mix(in oklab, currentColor 60%, transparent);
}

/* X6 — a checklist in two columns where each can be at least 14rem wide, one
   where it cannot; items never split across the columns. */
.simple-section__list--cols-2 {
  columns: 2 14rem;
  column-gap: 2rem;
}

.simple-section__list--cols-2 > li {
  break-inside: avoid;
  padding-block: 0.25rem;
}

/* X3 / X4 — ordered steps. The row decides its own columns from its own
   width (a container), so a step row inside a split never squeezes. */
.simple-section__steps-wrap,
.simple-section__features-wrap {
  container-type: inline-size;
}

.simple-section__steps {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: start;
}

.simple-section__step-title {
  margin: 0;
  font-weight: 600;
  text-wrap: balance;
}

.simple-section__step-text {
  margin-top: 0.375rem;
  font-size: 1rem;
  line-height: 1.5rem;
}

.simple-section__step-marker {
  display: block;
  font-family: var(--text-h2-family, inherit);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--simple-section-star, var(--color-primary));
}

/* On a brand ground the page's primary IS the ground, so the proof accent
   read at :root put the numerals green on green (1.26:1 on emerald; site pack
   finding 11). There they take the ground's own ink, which clears 3:1 (large
   text) on the brand variant of every family (4.01:1 at its lowest, emerald;
   tests/layouts/steps-brand-contrast.test.mjs). */
[data-theme$="-brand"] .simple-section__step-marker {
  color: var(--color-base-content);
}

/* Across: a hairline over each step connects the row; numeral, title, text. */
.simple-section__steps--across {
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem 2rem;
}

.simple-section__steps--across > .simple-section__step {
  padding-top: 1.25rem;
  border-top: 1px solid color-mix(in oklab, currentColor 22%, transparent);
}

.simple-section__steps--across .simple-section__step-marker {
  margin-bottom: 0.75rem;
  font-size: 1.875rem;
}

@container (min-width: 36rem) {
  .simple-section__steps--across {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .simple-section__steps--across > .simple-section__step:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

@container (min-width: 48rem) {
  .simple-section__steps--cols-3 {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .simple-section__steps--cols-3 > .simple-section__step:last-child:nth-child(odd) {
    grid-column: auto;
  }
}

@container (min-width: 60rem) {
  .simple-section__steps--cols-4 {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .simple-section__steps--cols-4 > .simple-section__step:last-child:nth-child(odd) {
    grid-column: auto;
  }
}

/* Vertical: the numeral in its own column, a rail from each numeral down to
   the next. */
.simple-section__steps--vertical > .simple-section__step {
  position: relative;
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  column-gap: 1rem;
  padding-bottom: 1.5rem;
}

.simple-section__steps--vertical > .simple-section__step:last-child {
  padding-bottom: 0;
}

.simple-section__steps--vertical .simple-section__step-marker {
  padding-top: 0.125rem;
  font-size: 1.5rem;
  text-align: center;
}

.simple-section__steps--vertical > .simple-section__step:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 2.25rem;
  bottom: 0.375rem;
  inset-inline-start: calc(1.375rem - 0.5px);
  border-inline-start: 1px solid color-mix(in oklab, currentColor 22%, transparent);
}

/* Timeline: the time label where the numeral was, a dot on a continuous
   rail; below 30rem the label moves onto the rail above its step. */
.simple-section__steps--timeline > .simple-section__step {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  column-gap: 1.5rem;
}

.simple-section__step-label {
  padding-top: 0.125rem;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.5rem;
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.simple-section__steps--timeline .simple-section__step-body {
  position: relative;
  padding-inline-start: 1.5rem;
  padding-bottom: 1.75rem;
  border-inline-start: 2px solid color-mix(in oklab, currentColor 20%, transparent);
}

.simple-section__steps--timeline > .simple-section__step:last-child .simple-section__step-body {
  padding-bottom: 0;
}

.simple-section__steps--timeline .simple-section__step-body::before {
  content: "";
  position: absolute;
  top: 0.4375rem;
  inset-inline-start: -0.4375rem;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 9999px;
  background-color: var(--simple-section-star, var(--color-primary));
}

@container (max-width: 29.99rem) {
  .simple-section__steps--timeline > .simple-section__step {
    grid-template-columns: minmax(0, 1fr);
  }

  .simple-section__steps--timeline .simple-section__step-label {
    padding: 0 0 0.25rem 1.5rem;
    text-align: start;
    border-inline-start: 2px solid color-mix(in oklab, currentColor 20%, transparent);
  }
}

/* X8 — parallel points: an optional plain icon, title, text; no card, no
   hover, left-aligned; one column, two from 34rem, three from 52rem. */
.simple-section__features {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: start;
}

@container (min-width: 34rem) {
  .simple-section__features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .simple-section__features > .simple-section__feature:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

@container (min-width: 52rem) {
  .simple-section__features--cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .simple-section__features--cols-3 > .simple-section__feature:last-child:nth-child(odd) {
    grid-column: auto;
  }
}

.simple-section__feature--icon {
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr);
  column-gap: 0.875rem;
}

.simple-section__feature-icon {
  font-size: 1.375rem;
  line-height: 1.75rem;
  text-align: center;
  color: var(--simple-section-star, var(--color-primary));
}

.simple-section__feature-title {
  margin: 0;
  font-weight: 600;
  text-wrap: balance;
}

.simple-section__feature-text {
  margin-top: 0.375rem;
  font-size: 1rem;
  line-height: 1.5rem;
}

a.simple-section__feature-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--simple-section-star, var(--color-primary));
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
}

/* X7 — a table that explains: body-size cells, full-ink header, the first
   cell of each row a row header in the label weight, cells top-aligned so a
   two-line value starts level with its label. */
.table.table--body {
  font-size: 1rem;
  line-height: 1.5rem;
}

.table.table--body :where(thead, tfoot) {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-base-content);
}

.table.table--body :where(td, th) {
  vertical-align: top;
}

.table.table--row-headers tbody th[scope="row"] {
  font-weight: 600;
  text-align: start;
}

/* X2 — `phone_order` on Media_Text: once the pair stacks (the container is
   narrower than two 20rem columns and the widest gap), the named column goes
   first. Only for Media_Text that asks; every other keeps source order. */
.media-text__container--ordered {
  container-type: inline-size;
}

@container (max-width: 43.99rem) {
  .media-text__grid.media-text__grid--text-first,
  .media-text__grid.media-text__grid--media-first {
    grid-template-columns: minmax(0, 1fr);
  }

  .media-text__grid--text-first > .media-text__content,
  .media-text__grid--media-first > .media-text__media {
    order: -1;
  }
}

/* X9 — a sticky column (`sticky: true`): from 1024px it holds its place
   below the header while the taller column beside it scrolls. */
@media (min-width: 1024px) {
  .column--sticky {
    position: sticky;
    top: calc(var(--sticky-header-height, 0px) + var(--plexa-chrome-top, 0px) + 1.5rem);
    align-self: start;
    height: auto;
  }
}

/* ==========================================================================
   OFFER — a price, the recommended card in a row of plans, a card's action at
   its foot, a price column. The offer research (2026-09-28) is the spec; its
   gap names (O1 price, O2 recommendation, O3 pinned action, O9 price column)
   are cited where each rule answers one. Tokens only: the primary role, its
   content colour, and the text colour around them.
   ========================================================================== */

/* O1 — a price. "From", the amount and its unit share one baseline, so they
   read as one phrase; the amount carries the size (the card's key fact) in
   tabular figures; the rest of the price sits directly under it, at body
   size, never in small print. */
.simple-section__price-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.5rem;
  row-gap: 0.25rem;
  margin: 0;
}

.text-center .simple-section__price-line {
  justify-content: center;
}

.simple-section__price-amount {
  font-family: var(--text-h2-family, inherit);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.simple-section__price-qualifier,
.simple-section__price-unit {
  font-size: 1rem;
  line-height: 1.5rem;
}

.simple-section__price-qualifier {
  font-weight: 600;
}

.simple-section__price-note {
  margin-top: 0.5rem;
  font-size: 1rem;
  line-height: 1.5rem;
}

/* The price is its own group in running text: 20px after what introduces
   it, a list or an action after it as after any text. */
.simple-section--prose > .simple-section__content > p + .simple-section__price {
  margin-top: 1.25rem;
}

.simple-section--prose > .simple-section__content > .simple-section__price + .simple-section__list {
  margin-top: 1.25rem;
}

.simple-section--prose > .simple-section__content > .simple-section__price + .btn,
.simple-section--prose > .simple-section__content > .simple-section__price + a.simple-section__link,
.simple-section--prose > .simple-section__content > p + .simple-section__buttons,
.simple-section--prose > .simple-section__content > .simple-section__list + .simple-section__buttons,
.simple-section--prose > .simple-section__content > .btn + a.simple-section__link {
  margin-top: 1.5rem;
}

/* O2 — the recommended card. A 2px edge in the primary role (an outline, so
   the card's box and its content do not move against its neighbours) and
   the reason on the card's top edge, out of the flow: names, prices and
   buttons stay level across the row. No scale, no glow, no shadow change. */
/* Two classes: daisyUI's .card sets a transparent 2px outline of its own. */
.simple-section__panel.simple-section__panel--featured {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.simple-section__panel-label {
  position: absolute;
  top: 0;
  inset-inline-start: 1.5rem;
  max-width: calc(100% - 3rem);
  padding: 0.25rem 0.75rem;
  overflow: hidden;
  border-radius: 9999px;
  background-color: var(--color-primary);
  color: var(--color-primary-content);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25rem;
  white-space: nowrap;
  text-overflow: ellipsis;
  transform: translateY(-50%);
}

/* Both wrappers render_content_item() (and now render_content_column())
   can land in — see the "Every content item after the first" note above for
   why Media_Text_Component needs its own selector beside Simple_Section's. */
.simple-section__content > .simple-section__panel-label + *,
.media-text__content > .simple-section__panel-label + * {
  margin-top: 0;
}

/* O3 — a stretched card's last action sits at the card's foot, so a row of
   plans or services ends with its buttons (or links) on one line whatever
   each card holds above them. The item before it keeps 24px, the least the
   action may sit from what it follows. A link keeps its own width. */
.simple-section--stretch > .simple-section__content > :is(.btn, a.simple-section__link, .simple-section__buttons):last-child {
  margin-top: auto;
}

.simple-section--stretch > .simple-section__content > :has(+ :is(.btn, a.simple-section__link, .simple-section__buttons):last-child) {
  margin-bottom: 1.5rem;
}

.simple-section--stretch > .simple-section__content > a.simple-section__link:last-child {
  align-self: flex-start;
}

/* O9 — a price column: figures aligned to the end, tabular, header with
   them, so the amounts read down the column. */
.table :where(th, td).table__numeric {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   OFFER REVIEW (2026-09-28)
   ========================================================================== */

/* Level card rows, for real. surfaces.css sets every section `.column-item`
   to display:block ("allow natural flow"), so `flex: 1 1 auto` on a stretched
   section inside it did nothing and each card kept its content height: in
   offer-three-plans the third card ended short with its button high, in
   offer-service-row the fourth ran long with its link low. A column item that
   holds a stretched section is a flex column again, so the card fills the
   column (already the row's height) and O3 pins its action to the foot. */
.plexa-content-section .column-item:has(> .simple-section--stretch) {
  display: flex;
  flex-direction: column;
}

/* A filled button on a muted ground keeps the family's full primary. A
   muted finish drops every role colour to a third of
   its chroma (scripts/generate-theme-modes.js, generateMuted), which is right
   for washes and accents and wrong for a filled button: at 0.05 chroma the
   primary button read as disabled (offer-price-range on the muted band). The
   page's own family declares the action colours on the element that carries
   the unmuted theme; a muted section does not redeclare them, so its buttons
   inherit the family's real primary. */
[data-theme]:not([data-theme$="-muted"]):not([data-theme$="-muted-dark"]) {
  --plexa-action-primary: var(--color-primary);
  --plexa-action-primary-content: var(--color-primary-content);
}

[data-theme$="-muted"] .btn-primary,
[data-theme$="-muted-dark"] .btn-primary,
.btn-primary[data-theme$="-muted"],
.btn-primary[data-theme$="-muted-dark"] {
  --btn-color: var(--plexa-action-primary, var(--color-primary));
  --btn-fg: var(--plexa-action-primary-content, var(--color-primary-content));
}

/* Opening hours in a text group (the `hours` item): a label over the lines,
   24px after the call line it belongs to, full ink, 16px. */
.simple-section__hours { margin: 0; }
.simple-section__hours p { margin: 0; font-size: 1rem; line-height: 1.5rem; }
.simple-section__hours-label { font-weight: 600; }
.simple-section--prose > .simple-section__content > p + .simple-section__hours,
.simple-section--prose > .simple-section__content > a.simple-section__link + .simple-section__hours,
.simple-section--prose > .simple-section__content > .btn + .simple-section__hours {
  margin-top: 1.5rem;
}

/* ==========================================================================
   CLOSE — the close research (2026-09-28) gaps KG1 and KG2, and the rhythm
   of the action group a close ends on. Tokens only.
   ========================================================================== */

/* KG1 — a section button is a 44px target, 48px on a phone (WCAG 2.5.8; the
   48px CTA floor for a phone; the same 44px base the form's submit and
   fields share, form.css). daisyUI's .btn was 40px. Height follows its
   content, so a label that must wrap grows rather than clips. */
.simple-section__content .btn {
  min-height: 2.75rem;
  height: auto;
}

@media (max-width: 767px) {
  .simple-section__content .btn {
    min-height: 3rem;
  }
}

/* The one reassurance line under a close's buttons: 16px below them, full
   ink, body size (KB3). */
.simple-section--prose > .simple-section__content > .simple-section__buttons + p {
  margin-top: 1rem;
}

/* KG2 — a link set at a type size (the phone-first close's number): its
   own line at its own width, tabular figures so the digits do not shift,
   an underline scaled to the size, and a little more air around it than a
   running link. The size alias sets its font size and line height. */
a.simple-section__link--sized {
  display: block;
  width: fit-content;
  max-width: 100%;
  font-variant-numeric: tabular-nums;
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.12em;
  overflow-wrap: anywhere;
}

.simple-section__content > * + a.simple-section__link--sized {
  margin-top: 1rem;
}

.simple-section__content > a.simple-section__link--sized + * {
  margin-top: 1rem;
}

/* A signed note's signature: the name at subheading size and weight, the
   role and business directly under it as one attribution group. */
.simple-section--prose > .simple-section__content > p.text-subheading:has(+ p.text-body) {
  font-weight: 600;
}

.simple-section--prose > .simple-section__content > p.text-subheading + p.text-body {
  margin-top: 0.25rem;
}
