/* ============================================================
   Solaris Certified — /certified/.

   Values are the Solaris Design System tokens, which this page loads from
   assets/ds/tokens/ unedited. Nothing here invents a colour, a step or a
   size: every value is a var(), exactly as the handoff has it, with the few
   deliberate exceptions called out in comments where they appear.

   Everything is scoped under .sol-certified. The tokens themselves sit on
   :root, which is safe — they are custom properties and paint nothing on
   their own — but the element defaults the design system ships in base.css
   are NOT loaded, because they would restyle the site header and any
   Elementor content sharing the page. They are reproduced here instead,
   scoped to this page.

   THE TWO ORANGES ARE NOT INTERCHANGEABLE, and getting them backwards is the
   most likely way to break the brand:
     --color-accent-default  #F15C30 Flamingo, the ACTION colour: buttons and
                                     links, nothing else.
     --color-accent-highlight #FF9A24 Princeton Orange, ILLUSTRATION: badges,
                                     plinths, meters, baselines, the tick.
   Orange type fails contrast on white (2.06:1), which is why
   --color-text-accent-ink (#9A5A00) exists and why eyebrows use it. Ink ON
   Princeton Orange is black, --color-on-accent-highlight, never white
   (CA-3.5 / CA-4.3).

   Section order below follows the page.
   ============================================================ */

/* ---- Page shell -------------------------------------------- */

.sol-certified {
  /* The deferred brand decision (system task WEB-14). Button reads
     --button-radius and production ships square, so square is the default
     here too. One line flips the whole page to pills:
     --button-radius: var(--radius-pill). */
  --button-radius: 0px;

  /* Vertical rhythm. Every section is `padding: var(--sec) 0`, so a seam
     between two sections is 2 x --sec regardless of the grounds either side.

     --sec IS the design system's section half and nothing else. The sectionPad
     option that used to set --sec-max inline from page-certified.php is gone
     (2026-09-20): a per-page knob on a ratified system value is how one page
     drifts off the rhythm, and an inline custom property outranks every media
     query in this file, so the knob could silently kill the steps at the
     bottom of it too. */
  --sec: var(--layout-section-half);

  /* The band's inset and the band's lead, read straight from the system. The
     tokens make their own one step at 720 (section half 112 -> 64, band inset
     80 -> 48; the lead stays 16), so this page carries no step-downs of its
     own (CA-1.9, CA-1.4). */
  --band: var(--layout-band-inset);
  --lead: var(--layout-band-lead);

  /* The content column is 1280px with 32px gutters. Everything here is
     border-box, so the wrapper carries the column plus both gutters. */
  --wrap: calc(var(--layout-max-width) + 2 * var(--layout-gutter));

  background: var(--color-surface-default);
  color: var(--color-text-secondary);
  font: var(--type-body-base);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* The offset panel runs off the top of the page and the plinth reaches past
     its column; neither may put a horizontal scrollbar on the document. */
  overflow-x: clip;
}

/* The dialog's wrapper needs the scope but must not paint a ground or clip
   anything — a clipping ancestor around a fixed-position scrim is a trap. */
.sol-certified--portal {
  background: none;
  overflow: visible;
}

.sol-certified *,
.sol-certified *::before,
.sol-certified *::after { box-sizing: border-box; }

/* The dialog, the two form panels, the success panel and the error line are
   all shown and hidden with the hidden attribute, and each carries a class
   that sets display — which outranks the user agent's [hidden] rule and
   leaves them on screen. This is the guard. The <noscript> block in
   dialog.php overrides it for its own case and is later in the document, so
   it still wins. */
.sol-certified [hidden] { display: none !important; }

/* The element defaults, in :where() so they weigh nothing of their own. They
   still outrank Bootstrap's reboot, which the site loads on every page and
   which has its own opinion about heading sizes and paragraph margins, and
   they no longer outrank the component classes below. */
.sol-certified :where(h1, h2, h3, h4) { color: var(--color-text-primary); margin: 0; }

.sol-certified :where(h1) { font: var(--type-heading-1); letter-spacing: var(--type-heading-1-tracking); }
/* H2's tracking is POSITIVE (+2%) and that is a real brand tell taken from the
   Figma named style, not a typo.

   h2 and h3 are FLUID below 1024 (CA-2.7): h2 28 -> 40, h3 22 -> 28. The
   clamps cap at 1024 on their own, so there are no heading steps anywhere in
   this file; the line-height stays the token's. Display/xl needs nothing: it
   already clamps to 44px. */
