/* Alder Heating & Air demo — the page's own styles.
 *
 * Ported from the design export "Alder Heating and Air - offline.html". The
 * canvas writes every declaration as an inline style attribute, which is how
 * the canvas works and not how a page should ship, so they are lifted into
 * classes here. Every VALUE is the export's: the clamps, the easings, the odd
 * 14.5px and 17.5px sizes, the 4/4.4 about ratio, the 1.05fr/0.95fr hero
 * split. If a number here disagrees with the canvas, this file is wrong.
 *
 * Three deliberate departures, each noted where it appears:
 *
 *  - the export branches its layout on window.innerWidth at 760, 900, 1180
 *    and 1220; those are media queries here. A media query measures the
 *    viewport WITHOUT the classic scrollbar and innerWidth measures it with,
 *    so the two disagree by up to ~15px right at a breakpoint. Nothing in
 *    this layout is knife-edge at those widths, and the alternative is a
 *    resize listener re-rendering the page.
 *  - the four views are real sections toggled with [hidden] rather than
 *    re-rendered subtrees.
 *  - the site footer sits outside <main> and carries main's frame itself.
 *
 * Nocturne's own tokens and component classes (.btn, .tag, .lighten, the
 * palette) come from nocturne.css and are not restated.
 *
 * On the eyebrow sizes: the export uses 12px for section and page labels,
 * 11.5px for labels inside a panel, and 11px in the footer. They are three
 * classes on purpose. One .eyebrow carrying whichever size was measured
 * first is how the sibling demo rendered every eyebrow as body text.
 */

/* ---------------------------------------------------------------- base ---
   The page ground, off the export's root wrapper div. */
body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(1100px 700px at 88% -180px, color-mix(in srgb, var(--color-accent-900) 74%, transparent), transparent 60%),
    radial-gradient(900px 700px at -6% 100%, color-mix(in srgb, black 30%, transparent), transparent 55%),
    var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  text-wrap: pretty;
  -webkit-font-smoothing: antialiased;
  transition: background 0.45s ease;
}
/* mix-blend-mode: lighten over a dark ground lifts the photograph; over a
   light one it washes it to nothing. Daylight turns it off. */
body[data-theme="day"] .lighten { mix-blend-mode: normal; }
a { color: var(--color-accent-300); text-decoration: none; }
a:hover { color: var(--color-accent-200); }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* height:auto matters: the width/height ATTRIBUTES map to a presentational
   height hint that beats a bare aspect-ratio, which on the sibling demo
   cropped the subject out of its own photograph. The slots that do want a
   fixed height say so again below. */
img { max-width: 100%; height: auto; display: block; }
/* [hidden] is a UA declaration; .about below sets display:grid, which is an
   author one and wins. Without this the About view renders under Home. */
[hidden] { display: none !important; }

@keyframes al-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes al-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes al-wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes al-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.3; transform: scale(0.7); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--color-surface); color: var(--color-text);
  padding: 10px 16px; border-radius: var(--radius-md);
}
.skip:focus { left: 8px; top: 8px; }

.noscript {
  margin: 0; padding: 18px clamp(18px, 5vw, 56px);
  background: var(--color-surface); border-bottom: 1px solid var(--color-divider);
  font-size: 15px; line-height: 1.6;
}
.noscript p { margin: 0 0 8px; max-width: 62ch; }
.noscript p:last-child { margin: 0; color: var(--color-neutral-400); }

/* The export's mainStyle, shared with the footer that used to live inside it. */
.wrap {
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: clamp(18px, 5vw, 56px);
}
/* .wrap moved off <main> and onto the views, so the banner and the ribbon
   can run edge to edge. These two carry what main.wrap used to. */
.page { padding-top: clamp(24px, 3.4vw, 48px); }
.home__rest { padding-top: clamp(26px, 3.4vw, 44px); }
.fade { animation: al-fade 0.4s ease both; }