.sol-certified :where(h2) {
  font: var(--type-heading-2);
  font-size: var(--type-heading-2-fluid-size);
  letter-spacing: var(--type-heading-2-tracking);
}
.sol-certified :where(h3) {
  font: var(--type-heading-3);
  font-size: var(--type-heading-3-fluid-size);
  letter-spacing: var(--type-heading-3-tracking);
}
.sol-certified :where(h4) { font: var(--type-heading-4); letter-spacing: var(--type-heading-4-tracking); }

.sol-certified :where(p) { margin: 0; }
.sol-certified :where(ol, ul) { margin: 0; padding: 0; list-style: none; }
.sol-certified :where(img) { max-width: 100%; display: block; }
.sol-certified :where(a) { color: var(--color-text-link); text-decoration: none; }
.sol-certified :where(a:hover) { color: var(--color-accent-hover); }

/* Inline links in body copy are underlined (CA-4.4): Flamingo, hover
   --color-accent-hover at fast. The :where(a) base above stays bare so the
   buttons and tabs, which are links too, are untouched. */
.sol-certified :is(.sol-certified__lead, .sol-certified__body, .sol-certified__success-body, .sol-certified__form-error) a {
  text-decoration: underline;
  transition: color var(--motion-duration-fast) var(--motion-ease);
}
.sol-certified :where(fieldset) { margin: 0; padding: 0; border: 0; min-width: 0; }
.sol-certified :where(input, button, select, textarea) { font-family: inherit; }

/* Keep a visible ring. The design removes the outline and replaces it with
   the focus elevation; removing one without the other is how a keyboard
   reader loses the page. */
.sol-certified :focus-visible { outline: 0; box-shadow: var(--elevation-focus); }

.sol-certified__sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Button ------------------------------------------------
   The design system's Button, in CSS. The bundle's version injects this same
   sheet from JavaScript; a server-rendered page has no reason to wait for
   that. Class names are the bundle's so the two stay recognisably one
   component. One size only: min-height 44px with 24/48 padding and a 15px
   label, which reproduces production's measured 160x62.

   Identical to the awards page's copy, on purpose — when the theme grows a
   components stylesheet, both pages drop their copy and link that. */

.sol-certified .sds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-200);
  box-sizing: border-box;
  min-height: var(--target-min);
  border: 0;
  padding: var(--space-500) var(--space-700);
  border-radius: var(--button-radius, 0px);
  font: var(--type-control-base);
  letter-spacing: var(--type-control-base-tracking);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  /* Colour only. Hover changes colour and nothing else: no lift, no shadow. */
  transition: background-color var(--motion-duration-fast) var(--motion-ease),
              color var(--motion-duration-fast) var(--motion-ease),
              border-color var(--motion-duration-fast) var(--motion-ease);
}

.sol-certified .sds-btn--solid { background: var(--color-accent-default); color: var(--color-text-inverse); }
.sol-certified .sds-btn--solid:hover { background: var(--color-accent-hover); color: var(--color-text-inverse); text-decoration: none; }

/* The 2px border is the one unmeasured, untokenised value in the component.
   Both variants must be the same height, so the outline pays for its border
   out of its own padding. */
.sol-certified .sds-btn--outline {
  background: transparent;
  /* Amber Ink, not navy (CA-4.2). */
  color: var(--color-text-accent-ink);
  border: 2px solid var(--color-accent-default);
  padding: calc(var(--space-500) - 2px) calc(var(--space-700) - 2px);
}
.sol-certified .sds-btn--outline:hover { border-color: var(--color-accent-hover); color: var(--color-accent-hover); text-decoration: none; }

.sol-certified .sds-btn[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }

/* Phones: every button runs the full width, keeping its 48 side pad (CA-4.10). */
@media (max-width: 720px) {
  .sol-certified .sds-btn { width: 100%; }
}

/* ---- Layout primitives ------------------------------------- */

.sol-certified__wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--layout-gutter);
}

.sol-certified__section { padding: var(--sec) 0; }

/* A full-bleed band of sunken grey, for the tier cards. */
.sol-certified__band {
  background: var(--color-surface-sunken);
  padding: var(--band) 0;
}

/* THE BAND LEAD: heading on white, band below it, this gap between them. It is
   carried as padding on the heading's own wrapper rather than as margin-top on
   the band, because spacing in this system is padding - a margin here is one
   collapse away from putting a gap where the two grounds are supposed to meet.
   Scoped to the collection's DIRECT wrap so it cannot reach the wrap nested
   inside the band. */
.sol-certified__tiers > .sol-certified__wrap { padding-bottom: var(--lead); }

/* ---- Shared type ------------------------------------------- */

.sol-certified__eyebrow {
  font: var(--type-label-sm);
  letter-spacing: var(--type-label-sm-tracking);
  text-transform: uppercase;
  /* Not --color-accent-highlight: orange type on white is 2.06:1. */
  color: var(--color-text-accent-ink);
  margin-bottom: var(--space-400);
}

.sol-certified__lead {
  font: var(--type-body-lg);
  color: var(--color-text-secondary);
  text-wrap: pretty;
}

.sol-certified__body {
  font: var(--type-body-base);
  color: var(--color-text-secondary);
  text-wrap: pretty;
}

.sol-certified__body strong { color: var(--color-text-primary); }

.sol-certified__lead--measure { max-width: 50ch; }

/* ---- The dot-grid disc -------------------------------------
   The page's only texture, standing in for the photography and line-art
   production uses as section accents and which this design never received
   (they live in the WordPress media library, and wp-content/uploads is
   gitignored). Two sizes, both Princeton Orange at low opacity. */

.sol-certified__dots {
  position: absolute;
  border-radius: var(--radius-pill);
  background-image: radial-gradient(var(--color-accent-highlight) 1.5px, transparent 1.5px);
  background-size: 13px 13px;
  pointer-events: none;
}

.sol-certified__dots--offset {
  width: 104px;
  height: 104px;
  bottom: var(--space-700);
  left: var(--space-700);
  opacity: .4;
}

.sol-certified__dots--plinth {
  width: 170px;
  height: 170px;
  bottom: -54px;
  right: -46px;
  opacity: .35;
}

/* ============================================================
   1. Hero
   ============================================================ */

.sol-certified__hero {
  position: relative;
  background: var(--color-surface-default);
  /* Top 64 (48 at 720) and bottom the section half, 112 (64 at 720), both
     from the tokens (CA-1.2, CA-1.3). */
  padding: var(--layout-hero-top) 0 var(--sec);
}

/* THE OFFSET PANEL. Ratified geometry, not eyeballed — place it from the
   content column, never from the viewport and never from a nudge:

     - anchored to the content column's RIGHT edge;
     - exactly HALF the content column wide, so its left edge is the column's
       centre line, which is where the badge plinth reaches to;
     - it runs off the TOP of the page, up behind the header, so it has no top
       edge and no top corners. Only the two bottom corners are rounded;
     - its bottom edge falls BEHIND the form card, so the seam is hidden by an
       object rather than ending in open space. Hence 780px against a -140px
       top: the number is "past the bottom of the card", not a measured height.

   Below the hero row's stack threshold it becomes a grey box around the
   hero copy (CA-5.3) — see the responsive section. */
.sol-certified__offset {
  position: absolute;
  top: -140px;
  height: 780px;
  right: max(var(--layout-gutter), calc((100% - var(--layout-max-width)) / 2));
  width: calc(min(var(--layout-max-width), 100% - 2 * var(--layout-gutter)) / 2);
  background: var(--color-surface-offset);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  overflow: hidden;
}

.sol-certified__hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  gap: var(--space-800);
  /* Start, not stretch (CA-7.7): the headline sits straight under the top
     pad and neither column is pulled to the other's height. */
  align-items: start;
}

.sol-certified__hero-copy {
  display: flex;
  flex-direction: column;
}

.sol-certified__display {
  font: var(--type-display-xl);
  letter-spacing: var(--type-display-xl-tracking);
  margin-bottom: var(--space-600);
  text-wrap: pretty;
}

.sol-certified__hero-lead {
  font: var(--type-body-lg);
  color: var(--color-text-secondary);
  max-width: 46ch;
  text-wrap: pretty;
}

/* The gap between the paragraph and the plinth. The hero row is
   align-items: start (CA-7.7), so the column is its content's height and
   this is a plain 48, not a pin to the bottom of the row. */
.sol-certified__hero-spacer { flex: 1 0 var(--space-700); }

/* THE BADGE PLINTH. Navy's documented job is a dark OBJECT, never a section
   ground — the hero stays white. Pulled right by half the row gap
   (space-800 / 2 = space-600) so its right edge lands exactly on the content
   column's centre line, where the grey panel begins. The plinth and the panel
   interlock on a line the layout already owns. */