/* ---------------------------------------------------------------- rail ---
   A real site header, not a dashboard rail: sticky, blurred, one row. */
.rail {
  position: sticky; top: 0; z-index: 30;
  display: grid; align-items: center;
  gap: 12px clamp(16px, 2.6vw, 40px);
  grid-template-columns: minmax(0, 1fr);
  padding: 14px clamp(18px, 5vw, 56px);
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-divider);
}
.brand {
  display: flex; flex-direction: column; gap: 3px;
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  /* The UA font shorthand on a form control sets family AND line-height, and
     neither inherits from body. The export wraps the brand in a <div>, so
     without this the tagline renders in Arial. */
  font-family: var(--font-body);
}
.brand__name {
  font-family: var(--font-heading); font-weight: 500; font-size: 21px;
  letter-spacing: -0.015em; color: var(--color-text);
}
.brand__tag { font-size: 11.5px; line-height: 1.6; letter-spacing: 0.05em; color: var(--color-neutral-400); }

.rail__nav {
  display: flex; gap: clamp(14px, 2vw, 28px); flex-wrap: wrap; align-items: center;
  justify-self: start;
}
.navlink {
  background: none; border: 0; cursor: pointer;
  font-family: var(--font-body); font-size: 15px; letter-spacing: 0.01em;
  text-align: left; padding: 5px 0;
  border-bottom: 1px solid transparent;
  color: var(--color-neutral-300);
  transition: color 0.25s ease, border-color 0.25s ease;
}
.navlink[aria-current="page"] { border-bottom-color: var(--color-accent); color: var(--color-text); }

.rail__toggles { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; justify-self: start; }
.pillgroup {
  display: flex; padding: 2px; gap: 2px;
  border: 1px solid var(--color-neutral-800); border-radius: 999px;
}
.pilltab {
  background: transparent; color: var(--color-neutral-400);
  border: 0; border-radius: 999px; padding: 5px 12px;
  font-size: 12px; font-family: var(--font-body); cursor: pointer;
  transition: background 0.3s ease, color 0.3s ease;
}
/* The icon buttons are square-ish rather than word-width. grid + place-items
   centres the 15px glyph without the line-box padding a text label needed. */
.pilltab--icon { display: grid; place-items: center; padding: 6px 11px; }
.pilltab[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-accent-800) 80%, transparent);
  color: var(--color-accent-200);
}

.rail__foot { display: none; justify-self: end; align-items: center; gap: 14px; }
.rail__live {
  font-size: 11.5px; line-height: 1.5; color: var(--color-neutral-500);
  display: flex; align-items: center; gap: 8px; text-align: right;
}
.rail__dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--color-accent); display: inline-block;
  animation: al-pulse 2.6s ease-in-out infinite;
}
.rail__call { text-decoration: none; padding: 11px 20px; white-space: nowrap; }

/* ------------------------------------------------------------ typography */
.h1 {
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(32px, 3.8vw, 54px); line-height: 1.05; letter-spacing: -0.024em;
  margin: 0 0 18px; margin-left: -0.05em;
}
.rise { animation: al-rise 0.8s 0.05s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
.rise-1 { animation-delay: 0.15s; }
.rise-2 { animation-delay: 0.25s; }

.h1--page {
  font-size: clamp(30px, 3.8vw, 50px); line-height: 1.06; letter-spacing: -0.022em;
  margin: 12px 0 20px; margin-left: -0.05em;
}
/* Each page's heading has its own measure and trailing space in the export. */
[data-view="services"] .h1--page { font-size: clamp(30px, 4vw, 52px); margin-bottom: 18px; max-width: 16ch; }
[data-view="about"] .h1--page { max-width: 15ch; }
[data-view="faq"] .h1--page { margin-bottom: 26px; max-width: 17ch; }

.h2 { font-family: var(--font-heading); font-weight: 500; letter-spacing: -0.015em; margin: 0; }
.h2--bar { font-size: clamp(21px, 2.2vw, 28px); }
.h2--sec { font-size: clamp(22px, 2.4vw, 30px); }
.h2--mid {
  font-size: clamp(24px, 2.6vw, 34px); line-height: 1.16; letter-spacing: -0.018em;
  margin: 12px 0 14px; max-width: 18ch;
}

/* No display:block. Where the export uses a standalone <span> the line box
   is sized by its parent's 16px strut, not by the 12px label -- 25.6px, not
   19.2px. Blockifying it lost 6px under four headings and left every page
   6px shorter than the canvas. Inside .sec__bar and .compare__head these are
   flex/grid items and get blockified anyway, exactly as in the export. */
.eyebrow {
  font-size: 12px; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--color-neutral-500);
  margin: 0;
}
.eyebrow--accent { color: var(--color-accent); }
.eyebrow--sm { font-size: 11.5px; }

.kicker { display: flex; align-items: center; gap: 12px; margin: 0 0 18px; }
.kicker .rule { width: 44px; height: 1px; background: var(--color-accent); display: block; flex: none; }
.kicker > span:not(.rule) {
  font-size: 12px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-accent);
}

.lede {
  font-size: clamp(15.5px, 1.2vw, 17.5px); line-height: 1.65; max-width: 44ch;
  margin: 0 0 26px; color: var(--color-neutral-200);
}
.lede--page {
  font-size: 16.5px; line-height: 1.7; max-width: 58ch;
  margin: 0 0 clamp(22px, 3vw, 38px);
}
.body { font-size: 15.5px; line-height: 1.7; color: var(--color-neutral-300); margin: 0; max-width: 46ch; }
.fine { font-size: 13.5px; color: var(--color-neutral-400); }
.fine--dim { margin: 0; }
.tnum { font-feature-settings: 'tnum' 1; }

.actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.actions .btn { text-decoration: none; }
.btn-lg { font-size: 16px; padding: 14px 26px; }
.actions--after { margin-top: clamp(22px, 3vw, 36px); gap: 12px; }
.actions--after .btn-primary { padding: 13px 24px; }
.actions--after .fine { font-size: 14px; }

/* -------------------------------------------------------------- banner ---
   The export had a boxed two-column hero inside the measure. This is the one
   wholesale departure from it: a full-bleed photograph with the copy over it.
   Everything below the banner is still the export's.

   The type over the photograph is light in BOTH themes, so these colours are
   literal rather than var()s -- a token that flips with the theme would put
   dark text on a dark picture every time someone hit Day. --banner-ink is the
   scrim's colour and is the only thing here that needs to stay in step with
   the photograph. */
.banner {
  --banner-ink: 14, 16, 24;
  position: relative; isolation: isolate;
  display: grid; align-items: end;
  min-height: clamp(460px, 74vh, 620px);
  animation: al-fade 0.7s ease both;
}
.banner__media { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.banner__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%;
  filter: saturate(0.94) contrast(1.03);
}
/* Two gradients, not one. The vertical pass darkens the strip the sticky rail
   sits over and the strip the copy sits on; the horizontal pass keeps the
   left column dark enough for body text while leaving the right-hand third of
   the photograph -- the ductwork and the two techs -- actually visible. */