.sol-certified__plinth {
  position: relative;
  margin: 0 calc(-1 * var(--space-600)) 0 0;
  background: var(--color-surface-invert);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-300);
  /* 32 all round: the 40 sides snap to the card scale (CA-6.11). */
  padding: var(--space-600);
  display: flex;
  align-items: center;
  gap: var(--space-600);
  overflow: hidden;
}

.sol-certified__plinth-badge {
  position: relative;
  /* 100px, not 150px: the badge file is the artwork with no box around it.
     The old padded export needed 150px to draw the same 100px badge. */
  width: 100px;
  height: auto;
  flex: none;
  /* Lifts the badge off the navy. It is a shadow cast BY the badge, not a
     restyling of it — the artwork itself is untouched. Navy-tinted, not black
     (CA-5.9): the deep navy, since the plinth's own navy would not show. */
  filter: drop-shadow(0 12px 28px var(--color-base-navy-900));
}

.sol-certified__plinth-text {
  position: relative;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-300);
}

.sol-certified__plinth-eyebrow {
  font: var(--type-label-sm);
  letter-spacing: var(--type-label-sm-tracking);
  text-transform: uppercase;
  /* Princeton Orange IS legible on navy — the contrast problem is on white. */
  color: var(--color-accent-highlight);
}

.sol-certified__plinth-title {
  font: var(--type-heading-4);
  letter-spacing: var(--type-heading-4-tracking);
  color: var(--color-text-inverse);
}

.sol-certified__plinth-sub {
  font: var(--type-body-sm);
  color: var(--color-on-invert-secondary);
}

/* #waitlist is the refrain buttons' target without JavaScript, so it clears
   the sticky header: 96 once its strip has retracted, 72 below 1024, plus 24
   (CA-8.9). */
.sol-certified__hero-form {
  position: relative;
  scroll-margin-top: calc(96px + var(--space-500));
}

@media (max-width: 1023.98px) {
  .sol-certified__hero-form { scroll-margin-top: calc(72px + var(--space-500)); }
}

/* ---- The waiting-list card ---------------------------------
   The page's primary conversion point, rendered twice: here as a white raised
   card, and again inside the dialog. */

.sol-certified__form-card--hero {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  /* 100, not 200 (CA-6.7): the plinth beside it keeps 300. */
  box-shadow: var(--elevation-100);
  padding: var(--space-600);
}

/* An <h2> carrying heading/3's size: the level is for the document outline,
   the size is the design's. */
.sol-certified__form-title {
  font: var(--type-heading-3);
  letter-spacing: var(--type-heading-3-tracking);
  margin-bottom: var(--space-400);
}

.sol-certified__form-sub {
  font: var(--type-body-base);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-500);
}

/* The audience toggle. Links, not buttons, so a reader without JavaScript can
   still reach the homeowner fields on a page load; certified.js intercepts
   them and switches the field set in place. */
.sol-certified__tabs {
  display: flex;
  gap: var(--space-100);
  padding: var(--space-100);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunken);
  margin-bottom: var(--space-500);
}

.sol-certified__tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target-min);
  padding: var(--space-300) var(--space-400);
  border: 0;
  border-radius: var(--radius-pill);
  font: var(--type-control-sm);
  letter-spacing: var(--type-control-sm-tracking);
  text-align: center;
  cursor: pointer;
  background: transparent;
  color: var(--color-text-secondary);
  transition: background-color var(--motion-duration-fast) var(--motion-ease),
              color var(--motion-duration-fast) var(--motion-ease);
}

.sol-certified__tab:hover { color: var(--color-text-primary); }

/* ACTIVE INK ON PRINCETON ORANGE IS BLACK, NOT WHITE (CA-4.3). White is 2.1:1
   and fails AA. Do not "fix" it back to white. */
.sol-certified__tab[aria-selected="true"] {
  background: var(--color-accent-highlight);
  color: var(--color-on-accent-highlight);
}

.sol-certified__tab[aria-selected="true"]:hover { color: var(--color-on-accent-highlight); }

.sol-certified__fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--space-400);
}

.sol-certified__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sol-certified__field--wide { grid-column: 1 / -1; }

.sol-certified__label {
  font: var(--type-label-base);
  letter-spacing: var(--type-label-base-tracking);
  color: var(--color-text-primary);
}