.banner__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(var(--banner-ink), 0.74) 0%,
      rgba(var(--banner-ink), 0.30) 26%,
      rgba(var(--banner-ink), 0.34) 58%,
      rgba(var(--banner-ink), 0.82) 100%),
    linear-gradient(90deg,
      rgba(var(--banner-ink), 0.82) 0%,
      rgba(var(--banner-ink), 0.60) 42%,
      rgba(var(--banner-ink), 0.12) 100%);
}
.banner__inner {
  width: 100%;
  padding-block: clamp(30px, 5vw, 60px);
  display: grid; gap: clamp(20px, 3vw, 40px);
  grid-template-columns: minmax(0, 1fr);
  align-items: end;
}
.banner__copy { max-width: 62ch; }
.banner__h { color: #fff; }
.banner__lede { color: rgba(255, 255, 255, 0.88); }
.banner__actions { margin-top: clamp(20px, 2.6vw, 30px); }
/* A solid pill, and deliberately NOT the accent. .btn-primary is an outlined
   accent button, which is right on a surface and wrong on a photograph: over
   the scrim the day accent #6f61bf measures 3.21:1, under AA. Filling it with
   the accent does not fix it either -- light text on the night accent is
   3.31:1. A white pill with ink text is 17.8:1 in both themes and does not
   move when the palette does. */
.banner__actions .btn-primary {
  background: #fff; color: #14101c; border-color: #fff;
}
.banner__actions .btn-primary:hover { background: rgba(255, 255, 255, 0.88); border-color: rgba(255, 255, 255, 0.88); }
.kicker--on > span:not(.rule) { color: rgba(255, 255, 255, 0.82); }
.fine--on { color: rgba(255, 255, 255, 0.78); }

/* The owner card. Narrow: a chip under the buttons, so the face survives on a
   phone instead of being hidden. Wide: its own column beside the copy. */
.ownercard {
  margin: 0; display: flex; align-items: center; gap: 14px;
  padding: 10px; border-radius: var(--radius-md);
  background: rgba(var(--banner-ink), 0.58);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(8px);
  justify-self: start;
}
.ownercard img {
  width: 64px; height: 80px; object-fit: cover; flex: none;
  border-radius: calc(var(--radius-md) - 4px); display: block;
}
.ownercard__cap { display: flex; flex-direction: column; gap: 3px; padding-right: 8px; }
.ownercard__name { font-family: var(--font-heading); font-weight: 500; font-size: 16px; color: #fff; }
.ownercard__role { font-size: 12.5px; line-height: 1.45; color: rgba(255, 255, 255, 0.74); }

/* -------------------------------------------------------------- ribbon --- */
.ribbon {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-divider);
}
.ribbon__inner {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px clamp(16px, 3vw, 44px);
  padding-block: 16px;
}
.ribbon__i { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* --color-neutral-300, not -400. The 2026-09-21 contrast pass measured -400
   at 4.18:1 on this palette's daylight ground, i.e. under AA for small text;
   adding a fresh instance of a known-failing token is not something to do on
   the way past. */
.ribbon__k {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-neutral-300);
}
.ribbon__v { font-size: 14px; color: var(--color-text); }

/* -------------------------------------------------------------- sections */
.sec { margin-top: clamp(34px, 5vw, 64px); }
.sec--triage { margin-top: clamp(20px, 3vw, 34px); }
/* Every section head sits under a hairline with an accent tick on it. The
   export separated sections with space alone, which read as one long column
   once the boxed hero stopped closing the top of the page. */
.sec__bar {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 10px 18px;
  align-items: baseline; justify-content: space-between;
  padding-top: 18px;
  border-top: 1px solid var(--color-divider);
  margin-bottom: 18px;
}
.sec__bar::before {
  content: ""; position: absolute; top: -1px; left: 0;
  width: 56px; height: 2px; background: var(--color-accent);
}
.sec--triage .sec__bar { margin-bottom: 16px; }
.sec__bar .btn-ghost { cursor: pointer; }

/* -------------------------------------------------------------- triage --- */
.pills { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.pill {
  cursor: pointer; font-family: var(--font-body); font-size: 14px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--color-neutral-800);
  background: transparent; color: var(--color-neutral-300);
  transition: all 0.3s ease;
}
.pill[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent-900) 70%, transparent);
  color: var(--color-text);
}
.triage {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: clamp(16px, 2.5vw, 32px);
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-surface) 66%, transparent);
  box-shadow: var(--shadow-sm);
}
.triage .eyebrow--accent { margin-bottom: 8px; }
.triage__cause {
  margin: 0 0 14px;
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(19px, 2vw, 24px); line-height: 1.3; letter-spacing: -0.012em;
}
.triage__detail { margin: 0; font-size: 15px; line-height: 1.7; color: var(--color-neutral-300); max-width: 52ch; }
.triage__side { display: grid; gap: 14px; align-content: start; }
.triage__side .eyebrow { margin-bottom: 4px; }
.triage__v { margin: 0; font-size: 15px; color: var(--color-text); }
.triage__cta { text-decoration: none; text-align: center; }

/* ------------------------------------------------------------- compare --- */
.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(20px, 3vw, 56px); align-items: start; }
.compare { display: grid; gap: 0; }
.compare__head {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 6px clamp(16px, 3vw, 40px);
  padding-bottom: 12px; border-bottom: 1px solid var(--color-neutral-800);
}
.compare__row {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 4px clamp(16px, 3vw, 40px);
  padding: 14px 0; border-bottom: 1px solid var(--color-divider);
  font-size: 15px; line-height: 1.55;
}
.compare__a { color: var(--color-text); }
.compare__b { color: var(--color-neutral-400); }

/* ------------------------------------------------------------ services --- */
.svcgrid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 1px; background: var(--color-divider);
  border-radius: var(--radius-md); overflow: hidden;
}
.svc {
  background: var(--color-bg); padding: 20px;
  display: grid; gap: 6px;
  transition: background 0.3s ease;
}
.svc:hover { background: color-mix(in srgb, var(--color-accent-900) 40%, transparent); }
.svc__title { margin: 0; font-family: var(--font-heading); font-weight: 500; font-size: 17.5px; letter-spacing: -0.01em; }
.svc__body { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--color-neutral-300); }
.svc__meta { margin: 4px 0 0; font-size: 12px; letter-spacing: 0.04em; color: var(--color-accent); }

/* the services page's own rows */
.svcrows { display: grid; gap: 0; }
.svcrow {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 6px clamp(18px, 3vw, 48px);
  padding: 20px 0; border-top: 1px solid var(--color-neutral-800);
  align-items: baseline;
}
.svcrow__title { margin: 0; font-family: var(--font-heading); font-weight: 500; font-size: 19px; letter-spacing: -0.012em; }
.svcrow__body { margin: 0; font-size: 15px; line-height: 1.65; color: var(--color-neutral-300); max-width: 58ch; }
.svcrow__meta { margin: 0; font-size: 12.5px; color: var(--color-accent); letter-spacing: 0.03em; }

/* --------------------------------------------------------------- price --- */
.prices { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(14px, 2vw, 22px); }
.price {
  padding: clamp(20px, 3vw, 30px); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-surface) 66%, transparent);
  box-shadow: var(--shadow-sm);
}
.price--lit {
  background:
    radial-gradient(600px 260px at 85% -30%, color-mix(in srgb, var(--color-section-glow) 72%, transparent), transparent 64%),
    var(--color-section);
  box-shadow: var(--shadow-md);
}
.price .eyebrow { margin-bottom: 10px; }
.eyebrow--lit { color: color-mix(in srgb, var(--color-neutral-100) 72%, transparent); }
.price__fig {
  margin: 0; font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(34px, 3.6vw, 46px); line-height: 1; letter-spacing: -0.025em;
}
.price__fig--lit { color: var(--color-neutral-100); }
.price__per { font-size: 16px; letter-spacing: 0; }
.price__note { margin: 12px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--color-neutral-300); }
.price__note--lit { color: color-mix(in srgb, var(--color-neutral-100) 88%, transparent); }