/* Non-required fields say so; required ones stay unmarked (CA-10.7). */
.sol-certified__optional { color: var(--color-text-muted); }

/* 0/16 on a 44 floor (CA-10.1), the control border (CA-10.4). Focus is the
   halo alone, from the :focus-visible rule at the top of the file: no border
   change on focus or hover (CA-10.3). */
.sol-certified__input {
  width: 100%;
  min-height: var(--target-min);
  padding: 0 var(--space-400);
  border: 1px solid var(--color-border-control);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
  /* 16px, deliberately: anything smaller makes iOS Safari zoom on focus. */
  font: var(--type-body-base);
  color: var(--color-text-primary);
}

/* A field the script or the server objected to. The message under it is the
   answer; the border only says which field it belongs to. */
.sol-certified__input[aria-invalid="true"] { border-color: var(--color-feedback-error); }

/* The field message, directly under its own input (CA-10.5 / 10.6). */
.sol-certified__field-error {
  font: var(--type-body-sm);
  color: var(--color-feedback-error);
}

/* The consent row carries the pad so its message can sit under the box,
   inside it. The box itself is unchanged (CA-10.7 consent: deferred). */
.sol-certified__consent-field {
  display: flex;
  flex-direction: column;
  /* No gap: the box's 44 target already leaves room under a one-line
     label. */
  gap: 0;
  padding: var(--space-400) 0 var(--space-500);
}

.sol-certified__consent {
  display: flex;
  gap: var(--space-300);
  align-items: flex-start;
  min-height: var(--target-min);
  font: var(--type-body-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
}

.sol-certified__consent input {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 3px 0 0;
  /* The only place Flamingo appears as a fill outside a button: a checkbox is
     an action control, so it takes the action colour. */
  accent-color: var(--color-accent-default);
}

/* The line above the fields, now only for a send that failed — a message
   about something the reader typed goes under that field instead. No bar,
   no inset (CA-10.5). */
.sol-certified__form-error {
  font: var(--type-body-base);
  color: var(--color-feedback-error);
  margin-bottom: var(--space-500);
}

/* Off-screen rather than display:none: a bot reading the DOM finds a real,
   fillable field, which is the whole point of it. */
.sol-certified__honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.sol-certified__count {
  font: var(--type-body-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-400);
}

.sol-certified__count strong { color: var(--color-text-accent-ink); }

/* The success state replaces the form in place. */
.sol-certified__success {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-400);
  padding: var(--space-400) 0;
}

.sol-certified__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-highlight);
  color: var(--color-on-accent-highlight);
  font: var(--type-heading-3);
  letter-spacing: var(--type-heading-3-tracking);
}

.sol-certified__success-body {
  font: var(--type-body-base);
  color: var(--color-text-secondary);
}

/* ============================================================
   2. The four tiers
   ============================================================ */

/* The section pads 112 below its band as well as above its heading
   (CA-1.5). */
.sol-certified__tiers { background: var(--color-surface-default); padding: var(--sec) 0; }

/* The design file carries width/height literals here from a direct
   manipulation in the design tool. They are dropped: the block is capped and
   otherwise fluid. */
.sol-certified__intro { max-width: 720px; }
.sol-certified__intro h2 { margin-bottom: var(--space-500); text-wrap: pretty; }

.sol-certified__quad {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: var(--space-500);
}

.sol-certified__tier {
  background: var(--color-surface-raised);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-100);
  padding: var(--space-500);
  display: flex;
  flex-direction: column;
  gap: var(--space-500);
}

.sol-certified__tier-badge { width: 61px; height: auto; }

/* The evidence-depth meter, pinned to the bottom of the card whatever the
   heading above it does. It says "higher tiers ask for more" and NOTHING
   further — no criteria, no counts, no "most popular". None of that is known
   yet and inventing it is a commercial promise, not filler. */
.sol-certified__meter {
  margin-top: auto;
  padding-top: var(--space-400);
  border-top: 1px solid var(--color-border-default);
}

.sol-certified__pips {
  display: flex;
  gap: var(--space-100);
  margin-bottom: var(--space-300);
}

.sol-certified__pip {
  flex: 1;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-border-default);
}

.sol-certified__pip.is-filled { background: var(--color-accent-highlight); }