/* ---------------------------------------------------------------- work --- */
.work { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(14px, 2vw, 24px); align-items: start; }
.work__main { margin: 0; }
.work__frame { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
.work__frame img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.work__cap { font-size: 13px; color: var(--color-neutral-400); padding: 10px 2px 0; }
.thumbs { display: grid; gap: clamp(12px, 1.6vw, 18px); }
.thumb {
  margin: 0; display: grid; grid-template-columns: 96px minmax(0, 1fr);
  gap: 14px; align-items: center;
  transition: transform 0.35s ease;
}
.thumb:hover { transform: translateX(4px); }
.thumb__frame { border-radius: var(--radius-md); overflow: hidden; }
.thumb__frame img { width: 96px; height: 72px; object-fit: cover; }
.thumb__cap { font-size: 13.5px; line-height: 1.5; color: var(--color-neutral-300); }

/* ----------------------------------------------------- review + coverage */
.review {
  margin: 0; padding: clamp(20px, 3vw, 32px); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-surface) 62%, transparent);
  box-shadow: var(--shadow-sm);
}
.review__quote {
  margin: 0 0 16px; font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(19px, 2.1vw, 26px); line-height: 1.45; letter-spacing: -0.012em;
}
.review__who { font-size: 13px; color: var(--color-neutral-400); }
.stars { color: var(--color-accent); letter-spacing: 0.08em; }
.areas { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.coverage .eyebrow--sm { margin-bottom: 6px; }
.hours { margin: 0 0 4px; font-size: 15px; color: var(--color-text); }

/* ------------------------------------------------------------ keepring --- */
.keepring {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  padding: clamp(24px, 3.5vw, 44px);
  background:
    radial-gradient(700px 300px at 92% 0%, color-mix(in srgb, var(--color-accent-900) 85%, transparent), transparent 62%),
    var(--color-surface);
}
.keepring__wipe {
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(to right, transparent, var(--color-accent), transparent);
  animation: al-wipe 1.2s ease-out both;
}
.keepring__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(20px, 3vw, 48px); align-items: center; }
.keepring__h {
  font-size: clamp(21px, 2.4vw, 30px); line-height: 1.22;
  margin: 12px 0 12px; max-width: 22ch;
}
.keepring__steps { display: grid; gap: 10px; }
.krstep {
  display: grid; grid-template-columns: 24px 1fr; gap: 12px; align-items: start;
  padding: 12px 14px; border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--color-bg) 55%, transparent);
}
.krstep__n { font-family: var(--font-heading); font-size: 13px; color: var(--color-accent); font-feature-settings: 'tnum' 1; }
.krstep__t { font-size: 14.5px; line-height: 1.55; color: var(--color-neutral-200); }

/* --------------------------------------------------------------- about --- */
.about { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 3.5vw, 64px); align-items: start; }
.about .body { font-size: 16px; line-height: 1.75; max-width: 56ch; margin: 0 0 16px; }
/* after .about .body: same specificity, so the first paragraph's 16.5px only
   survives if it is declared later. */
.about .body--lead { font-size: 16.5px; color: var(--color-neutral-200); }
.about .body--last { margin-bottom: 24px; }
.creds { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 16px; }
.cred__k { margin: 0; font-size: 11px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-neutral-500); }
.cred__v { margin: 5px 0 0; font-size: 15px; color: var(--color-text); }
.about__photo { margin: 0; border-radius: var(--radius-lg); overflow: hidden; }
.about__photo img { width: 100%; aspect-ratio: 4 / 4.4; object-fit: cover; }

/* ----------------------------------------------------------------- faq --- */
/* The cap is on the children, not the view. .faq used to be a 980px block
   sitting at the left of the 1280px measure <main> supplied; now that the view
   carries .wrap itself, a max-width here would meet .wrap's margin-inline:auto
   and centre the whole column instead of leaving it where it was. */
.faq > * { max-width: 980px; }
.faq__list { display: grid; gap: 0; }
.faq__item { border-top: 1px solid var(--color-neutral-800); }
.faq__h { margin: 0; font-size: inherit; font-weight: inherit; }
.faq__q {
  display: flex; width: 100%; gap: 16px;
  align-items: baseline; justify-content: space-between; text-align: left;
  background: none; border: 0; padding: 18px 0; cursor: pointer;
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(16.5px, 1.7vw, 19px); letter-spacing: -0.01em;
  color: var(--color-text);
  transition: color 0.25s ease;
}
.faq__q[aria-expanded="true"] { color: var(--color-accent-200); }
.faq__icon {
  font-size: 20px; color: var(--color-accent); line-height: 1;
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.faq__q[aria-expanded="true"] .faq__icon { transform: rotate(45deg); }
.faq__a {
  display: grid; grid-template-rows: 0fr; opacity: 0; overflow: hidden;
  transition: grid-template-rows 0.4s cubic-bezier(0.2, 0.7, 0.3, 1), opacity 0.3s ease;
}
.faq__a[data-open] { grid-template-rows: 1fr; opacity: 1; }
.faq__a > div { min-height: 0; overflow: hidden; }
.faq__a p {
  margin: 0; padding: 0 0 20px;
  font-size: 15.5px; line-height: 1.7; color: var(--color-neutral-300); max-width: 68ch;
}
.faq .actions--after { margin-top: 28px; }

/* -------------------------------------------------------------- footer --- */
.sitefoot {
  margin-top: clamp(36px, 5vw, 72px);
  padding-top: clamp(20px, 3vw, 32px);
  padding-bottom: 96px;
  border-top: 1px solid var(--color-divider);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 22px 36px;
  font-size: 13.5px; color: var(--color-neutral-400);
}
.sitefoot p { margin: 0; line-height: 1.65; }
.sitefoot__name { margin: 0 0 6px !important; font-family: var(--font-heading); font-size: 15.5px; color: var(--color-text); }
.sitefoot__k {
  margin: 0 0 6px !important;
  font-size: 11px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-neutral-500);
}
.sitefoot__links { display: grid; gap: 5px; justify-items: start; }
.footlink {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--font-body); font-size: 13.5px; color: var(--color-neutral-300);
}
.footlink:hover { color: var(--color-accent-200); }

/* ----------------------------------------------------------- mobile bar --- */
.mobilebar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--color-divider);
}
.mobilebar .btn { text-decoration: none; padding: 14px; font-size: 16px; margin-top: 0; }

/* ==========================================================================
   The export's `wide` branch: window.innerWidth >= 760.
   ========================================================================== */
@media (min-width: 760px) {
  .rail { grid-template-columns: minmax(0, 1fr) auto; }
  .rail__nav { justify-self: end; }
  .rail__foot { display: flex; }
  .mobilebar { display: none; }
  .sitefoot { padding-bottom: 72px; }

  .banner__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 260px); }
  .ownercard {
    display: block; padding: 12px;
    justify-self: end; width: 100%; max-width: 260px;
  }
  .ownercard img { width: 100%; height: auto; aspect-ratio: 4 / 5; }
  .ownercard__cap { padding: 12px 4px 4px; gap: 4px; }
  .ribbon__inner { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  .triage { grid-template-columns: minmax(0, 1.6fr) minmax(0, 220px); }
  .split, .keepring__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .about { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
  .compare__head, .compare__row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .svcgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .svcrow { grid-template-columns: minmax(0, 240px) minmax(0, 1fr) minmax(0, 150px); }
  .work { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
}

@media (min-width: 900px) {
  .prices { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1180px) {
  .svcgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The four-column rail: brand, nav, toggles, phone. */
@media (min-width: 1220px) {
  .rail { grid-template-columns: auto minmax(0, 1fr) auto auto; }
  .rail__nav { justify-self: start; }
}

/* Visually hidden, still announced. The mode buttons carry no text on screen
   and an icon-only button without an accessible name is read out as, simply,
   "button". aria-hidden on the SVG keeps the graphic out of the name so what
   is announced is the span and nothing else. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.modeicon { width: 15px; height: 15px; display: block; }