.sol-certified__meter-caption {
  font: var(--type-label-sm);
  letter-spacing: var(--type-label-sm-tracking);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* ============================================================
   3 & 5. The editorial rows

   Device left here, device right at #checks and in the homeowner section.
   Strict ABAB is the page-structure rule: if one moves, the other moves too.
   The order is set in CSS rather than in the markup so the stacked layout can
   keep a sensible reading order — at every width the copy comes first.
   ============================================================ */

.sol-certified__editorial {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
  gap: var(--space-800);
  align-items: center;
}

/* #checks hangs its diagram from the top of the row rather than centring it:
   the copy beside it is much shorter, and a centred card leaves the orange
   header bar floating level with the middle of the paragraph. */
.sol-certified__editorial--top { align-items: start; }

/* ---- The failure timeline (device, left) ---- */

.sol-certified__timeline {
  background: var(--color-surface-offset);
  border-radius: var(--radius-lg);
  /* 32 all round (CA-6.11). Its eyebrow keeps the standard 16 below it
     (CA-3.4): the timeline is a rail of dots, not a dense hairline list. */
  padding: var(--space-600);
}

.sol-certified__step { display: flex; gap: var(--space-400); }

.sol-certified__step-rail {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 7px;
}

.sol-certified__step-dot {
  width: 11px;
  height: 11px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-highlight);
}

/* The connector runs from the dot to the next one. The last step has none:
   the line stops where the argument does. */
.sol-certified__step-line {
  flex: 1;
  width: 2px;
  background: var(--color-border-default);
}

.sol-certified__step-body {
  min-width: 0;
  padding-bottom: var(--space-500);
}

.sol-certified__step--last .sol-certified__step-body { padding-bottom: 0; }

.sol-certified__step-title {
  display: block;
  font: var(--type-item-base);
  letter-spacing: var(--type-item-base-tracking);
  color: var(--color-text-primary);
}

.sol-certified__step-text {
  display: block;
  font: var(--type-body-sm);
  color: var(--color-text-secondary);
  margin-top: var(--space-200);
}

/* ---- The copy column ---- */

.sol-certified__editorial-copy h2 { margin-bottom: var(--space-600); text-wrap: pretty; }
.sol-certified__editorial-copy .sol-certified__lead { margin-bottom: var(--space-500); }
.sol-certified__editorial-copy .sol-certified__lead:last-child { margin-bottom: 0; }
.sol-certified__editorial-copy .sol-certified__body { margin-bottom: var(--space-600); }
.sol-certified__editorial-copy .sol-certified__body:last-child { margin-bottom: 0; }

/* Device left, copy right — the mirror of #checks and the homeowner section
   below it, both of which need no rule at all because device-right IS the
   source order. The copy comes first in the markup of every row, so a stacked
   column always reads heading-then-device; only the wide layout swaps them
   back, and only here. 968px is the complement of the hero's stack
   threshold. */
@media (min-width: 968px) {
  .sol-certified__editorial--device-left > .sol-certified__timeline { order: 1; }
  .sol-certified__editorial--device-left > .sol-certified__editorial-copy { order: 2; }
}

/* ============================================================
   4. Refrains 1 and 2

   The same block, verbatim, twice. That repetition is production's own rhythm
   device — it is not a duplicate to tidy up.
   ============================================================ */

.sol-certified__refrain { background: var(--color-surface-default); }

.sol-certified__refrain-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-500);
  text-align: center;
}

.sol-certified__refrain-inner h2 { text-wrap: pretty; }

/* 24 between everything, from the gap alone (CA-1.8). */
.sol-certified__refrain-inner .sol-certified__lead { max-width: 52ch; }

/* ============================================================
   5. The evidence diagram

   INTENTIONALLY WORDLESS. The installer should sense that early requirements
   are easy and hard ones belong to higher tiers, without a list that reads
   like a chore. An earlier itemised version was rejected — do not reintroduce
   a list of documents here.

   Each column carries its own --stack, --plinth and --fill, set in
   assessment.php, so the ascent is described once rather than in four
   near-copies of the same rule. The four columns stay four at EVERY width by
   design: the ascending shape is the content, so it shrinks rather than wraps.
   ============================================================ */

.sol-certified__evidence {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-100);
  overflow: hidden;
}

.sol-certified__evidence-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-400);
  padding: var(--space-400) var(--space-500);
  background: var(--color-accent-highlight);
}

.sol-certified__evidence-title,
.sol-certified__evidence-hint {
  font: var(--type-label-sm);
  letter-spacing: var(--type-label-sm-tracking);
  /* Ink on Princeton Orange is black, never white (CA-3.5). */
  color: var(--color-on-accent-highlight);
}

.sol-certified__evidence-title { text-transform: uppercase; }

.sol-certified__evidence-body { padding: var(--space-700) var(--space-500) var(--space-500); }

.sol-certified__evidence-cols {
  display: flex;
  align-items: flex-end;
  gap: var(--space-300);
}

.sol-certified__evidence-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-300);
}

.sol-certified__stack { position: relative; height: var(--stack); }

.sol-certified__sheet {
  position: absolute;
  inset: 0;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-sm);
}

/* Back sheets offset up AND left, so the rightmost column never overflows the
   card. */
.sol-certified__sheet--back {
  top: var(--offset);
  left: var(--offset);
}

.sol-certified__sheet--front {
  box-shadow: var(--elevation-100);
  padding: 0 var(--space-300);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-200);
}

.sol-certified__sheet-line {
  display: block;
  height: 4px;
  width: var(--w, 100%);
  border-radius: var(--radius-pill);
  background: var(--color-border-default);
}

/* The "title" line of each document. */
.sol-certified__sheet-line--title {
  width: 58%;
  background: var(--color-accent-highlight);
}

/* "And more", unspecified — which is the whole point, since the criteria are
   not written. A zero-height span showing only its dashed top border. */
.sol-certified__sheet-line--more {
  height: 0;
  width: 70%;
  background: none;
  border-top: 3px dashed var(--color-border-default);
  border-radius: 0;
}

.sol-certified__plinth-bar {
  height: var(--plinth);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  /* The ramp, mixed from the one highlight token rather than four literals:
     20% / 45% / 70% / 100% of Princeton Orange on white. */
  background: color-mix(in oklab, var(--color-accent-highlight) var(--fill), #fff);
}

.sol-certified__evidence-baseline {
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--color-accent-highlight);
}

.sol-certified__evidence-notes {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-500);
  margin-top: var(--space-400);
}

.sol-certified__evidence-note {
  font: var(--type-body-sm);
  color: var(--color-text-secondary);
  max-width: 20ch;
}

.sol-certified__evidence-note--end {
  color: var(--color-text-accent-ink);
  text-align: right;
}

.sol-certified__evidence-privacy {
  padding: var(--space-400) var(--space-500);
  background: var(--color-surface-sunken);
  border-top: 1px solid var(--color-border-default);
  font: var(--type-body-sm);
  color: var(--color-text-muted);
}

/* ============================================================
   6. For homeowners
   ============================================================ */

/* A white section with a sunken band inside it (CA-5.4), padded like every
   other section — no tall variant (CA-1.11) — so it pads 112 below its band
   too (CA-1.5). The band is what sets it apart from the installer argument
   either side. */
.sol-certified__homeowners {
  background: var(--color-surface-default);
  padding: var(--sec) 0;
}

/* On the grey band, so no hairline — the shadow alone (CA-6.8). */
.sol-certified__badge-card {
  background: var(--color-surface-raised);
  box-shadow: var(--elevation-100);
  border-radius: var(--radius-lg);
  padding: var(--space-700);
  display: flex;
  gap: var(--space-500);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

/* The badges are used WHOLE AND UNMODIFIED. They also appear on third-party
   installer and partner sites where none of this stylesheet exists, so they
   deliberately inherit no CSS — width only. Tier and ink are different files,
   never props or filters. Do not recolour, crop or restyle them. */
.sol-certified__badge-small { width: 53px; height: auto; }

/* ============================================================
   8. The dialog

   The same form as the hero, raised for the two lower CTAs. State is shared
   on purpose: one list, one submission.
   ============================================================ */

.sol-certified__dialog {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-600) var(--space-400);
  overflow-y: auto;
}

.sol-certified__scrim {
  position: fixed;
  inset: 0;
  /* The system scrim, navy at 62%, no blur (CA-5.8). */
  background: var(--color-scrim);
  animation: sol-certified-scrim-in var(--motion-duration-fast) var(--motion-ease);
}

.sol-certified__dialog-panel {
  position: relative;
  width: 100%;
  max-width: 560px;
  /* The standard modal shell (CA-10.10): a tall form scrolls inside the
     panel rather than off the bottom of the screen. */
  max-height: 88vh;
  overflow: auto;
  margin: auto;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-300);
  padding: var(--space-600);
  animation: sol-certified-dialog-in var(--motion-duration-base) var(--motion-ease);
}

.sol-certified__dialog-panel .sol-certified__form-title { padding-right: var(--space-600); }

/* A permanent offset disc, 44, inset 16, the × at item/lg (CA-10.10,
   CA-2.8) — the standard modal close. */
.sol-certified__dialog-close {
  position: absolute;
  top: var(--space-400);
  right: var(--space-400);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--target-min);
  height: var(--target-min);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-surface-offset);
  color: var(--color-text-primary);
  font: var(--type-item-lg);
  letter-spacing: var(--type-item-lg-tracking);
  cursor: pointer;
}

/* The page keeps scrolling behind an open dialog otherwise, and the scrim is
   fixed, so the content moves under a static overlay. The root is named as
   well as the body: the site gives <html> its own overflow-x, and then the
   body's overflow no longer reaches the viewport, which is the scroller. */
body.sol-certified-dialog-open,
html:has(> body.sol-certified-dialog-open) { overflow: hidden; }

/* The only two animations on the page, plus the site header's own. No scroll
   reveals, no parallax. */
@keyframes sol-certified-scrim-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes sol-certified-dialog-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   Responsive

   THE DESIGN SHIPS NO MOBILE LAYOUT. Three of the bands below are the
   design's own, named in the handoff and load-bearing. The rest are this
   build's, and each says what it is answering — because a page whose whole
   job is a form is a page most people will meet on a phone.

   Floor is --viewport-min, 360px.
   ============================================================ */

/* ---- The design's own bands ---- */

/* The hero row's stack threshold: a 420px basis twice, a 64px gap and two
   32px gutters. Below it the offset panel becomes a grey box around the hero copy
   rather than asking a half-column device to work at full width, and
   the plinth stops reaching for a centre line that no longer exists. */
@media (max-width: 967.98px) {
  .sol-certified__offset { display: none; }
  .sol-certified__plinth { margin-right: 0; }

  /* The hero stays white and the offset panel becomes a grey box around the
     hero copy (CA-5.3), not the hero's ground. */
  .sol-certified__hero-copy {
    background: var(--color-surface-offset);
    border-radius: var(--radius-lg);
    padding: var(--space-600);
  }
}

@media (max-width: 720px) {
  .sol-certified__hero-copy { padding: var(--space-500); }
}

/* Load-bearing. The tier ladder is an ORDERED sequence of four, so it must
   never orphan 3+1 — a lone Platinum on its own row, right across the
   iPad-portrait band. auto-fit cannot express "never 3 columns". */
@media (min-width: 480px) and (max-width: 995px) {
  .sol-certified__quad,
  [data-sol="quad"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Phone width: the plinth gives up its horizontal lockup. */
@media (max-width: 720px) {
  .sol-certified__plinth {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ---- This build's ---- */

/* A 32px gutter each side of a 360px screen spends 18% of it on margin. The
   next step down is the one the card padding already uses. */
@media (max-width: 480px) {
  .sol-certified { --layout-gutter: var(--space-500); }

  /* "I'm a homeowner" needs 112px on one line and the pill only has about 117
     left at 360px. The pill's WIDTH comes from the rail (it is flex: 1), so its
     horizontal padding does nothing but squeeze the label — dropping it to the
     smallest step buys the line back and changes nothing visible. The 44px
     target floor is vertical and is untouched. */
  .sol-certified__tab { padding-inline: var(--space-100); }
}

/* The evidence diagram keeps its four columns at every width — the ascending
   shape IS the content. Only the gap and the card's inner padding give way,
   so the sheets keep enough room to read as sheets. */
@media (max-width: 480px) {
  .sol-certified__evidence-cols { gap: var(--space-200); }
  .sol-certified__evidence-body { padding: var(--space-600) var(--space-400) var(--space-400); }
  .sol-certified__evidence-head,
  .sol-certified__evidence-privacy { padding: var(--space-400); }
  .sol-certified__sheet--front { padding: 0 var(--space-200); }
  .sol-certified__evidence-notes { gap: var(--space-400); }
}

/* The dialog is a card on a desktop and a sheet on a phone: at 360px, 16px of
   scrim either side is 9% of the screen spent on showing that there is a
   page behind it. */
@media (max-width: 480px) {
  .sol-certified__dialog { padding: var(--space-400) var(--space-300); }
}

/* Motion is restrained and rule-bound, and all of it comes off here. */
@media (prefers-reduced-motion: reduce) {
  .sol-certified *,
  .sol-certified *::before,
  .sol-certified *::after {
    transition: none !important;
    animation: none !important;
  }
}
