/* Smart Home Life: site.css
   Components only. Every value comes from tokens.css (DESIGN_BRIEF.md is the source of truth).
   Classes are prefixed .shl-. Hover lives only inside @media (hover: hover) and (pointer: fine). */

/* ---------------------------------------------------------------- Base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--ground);
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  -webkit-font-smoothing: antialiased;
}

main { overflow-x: clip; }

::selection { background: var(--selection); color: var(--ink); }

a, button, summary { -webkit-tap-highlight-color: transparent; }
button, summary { touch-action: manipulation; }

img, svg { display: block; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
/* Headings take focus only as a deep-link landing spot (G7); they are not controls, so no ring. */
:is(h2, h3)[tabindex="-1"]:focus { outline: none; }

.shl-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The one documented exception (10c): stops per-element color transitions lagging the theme crossfade. */
.shl-theme-switching *, .shl-theme-switching *::before, .shl-theme-switching *::after { transition: none !important; }
html.preload:root *, html.preload:root *::before, html.preload:root *::after { transition: none; animation: none; }

/* The standard reduced-motion reset (10c). Transitions are handled per component. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* Theme-paired images: the cream logo files on dark, the ink files on light. */
:root[data-theme="light"] .shl-on-dark { display: none; }
:root:not([data-theme="light"]) .shl-on-light { display: none; }

/* ---------------------------------------------------------------- C1 Skip link */
.shl-skip {
  position: fixed;
  top: 8px;
  left: max(var(--gutter), env(safe-area-inset-left));
  z-index: var(--z-skip);
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  padding: 0 var(--s-5);
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-small);
  font-weight: var(--fw-strong);
  text-decoration: none;
  transform: translateY(-200%);
}
.shl-skip:focus-visible { transform: none; }

/* ---------------------------------------------------------------- C2 Header pill (section 6) */
.shl-nav-wrap {
  position: fixed;
  top: var(--nav-top-safe);
  left: 0;
  right: 0;
  z-index: var(--z-nav);
  padding-inline: max(var(--gutter), env(safe-area-inset-left)) max(var(--gutter), env(safe-area-inset-right));
  pointer-events: none;
  container: shl-nav / inline-size;
}

.shl-nav {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--s-1);
  width: fit-content;
  max-width: var(--wrap);
  height: var(--nav-h);
  margin-inline: auto;
  padding-inline: var(--s-2) 6px;
  border: 1px solid var(--hair);
  border-top-color: var(--edge-hi);
  border-radius: var(--r-pill);
  background: var(--pill-fill);
  -webkit-backdrop-filter: var(--pill-blur);
  backdrop-filter: var(--pill-blur);
  view-transition-name: shl-nav;
  transition: border-color var(--dur-chrome) var(--ease-color), box-shadow var(--dur-chrome) var(--ease-color);
}

html.is-scrolled .shl-nav {
  border-color: var(--hair-strong);
  border-top-color: var(--edge-hi);
  box-shadow: 0 10px 30px -14px var(--shadow);
}

/* Brand */
.shl-brand {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  margin-inline-end: var(--s-3);
  padding-inline: var(--s-2);
  border-radius: var(--r-pill);
}
.shl-brand-lockup { height: 28px; width: auto; }
.shl-brand-mark { display: none; height: 32px; width: auto; }

/* Primary links */
.shl-nav-links {
  display: flex;
  gap: var(--s-1);
  margin: 0 var(--s-2) 0 0;
  padding: 0;
  list-style: none;
}
.shl-nav-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  padding: 0 var(--s-3);
  border-radius: var(--r-pill);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  text-decoration: none;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
  white-space: nowrap;
  transition: color var(--dur-hover) var(--ease-color);
}
.shl-nav-links a:active { color: var(--ink); }
.shl-nav-links a[aria-current="page"] {
  color: var(--ink);
  font-weight: var(--fw-strong);
}
.shl-nav-links a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 6px;
  width: 16px;
  height: 2px;
  margin-left: -8px;
  background: var(--ink);
}

/* Icon buttons: theme toggle, Instagram, menu */
.shl-icon-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--target);
  height: var(--target);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease-color), background-color var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-icon-btn:active { transform: scale(0.95); }
.shl-icon-btn svg { width: 20px; height: 20px; grid-area: 1 / 1; }
.shl-ig svg { width: 22px; height: 22px; }

/* Theme toggle: the sun offers light (shown in dark), the moon offers dark (shown in light). The incoming
   glyph turns in with an animation, only while the theme switches (never on load): the theme-switch rule
   (10c) stops transitions, not animations. */
.shl-theme .shl-moon { opacity: 0; }
:root[data-theme="light"] .shl-theme .shl-sun { opacity: 0; }
:root[data-theme="light"] .shl-theme .shl-moon { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  html.shl-theme-switching[data-theme="light"] .shl-theme .shl-moon,
  html.shl-theme-switching:not([data-theme="light"]) .shl-theme .shl-sun { animation: shl-glyph-in var(--dur-chrome) var(--ease-in-out); }
}
@keyframes shl-glyph-in {
  from { opacity: 0; transform: rotate(-45deg) scale(0.8); }
  to { opacity: 1; transform: none; }
}

/* Menu button: bars swap to an X. Mobile only. */
.shl-menu-btn { display: none; }
.shl-menu-btn svg { transition: opacity var(--dur-hover) var(--ease-out), transform var(--dur-hover) var(--ease-out), filter var(--dur-hover) var(--ease-out); }
.shl-menu-btn .shl-x { opacity: 0; transform: scale(0.8); filter: blur(2px); }
.shl-menu-btn[aria-expanded="true"] { background: var(--raised); color: var(--ink); }
.shl-menu-btn[aria-expanded="true"] .shl-bars { opacity: 0; transform: scale(0.8); filter: blur(2px); }
.shl-menu-btn[aria-expanded="true"] .shl-x { opacity: 1; transform: none; filter: none; }

/* CTA end cap: the only red fill on the page. */
.shl-cta {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: var(--target);
  margin-inline-start: var(--s-1);
  padding: 0 18px;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-strong);
  text-decoration: none;
  white-space: nowrap;
  transition: box-shadow var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-cta:active { transform: scale(0.97); }
.shl-cta-long { display: none; }

/* Wide containers: the long CTA label. */
@container shl-nav (width >= 44rem) {
  .shl-cta-long { display: inline; }
  .shl-cta-short { display: none; }
}

/* Collapse: below the measured value the links and Instagram leave the pill and the menu button appears. */
@container shl-nav (width < 42.5rem) {
  .shl-nav { width: 100%; }
  .shl-nav-links, .shl-ig { display: none; }
  .shl-brand { margin-inline-end: auto; }
  .shl-menu-btn { display: inline-grid; }
}

/* Narrowest pills (measured: mark, theme, menu and "Get App" no longer fit, e.g. 200% text on a phone):
   the theme toggle moves from the pill into the menu as a labelled row. */
@container shl-nav (width < 17.5rem) {
  .shl-nav .shl-theme { display: none; }
  .shl-menu .shl-menu-theme-row { display: list-item; }
}

/* Very narrow containers: the house mark alone. */
@container shl-nav (width < 22rem) {
  .shl-brand-lockup { display: none; }
  .shl-brand-mark { display: block; }
  :root[data-theme="light"] .shl-brand-mark.shl-on-dark,
  :root:not([data-theme="light"]) .shl-brand-mark.shl-on-light { display: none; }
}

/* Menu panel: a solid floating card under the pill. A disclosure, not role="menu". */
.shl-menu {
  pointer-events: auto;
  position: absolute;
  top: calc(var(--nav-h) + 8px);
  left: max(var(--gutter), env(safe-area-inset-left));
  right: max(var(--gutter), env(safe-area-inset-right));
  z-index: var(--z-panel);
  max-width: var(--wrap);
  max-height: calc(100svh - 96px);
  margin-inline: auto;
  padding: var(--s-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--hair);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: 0 18px 40px -18px var(--shadow);
  transform-origin: top right;
  transition: opacity var(--dur-panel-in) var(--ease-out), transform var(--dur-panel-in) var(--ease-out), display var(--dur-panel-in) allow-discrete;
}
.shl-menu[hidden] {
  display: none;
  opacity: 0;
  transform: translateY(-4px) scale(0.99);
  transition-duration: var(--dur-panel-out);
}
@starting-style {
  .shl-menu:not([hidden]) { opacity: 0; transform: translateY(-6px) scale(0.98); }
}
.shl-menu ul { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.shl-menu li.shl-menu-sep {
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--hair);
}
.shl-menu-theme-row { display: none; }
.shl-menu a, .shl-menu-theme {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--target-row);
  padding: 0 var(--s-4);
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: var(--fs-body);
  font-weight: var(--fw-strong);
  text-decoration: none;
  transition: background-color var(--dur-hover) var(--ease-color);
}
.shl-menu-theme {
  width: 100%;
  margin: 0;
  border: 0;
  background: transparent;
  font-family: inherit;
  text-align: start;
  cursor: pointer;
}
.shl-menu a:focus-visible, .shl-menu-theme:focus-visible { outline-offset: -2px; }
.shl-menu a svg, .shl-menu-theme svg { width: 22px; height: 22px; color: var(--ink-2); }
.shl-menu a[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 50%;
  width: 2px;
  height: 16px;
  margin-top: -8px;
  background: var(--ink);
}
.shl-menu.shl-menu-instant, .shl-menu.shl-menu-instant[hidden] { transition: none; }

/* Hover, fine pointers only. */
@media (hover: hover) and (pointer: fine) {
  .shl-nav-links a:hover { color: var(--ink); text-decoration-line: underline; }
  .shl-nav-links a[aria-current="page"]:hover { text-decoration-line: none; }
  .shl-icon-btn:hover { color: var(--ink); background: var(--raised); }
  .shl-cta:hover { box-shadow: inset 0 0 0 1px var(--ink); }
  .shl-menu a:hover, .shl-menu-theme:hover { background: var(--raised); }
}

/* No JavaScript: the header sits in flow, the theme toggle and menu button go, and below the collapse
   value the menu renders as a static wrapping row of links. */
html:not(.js) .shl-nav-wrap { position: relative; }
html:not(.js) .shl-theme, html:not(.js) .shl-menu-btn { display: none; }
@container shl-nav (width < 42.5rem) {
  html:not(.js) .shl-menu[hidden] {
    position: static;
    display: block;
    opacity: 1;
    transform: none;
    margin-top: var(--s-2);
  }
  html:not(.js) .shl-menu ul { display: flex; flex-wrap: wrap; }
  html:not(.js) .shl-menu li.shl-menu-sep { margin: 0; padding: 0; border: 0; }
}

/* Reduced motion: no press scale, the menu fades only (100ms both ways), icons swap instantly. */
@media (prefers-reduced-motion: reduce) {
  .shl-icon-btn:active, .shl-cta:active { transform: none; }
  .shl-menu, .shl-menu[hidden] {
    transform: none;
    transition: opacity var(--dur-reduced) var(--ease-out), display var(--dur-reduced) allow-discrete;
  }
  @starting-style {
    .shl-menu:not([hidden]) { opacity: 0; transform: none; }
  }
  .shl-menu-btn svg { transition: opacity var(--dur-reduced) var(--ease-out); transform: none; filter: none; }
}

/* Forced colors: controls keep a visible edge; the current item is underlined, never color alone. */
@media (forced-colors: active) {
  .shl-cta, .shl-icon-btn { border: var(--forced-edge); }
  .shl-nav-links a[aria-current="page"], .shl-menu a[aria-current="page"] { text-decoration-line: underline; }
}
/* A light high-contrast scheme paints a light background whatever the site theme: show the ink logo. */
@media (forced-colors: active) and (prefers-color-scheme: light) {
  :root .shl-brand .shl-on-dark { display: none; }
  :root .shl-brand .shl-brand-lockup.shl-on-light { display: block; }
}
@container shl-nav (width < 22rem) {
  @media (forced-colors: active) and (prefers-color-scheme: light) {
    :root .shl-brand .shl-brand-lockup.shl-on-light { display: none; }
    :root .shl-brand .shl-brand-mark.shl-on-light { display: block; }
  }
}
/* A dark high-contrast scheme paints a dark background whatever the site theme: show the cream logo. */
@media (forced-colors: active) and (prefers-color-scheme: dark) {
  :root .shl-brand .shl-on-light { display: none; }
  :root .shl-brand .shl-brand-lockup.shl-on-dark { display: block; }
}
@container shl-nav (width < 22rem) {
  @media (forced-colors: active) and (prefers-color-scheme: dark) {
    :root .shl-brand .shl-brand-lockup.shl-on-dark { display: none; }
    :root .shl-brand .shl-brand-mark.shl-on-dark { display: block; }
  }
}

/* Cross-page navigation holds the pill still (10b); normal navigation under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-old(root) { animation-duration: 120ms; }
::view-transition-new(root) { animation-duration: var(--dur-page); }
::view-transition-group(*) { animation-duration: var(--dur-page); }
/* The theme switch is a same-page crossfade over --dur-theme. */
html.shl-theme-switching::view-transition-old(root),
html.shl-theme-switching::view-transition-new(root),
html.shl-theme-switching::view-transition-group(*),
html.shl-theme-switching::view-transition-old(*),
html.shl-theme-switching::view-transition-new(*) { animation-duration: var(--dur-theme); }

/* ---------------------------------------------------------------- C21 Footer (section 7) */
.shl-foot {
  border-top: 1px solid var(--hair);
  background: var(--ground);
}
.shl-foot-inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-top: var(--s-12);
  padding-bottom: calc(var(--s-16) + env(safe-area-inset-bottom));
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}
.shl-foot-grid {
  display: grid;
  gap: var(--s-10) var(--col-gap);
}
.shl-foot-brand {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--tr-h3);
  font-weight: var(--fw-h3);
  color: var(--ink);
  text-wrap: balance;
}
.shl-foot-maker {
  margin: var(--s-3) 0 var(--s-2);
  max-inline-size: var(--measure-tight);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}
.shl-foot-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-8) var(--col-gap);
}
.shl-foot-head {
  margin: 0 0 var(--s-2);
  color: var(--ink);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-strong);
}
.shl-foot-list { margin: 0; padding: 0; list-style: none; }
.shl-foot-legal { grid-column: 1 / -1; }
.shl-foot-legal .shl-foot-list { display: flex; flex-wrap: wrap; gap: 0 var(--s-6); }

.shl-foot a {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-width: var(--target);
  min-height: var(--target);
  margin: 0 -6px;
  padding: 0 6px;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  text-decoration: none;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  overflow-wrap: anywhere;
  hyphens: auto;
  transition: color var(--dur-hover) var(--ease-color);
}
.shl-foot a[aria-current="page"] { color: var(--ink); font-weight: var(--fw-strong); }
.shl-foot a svg { width: 22px; height: 22px; flex: none; }

/* Acknowledgements fold: a native <details>. Closed by default; printed open. */
.shl-ack {
  margin-top: var(--s-12);
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}
.shl-ack-sum {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: var(--target-row);
  padding-block: var(--s-2);
  list-style: none;
  cursor: pointer;
  color: var(--ink-2);
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--tr-h3);
  font-weight: var(--fw-h3);
  transition: color var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-ack-sum::-webkit-details-marker { display: none; }
.shl-ack-label { min-width: 0; overflow-wrap: anywhere; hyphens: auto; }
.shl-ack-sum:active { transform: scale(0.99); }
.shl-ack-sum svg {
  width: 20px;
  height: 20px;
  flex: none;
  transition: transform var(--dur-chrome) var(--ease-in-out);
}
.shl-ack[open] .shl-ack-sum svg { transform: rotate(180deg); }
/* The content fade on open runs from site.js (the toggle event fires on every open; CSS alone cannot restart it
   inside a closed fold in Chromium or WebKit). Closing is instant. */
.shl-ack-body { padding-bottom: var(--s-6); }
.shl-ack-body p {
  margin: 0;
  max-inline-size: var(--measure);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}
.shl-ack-body p + p { margin-top: var(--s-2); }

.shl-foot-copy {
  margin: var(--s-6) 0 0;
  color: var(--ink-3);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--tr-caption);
}

@media (min-width: 56.25em) {
  .shl-foot-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .shl-foot-brandblock { grid-column: 1 / span 5; }
  /* Legal gets the widest track: "Acknowledgements" is the longest label. */
  .shl-foot-cols { grid-column: 7 / span 6; grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr) minmax(0, 1.3fr); }
  .shl-foot-legal { grid-column: auto; }
  .shl-foot-legal .shl-foot-list { display: block; }
}

@media (hover: hover) and (pointer: fine) {
  .shl-foot a:hover { color: var(--ink); text-decoration-line: underline; }
  .shl-ack-sum:hover { color: var(--ink); }
}

@media (prefers-reduced-motion: reduce) {
  .shl-ack-sum:active { transform: none; }
  .shl-ack-sum svg { transition: none; }
}

@media (forced-colors: active) {
  .shl-ack-sum { border: var(--forced-edge); padding-inline: var(--s-2); }
  .shl-foot a[aria-current="page"] { text-decoration-line: underline; }
}

@media print {
  .shl-ack::details-content { content-visibility: visible; display: block; }
  .shl-ack-sum svg { display: none; }
}

/* ---------------------------------------------------------------- C8 Device bezels: every app screenshot (markup from tools/shots.mjs) */
/* Owner ruling 2026-11-11: no bare screenshots. One component, five devices, drawn in CSS so any capture of the right
   aspect drops in. The outer .shl-bezel is a size container; every measurement inside is a fraction of its width (cqi),
   so body, corners, island and hinge scale together and the device keeps its shape at every breakpoint. The screen is
   the <img> itself at its own width and height (G14): nothing is cropped, and the status bar is always whole. The body
   colour is fixed in both themes (tokens 3d); only the rim follows the theme. No hover, zoom or tilt.
   Sections set the width on .shl-bezel (max-inline-size); keep the slot's sizes attribute in step with it. */
.shl-bezel { display: block; inline-size: 100%; container-type: inline-size; }
.shl-bezel picture { display: block; }
.shl-bezel-body {
  position: relative;
  display: block;
  padding: var(--bz-pad);
  border-radius: var(--bz-r);
  background: var(--bezel);
  box-shadow: 0 0 0 1px var(--bezel-rim), inset 0 0 0 1px var(--bezel-edge), 0 2px 3px var(--bezel-shadow), 0 20px 44px -18px var(--bezel-shadow);
}
.shl-bezel-screen {
  position: relative;
  display: block;
  inline-size: 100%;
  block-size: auto;
  border-radius: var(--bz-r-in);
  background: var(--shot-ground);
  color: var(--shot-ink);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  text-align: center;
}
.shl-bezel-body::before, .shl-bezel-body::after { content: none; position: absolute; pointer-events: none; }

/* iPhone: rounded body, an island over the gap in the capture's own status bar. */
.shl-bezel--phone { --bz-pad: 3.3cqi; --bz-r: 15.4cqi; --bz-r-in: 12.2cqi; }
.shl-bezel--phone .shl-bezel-body::after {
  content: "";
  z-index: 1;
  inset-block-start: 6cqi;
  inset-inline-start: 36cqi;
  inline-size: 28cqi;
  block-size: 8cqi;
  border-radius: var(--r-pill);
  background: var(--bezel);
}

/* iPad: a thin even bezel with a camera dot on the long top edge (landscape) or the short top edge (portrait).
   The same physical bezel is a larger share of the narrower portrait width. */
.shl-bezel--pad.shl-bezel--landscape { --bz-pad: 2.5cqi; --bz-r: 4.4cqi; --bz-r-in: 1.9cqi; --bz-cam: 0.7cqi; }
.shl-bezel--pad.shl-bezel--portrait { --bz-pad: 3.3cqi; --bz-r: 5.8cqi; --bz-r-in: 2.5cqi; --bz-cam: 0.9cqi; }
.shl-bezel--pad .shl-bezel-body::after {
  content: "";
  inset-block-start: calc((var(--bz-pad) - var(--bz-cam)) / 2);
  inset-inline-start: calc(50% - var(--bz-cam) / 2);
  inline-size: var(--bz-cam);
  block-size: var(--bz-cam);
  border-radius: var(--r-pill);
  background: var(--bezel-edge);
}

/* iPhone Duo, open: one screen across two halves. The spine shows in the body above and below the glass (::before,
   under the screen), and a fold line crosses the screen (::after). Landscape folds left to right, portrait top to bottom. */
.shl-bezel--duo-open.shl-bezel--landscape { --bz-pad: 2.3cqi; --bz-r: 6.4cqi; --bz-r-in: 4.3cqi; --bz-spine: 1.5cqi; --bz-fold: 0.16cqi; }
.shl-bezel--duo-open.shl-bezel--portrait { --bz-pad: 3.2cqi; --bz-r: 9cqi; --bz-r-in: 6cqi; --bz-spine: 2.1cqi; --bz-fold: 0.22cqi; }
.shl-bezel--duo-open .shl-bezel-body::before { content: ""; background: var(--bezel-seam); }
.shl-bezel--duo-open .shl-bezel-body::after { content: ""; z-index: 1; background: var(--bezel-hinge); box-shadow: 0 0 calc(var(--bz-spine) * 0.8) 0 var(--bezel-hinge-soft); }
.shl-bezel--duo-open.shl-bezel--landscape .shl-bezel-body::before { inset-block: 0; inset-inline-start: calc(50% - var(--bz-spine) / 2); inline-size: var(--bz-spine); }
.shl-bezel--duo-open.shl-bezel--landscape .shl-bezel-body::after { inset-block: var(--bz-pad); inset-inline-start: calc(50% - var(--bz-fold) / 2); inline-size: var(--bz-fold); }
.shl-bezel--duo-open.shl-bezel--portrait .shl-bezel-body::before { inset-inline: 0; inset-block-start: calc(50% - var(--bz-spine) / 2); block-size: var(--bz-spine); }
.shl-bezel--duo-open.shl-bezel--portrait .shl-bezel-body::after { inset-inline: var(--bz-pad); inset-block-start: calc(50% - var(--bz-fold) / 2); block-size: var(--bz-fold); }

/* iPhone Duo, closed: the narrower outer display, with the spine down the hinge side of the body. */
.shl-bezel--duo-closed { --bz-pad: 3.6cqi; --bz-r: 11.5cqi; --bz-r-in: 8.2cqi; --bz-spine: 1.1cqi; }
.shl-bezel--duo-closed .shl-bezel-body { padding-inline-start: calc(var(--bz-pad) * 2.1); border-start-start-radius: calc(var(--bz-r) * 0.62); border-end-start-radius: calc(var(--bz-r) * 0.62); }
.shl-bezel--duo-closed .shl-bezel-body::before { content: ""; inset-block: 0; inset-inline-start: calc(var(--bz-pad) * 0.9); inline-size: var(--bz-spine); background: var(--bezel-seam); }

@media (forced-colors: active) {
  .shl-bezel-body { border: var(--forced-edge); }
}
@media print {
  .shl-bezel-body { box-shadow: 0 0 0 1px var(--bezel-rim); }
}

/* ---------------------------------------------------------------- Interior page template (section 8a) */
.shl-page {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-top: var(--page-top);
  padding-bottom: var(--sec-standard);
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}
.shl-page:focus { outline: none; }
.shl-page-head { max-inline-size: 75%; }
.shl-page-head .shl-lede { margin-top: var(--s-4); }   /* beats .shl-prose p, which zeroes it */

h1, h2, h3 { margin: 0; font-family: var(--font-display); color: var(--ink); text-wrap: balance; text-rendering: optimizeLegibility; }
h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); letter-spacing: var(--tr-h1); font-weight: var(--fw-display); }
h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); letter-spacing: var(--tr-h2); font-weight: var(--fw-display); max-inline-size: 16em; }
h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: var(--tr-h3); font-weight: var(--fw-h3); }

.shl-lede {
  margin: var(--s-4) 0 0;
  max-inline-size: var(--measure-lede);
  color: var(--ink-2);
  font-size: var(--fs-lede);
  line-height: var(--lh-lede);
  letter-spacing: var(--tr-lede);
  text-wrap: pretty;
}
.shl-prose p { margin: 0 0 0.9em; max-inline-size: var(--measure); text-wrap: pretty; }

/* C5 standalone text link and C6 prose link. */
.shl-link {
  display: inline-flex;
  align-items: center;
  min-width: var(--target);
  justify-content: center;
  min-height: var(--target);
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.shl-prose a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--accent-ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  overflow-wrap: anywhere;
}

/* :target tint on jumped-to headings (10b). */
:is(h2, h3):target { animation: shl-target var(--dur-target) var(--ease-color); }
@keyframes shl-target {
  from { background-color: var(--raised); }
  to { background-color: transparent; }
}

/* 404 (8i) */
.shl-404-links { display: flex; flex-wrap: wrap; gap: 0 var(--s-8); margin: var(--s-2) 0 0; padding: 0; list-style: none; }
.shl-404-try { margin: var(--s-6) 0 0; color: var(--ink-2); }

/* C20 Acknowledgements list (8h): name, licence or trademark line, where it appears. */
.shl-ack-group { margin-top: var(--s-16); }
.shl-ack-group h2 { margin-bottom: var(--s-8); }
.shl-dl { margin: 0; border-top: 1px solid var(--hair); }
.shl-dl-row { display: grid; gap: var(--s-1); padding-block: var(--s-5); border-bottom: 1px solid var(--hair); }
.shl-dl dt { color: var(--ink); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-strong); }
.shl-dl dd { margin: 0; max-inline-size: var(--measure); color: var(--ink-2); }
.shl-dl .shl-where { color: var(--ink-3); font-size: var(--fs-small); line-height: var(--lh-small); }

@media (min-width: 56.25em) {
  .shl-dl-row { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); column-gap: var(--col-gap); }
  .shl-dl dd { grid-column: 2; }
  .shl-dl dt { grid-row: 1 / span 2; }
}
@media not all and (min-width: 56.25em) {
  .shl-page-head { max-inline-size: none; }
}
@media (min-width: 56.25em) {
  .shl-404 .shl-page-head { max-inline-size: calc((100% - 4 * var(--col-gap)) * 8 / 12 + 7 * var(--col-gap)); }
}

@media (hover: hover) and (pointer: fine) {
  .shl-link:hover, .shl-prose a:hover { text-decoration-thickness: var(--link-underline-w); }
}
@media (prefers-reduced-motion: reduce) {
  :is(h2, h3):target { animation: none; text-decoration: underline 2px var(--ink); }
}
@media print {
  .shl-nav-wrap, .shl-skip, .shl-legal ~ .shl-foot { display: none; }
  .shl-page { padding-top: 0; }
  .shl-prose a[href^="http"]::after { content: " (" attr(href) ")"; color: var(--ink-3); }
  .shl-prose a[href^="/"]::after { content: " (smarthomelifellc.com" attr(href) ")"; color: var(--ink-3); }
}

/* ---------------------------------------------------------------- Legal pages (8f, 8g): head, short version, contents, sections */
.shl-meta {
  margin: var(--s-3) 0 0;
  color: var(--ink-3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}
.shl-short { margin-top: var(--s-12); }
.shl-short h2 { margin-bottom: 0; }
.shl-short .shl-lede { margin-top: var(--s-4); }   /* beats .shl-prose p, which zeroes it */
.shl-contents { margin-top: var(--s-8); }
.shl-contents ol { margin: 0; padding: 0; list-style: none; columns: 2 16rem; column-gap: var(--col-gap); }
.shl-contents li { break-inside: avoid; }
.shl-contents a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  text-decoration: none;
  text-underline-offset: 4px;
}
.shl-legal-section { margin-top: var(--s-16); }
.shl-legal-section h2 { margin-bottom: var(--s-4); }
.shl-legal-section h3 { margin: var(--s-8) 0 var(--s-3); }
.shl-legal-section ul { margin: 0 0 0.9em; padding-left: 1.2em; max-inline-size: var(--measure); }
.shl-legal-section li { margin-bottom: 0.4em; }
.shl-legal .shl-prose p, .shl-legal p { max-inline-size: var(--measure); }

@media (hover: hover) and (pointer: fine) {
  .shl-contents a:hover { color: var(--ink); text-decoration-line: underline; }
}

/* ---------------------------------------------------------------- Privacy (8f): rail, mobile fold, C18 data-path block */
.shl-onpage { margin-top: var(--s-8); }
.shl-onpage ol, .shl-rail ol { margin: 0; padding: 0; list-style: none; }
.shl-onpage ol { padding-bottom: var(--s-4); }
.shl-onpage a, .shl-rail a {
  position: relative;
  display: flex;
  align-items: center;
  min-height: var(--target);
  padding-inline: var(--s-3) 0;
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  text-decoration: none;
  text-underline-offset: 4px;
}
.shl-rail a[aria-current="location"] { color: var(--ink); font-weight: var(--fw-strong); }
.shl-rail a[aria-current="location"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 16px;
  margin-top: -8px;
  background: var(--ink);
}
.shl-rail { display: none; }

.shl-path-dl { margin: var(--s-6) 0 0; border-top: 1px solid var(--hair); max-inline-size: var(--measure); }
.shl-path-dl > div { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-1); padding-block: var(--s-4); border-bottom: 1px solid var(--hair); }
.shl-path-dl dt { color: var(--ink); font-size: var(--fs-small); line-height: var(--lh-small); font-weight: var(--fw-strong); }
.shl-path-dl dd { margin: 0; color: var(--ink-2); overflow-wrap: anywhere; }

@media (min-width: 35em) {
  .shl-path-dl > div { grid-template-columns: 9rem minmax(0, 1fr); column-gap: var(--s-6); }
}
@media (min-width: 68.75em) {
  .shl-onpage { display: none; }
  .shl-legal-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--col-gap); margin-top: var(--s-12); }
  .shl-rail { display: block; grid-column: 1 / span 3; align-self: start; position: sticky; top: var(--nav-clear); max-block-size: calc(100dvh - var(--nav-clear) - var(--s-4)); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; padding: 5px; margin: -5px; }
  .shl-legal-body { grid-column: 4 / span 7; min-width: 0; }
  .shl-legal-body > .shl-legal-section:first-child { margin-top: 0; }
}

/* ---------------------------------------------------------------- FAQ (8d): group chips below 68.75em, end line */
/* 5px of padding holds the whole focus ring (2px outline, 3px offset) inside the scroller, which clips. */
.shl-chips { margin: var(--s-8) -5px 0; padding: 5px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; }
/* While chips sit hidden past the right edge (site.js sets data-more), fade that edge so the row reads as scrollable.
   Never with focus inside, so a focused chip and its ring are never faded. */
.shl-chips[data-more]:not(:focus-within) { mask-image: linear-gradient(to right, #000 85%, transparent); }
.shl-chips ul { display: flex; gap: var(--s-6); inline-size: max-content; margin: 0; padding: 0; list-style: none; }
.shl-chips a {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target);
  min-inline-size: var(--target);   /* a short label ("Basics", 42.6px) stays a 44px target; measured 2026-11-11 */
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  text-decoration: none;
  text-underline-offset: 4px;
}
.shl-chips a[aria-current="location"] { color: var(--ink); font-weight: var(--fw-strong); }
.shl-chips a[aria-current="location"]::after { content: ""; position: absolute; inset: auto 0 6px; height: 2px; background: var(--ink); }
.shl-faq-end { margin-top: var(--s-16); }
@media (min-width: 68.75em) {
  .shl-chips { display: none; }
}

@media (hover: hover) and (pointer: fine) {
  .shl-onpage a:hover, .shl-rail a:hover, .shl-chips a:hover { color: var(--ink); text-decoration-line: underline; }
}
@media (forced-colors: active) {
  .shl-rail a[aria-current="location"], .shl-chips a[aria-current="location"] { text-decoration-line: underline; }
}
@media print {
  .shl-rail, .shl-onpage, .shl-chips { display: none; }
}

/* ---------------------------------------------------------------- Support (8e): contact panel, quick answers */
/* C7 secondary button; C12 Copy Email uses it too. */
.shl-btn2 {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target-row);
  padding: 0 var(--s-5);
  border: 1px solid var(--control-edge);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-strong);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-btn2:active { transform: scale(0.97); }
.shl-btn2[hidden] { display: none; }
.shl-prose a.shl-btn2 { text-decoration: none; }   /* beats .shl-prose a: a button never shows a link underline */

.shl-support-grid { display: flex; flex-direction: column; gap: var(--s-16); margin-top: var(--s-12); }
.shl-contact h2 { font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: var(--tr-h3); font-weight: var(--fw-h3); }
.shl-contact .shl-contact-addr { margin: var(--s-3) 0 0; color: var(--ink); font-weight: var(--fw-strong); overflow-wrap: anywhere; user-select: all; }
.shl-contact-btns { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-4); }
.shl-contact .shl-copy-status { min-height: var(--lh-small); margin: var(--s-2) 0 0; color: var(--ink-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.shl-contact h3 { margin-top: var(--s-8); font-family: var(--font-body); font-size: var(--fs-small); line-height: var(--lh-small); letter-spacing: 0; font-weight: var(--fw-strong); }
.shl-contact ul { margin: var(--s-2) 0 0; padding-left: 1.2em; color: var(--ink-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.shl-contact li + li { margin-top: var(--s-1); }
.shl-contact .shl-contact-note { margin-top: var(--s-6); color: var(--ink-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.shl-contact .shl-contact-links { display: flex; flex-wrap: wrap; gap: 0 var(--s-6); margin: var(--s-4) 0 0; padding: 0; list-style: none; }
.shl-contact-links .shl-link { font-size: var(--fs-small); }
.shl-contact .shl-contact-links li + li { margin-top: 0; }   /* a row, not a list: no stacked-item gap */

.shl-qa-groups { display: flex; flex-direction: column; gap: var(--s-12); min-width: 0; }
.shl-qa-group h2 { margin-bottom: var(--s-6); }
.shl-qa-list { border-top: 1px solid var(--hair); }
/* C14 disclosure row */
.shl-qa { border-bottom: 1px solid var(--hair); }
.shl-qa-sum {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: calc(var(--target-row) + var(--s-2));
  padding: var(--s-3) var(--s-2);
  margin-inline: calc(-1 * var(--s-2));
  border-radius: var(--r-sm);
  list-style: none;
  cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-qa-sum::-webkit-details-marker { display: none; }
.shl-qa-sum:active { transform: scale(0.99); }
.shl-q { min-width: 0; color: var(--ink); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-strong); overflow-wrap: anywhere; text-wrap: pretty; }
.shl-qa-sum svg { width: 20px; height: 20px; flex: none; color: var(--ink-2); transition: transform var(--dur-chrome) var(--ease-in-out); }
.shl-qa[open] > .shl-qa-sum svg { transform: rotate(180deg); }
.shl-qa-body { padding-bottom: var(--s-6); }
.shl-qa-body p, .shl-qa-body ol, .shl-qa-body ul { margin: 0; max-inline-size: var(--measure); color: var(--ink-2); }
/* :is() lifts this to the weight of the reset above, so paragraphs in one answer keep a gap. */
.shl-qa-body > * + :is(p, ol, ul) { margin-top: var(--s-3); }
.shl-qa-body ol, .shl-qa-body ul { padding-left: 1.4em; }
.shl-qa-body li + li { margin-top: var(--s-1); }
.shl-qa:target > .shl-qa-sum { animation: shl-target var(--dur-target) var(--ease-color); }

@media (min-width: 56.25em) {
  .shl-support-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--col-gap); }
  .shl-qa-groups { grid-column: 1 / span 7; grid-row: 1; }
  .shl-contact { grid-column: 9 / span 4; grid-row: 1; align-self: start; position: sticky; top: calc(var(--nav-clear) + var(--s-4)); min-width: 0; }
}
@media (hover: hover) and (pointer: fine) {
  .shl-btn2:hover, .shl-qa-sum:hover { background-color: var(--raised); }
}
@media (prefers-reduced-motion: reduce) {
  .shl-btn2:active, .shl-qa-sum:active { transform: none; }
  .shl-qa-sum svg { transition: none; }
}
@media (forced-colors: active) {
  .shl-btn2 { border: var(--forced-edge); }
  .shl-qa-sum { border: var(--forced-edge); }
}
@media print {
  .shl-qa::details-content { content-visibility: visible; display: block; }
  .shl-qa-sum svg, .shl-contact-btns, .shl-copy-status { display: none; }
  .shl-contact { position: static; }
}

/* ---------------------------------------------------------------- Home (8b): shared wrap and 12-column grid (section 5) */
.shl-home:focus { outline: none; }
.shl-wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}
.shl-wrap-wide { max-width: var(--wrap-wide); }
@media (min-width: 56.25em) {
  .shl-wrap { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--col-gap); }
}

/* ---------------------------------------------------------------- Home 1 Hero #top (8b.1): stage */
.shl-hero {
  padding-top: var(--page-top);
  border-bottom: 1px solid var(--hair);
}
.shl-display {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  max-inline-size: 13.5em;
}
.shl-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--s-3) var(--s-6);
  margin-top: var(--s-6);
}
/* C3: Apple's badge artwork at 48px tall, never stretched or recolored. The link takes the site focus ring. */
.shl-badge { display: inline-block; flex: none; line-height: 0; border-radius: var(--r-sm); }
.shl-badge img { display: block; block-size: 48px; inline-size: auto; }

/* C4 QR: from 68.75em up, never under a coarse pointer, never on phones. A light tile with dark modules in both
   themes (cream on dark, surface on light), so it scans the same way whatever the theme. */
.shl-qr {
  display: none;
  align-items: center;
  gap: var(--s-4);
  margin: 0;
}
/* The wider space before the QR sits after the link, not on the QR, so a QR that wraps to its own row starts on
   the column edge with the badge. */
.shl-hero-actions .shl-link { margin-inline-end: var(--s-6); }
.shl-qr-code {
  inline-size: var(--qr);
  block-size: var(--qr);
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--ground);
  forced-color-adjust: none;
}
:root[data-theme="light"] .shl-qr-code { background: var(--surface); color: var(--ink); outline: 1px solid var(--hair); }
.shl-qr figcaption {
  max-inline-size: 9em;
  color: var(--ink-3);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--tr-caption);
}
@media (min-width: 68.75em) {
  .shl-qr { display: flex; }
}
@media (pointer: coarse) {
  .shl-qr { display: none; }
}

/* Device stage: below the copy. Under 35em the iPhone alone at 78% of the column. From 35em the iPad spans
   cols 2-11 of --wrap-wide and the iPhone overlaps its lower right in cols 9-12, its top 12% of the iPad's height
   down (the margin resolves against the iPhone's grid area: 0.12 x 3/4 x iPad width / iPhone width = 23.6%).
   The iPhone's foot sits on the hairline that closes the hero. */
.shl-hero-stage { margin-top: var(--s-12); }
.shl-hero-pad { display: none; }
.shl-hero-phone { inline-size: 78%; margin-inline: auto; }
@media (min-width: 35em) {
  .shl-hero-stage { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--col-gap); align-items: start; }
  .shl-hero-pad { display: block; grid-column: 2 / span 10; grid-row: 1; }
  .shl-hero-phone { grid-column: 9 / span 4; grid-row: 1; inline-size: auto; margin: 23.6% 0 0; }
}
@media (min-width: 56.25em) {
  .shl-hero-copy h1 { grid-column: 1 / span 11; }
  .shl-hero-copy .shl-lede { grid-column: 1 / span 6; }
  .shl-hero-actions { grid-column: 1 / -1; }
  .shl-hero-stage { margin-top: var(--s-16); }
}

/* Screen wake (10b): once per load the stage brightens; nothing moves and opacity stays 1 (LCP). Only with
   html.js-motion, which <head> sets without reduced motion; site.js adds is-loaded after the first frame. */
html.js-motion .shl-hero-stage .shl-bezel-screen { filter: brightness(0.82); transition: filter var(--dur-hero) var(--ease-out); }
html.js-motion.is-loaded .shl-hero-stage .shl-bezel-screen { filter: none; }

@media print {
  .shl-qr-code { background: var(--surface); color: var(--ink); }
}

/* ---------------------------------------------------------------- Home 2 Control #features (8b.2): split 5/7 */
.shl-control { padding-block: var(--sec-chapter); }
.shl-control-copy, .shl-control-media { min-width: 0; }
.shl-control-media { margin-top: var(--s-12); }
/* Under 35em the iPhone sits start-aligned at 78% of the column: full width it made the same silhouette as
   Console's iPad right below it (G4 measured 0.923 in light at 390). */
.shl-control-media .shl-bezel { display: block; inline-size: 78%; max-inline-size: var(--phone-max); }
@media (min-width: 35em) {
  .shl-control-media .shl-bezel { inline-size: 100%; margin-inline: auto; }
}

/* C9 ruled list: hairline rows, a Figtree 600 label over a one-line explanation in --ink-2. No icons, not links. */
.shl-ruled {
  margin: var(--s-6) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hair);
}
.shl-ruled li {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--s-1);
  min-block-size: var(--s-16);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--hair);
}
.shl-ruled-label { color: var(--ink); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg); font-weight: var(--fw-strong); }
.shl-ruled-line { max-inline-size: var(--measure); color: var(--ink-2); text-wrap: pretty; }

/* Honesty caption (11b): directly under the claim it qualifies, --fs-small in --ink-3, never in a tooltip. */
.shl-honesty {
  max-inline-size: var(--measure);
  margin: var(--s-4) 0 0;
  color: var(--ink-3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  text-wrap: pretty;
}

@media (min-width: 56.25em) {
  .shl-control-copy { grid-column: 1 / span 5; grid-row: 1; }
  /* Top-aligned with the H2: the media column starts on the same grid row, no top margin. */
  .shl-control-media { grid-column: 7 / span 6; grid-row: 1; align-self: start; margin-top: 0; }
}

/* ---------------------------------------------------------------- Home 3 Console #console (8b.3): theater */
/* On the page ground, centered: heading cols 3-10, the segment control centered under it, the iPad cols 2-11.
   One panel shows at a time; site.js swaps them instantly (no transition). Without JavaScript the tabs go and the
   three panels stack, each under its h3 caption. */
.shl-console { padding-block: var(--sec-chapter); }
.shl-console-head { min-width: 0; text-align: center; }
.shl-console-head h2, .shl-console-head .shl-lede, .shl-console-head .shl-honesty { margin-inline: auto; }
/* Block-end only: tabbing into a panel scrolls just far enough to show its border box, so this keeps the bottom of
   the focus ring on screen (G8). The top stays on html's scroll-padding-top (section 9). */
.shl-console-panel { min-width: 0; margin-top: var(--s-12); border-radius: var(--r-lg); scroll-margin-block-end: var(--s-2); }
.shl-console-panel[hidden] { display: none; }
.shl-console-cap { margin-bottom: var(--s-4); text-align: center; }
html.js .shl-console-cap, html.js .shl-console-rest { display: none; }

/* C10 segment control: a --surface track with a --control-edge boundary; the selected tab is --raised with its own
   --control-edge border, --ink and weight 600 (the state never rests on the 1.1:1 fill or the weight alone). Each tab
   reserves its weight-600 width (::after), so selecting one never shifts the others. Under 35em the track spans the
   column and the tabs share the spare width; from 35em it shrink-wraps and the tabs are equal. */
.shl-seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: auto;
  inline-size: 100%;
  margin-top: var(--s-8);
  padding: 3px;   /* deliberate optical inset, below the --s-1 step: the selected tab sits 3px inside the track */
  border: 1px solid var(--control-edge);
  border-radius: var(--r-pill);
  background: var(--surface);
}
.shl-seg-tab {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: var(--target);
  margin: 0;
  padding: 0 var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-medium);
  text-align: center;
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease-color), transform var(--dur-press) var(--ease-out);
}
.shl-seg-tab::after {
  content: attr(data-label);
  block-size: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: var(--fw-strong);
}
.shl-seg-tab:active { transform: scale(0.97); }
.shl-seg-tab[aria-selected="true"] {
  border-color: var(--control-edge);
  background: var(--raised);
  color: var(--ink);
  font-weight: var(--fw-strong);
}
html:not(.js) .shl-seg { display: none; }

@media (min-width: 35em) {
  .shl-seg { grid-auto-columns: minmax(0, 1fr); inline-size: fit-content; max-inline-size: 100%; margin-inline: auto; }
  .shl-seg-tab { padding-inline: var(--s-5); }
}
@media (min-width: 56.25em) {
  .shl-console-head { grid-column: 3 / span 8; }
  .shl-seg { grid-column: 1 / -1; justify-self: center; }
  .shl-console-panel { grid-column: 2 / span 10; }
}
@media (hover: hover) and (pointer: fine) {
  .shl-seg-tab:hover { color: var(--ink); }
}
@media (prefers-reduced-motion: reduce) {
  .shl-seg-tab:active { transform: none; }
}
@media (forced-colors: active) {
  .shl-seg { border: var(--forced-edge); }
  .shl-seg-tab[aria-selected="true"] { border: var(--forced-edge); text-decoration-line: underline; }
}

/* ---------------------------------------------------------------- Home 4 Guest Access #guest-access (8b.4): statement and steps */
/* One display sentence in cols 1-10, then the steps in cols 1-6 and the guest's pass page in cols 8-11, top-aligned.
   The site draws no door-code tile: the screenshot carries it. */
.shl-guest { padding-block: var(--sec-standard); }
.shl-display-2 {
  font-size: var(--fs-display-2);
  line-height: var(--lh-display-2);
  letter-spacing: var(--tr-display-2);
}
.shl-guest-copy, .shl-guest-media { min-width: 0; }
.shl-guest-copy { margin-top: var(--s-8); }
.shl-guest-media { margin-top: var(--s-12); }
.shl-guest-media .shl-bezel { display: block; inline-size: 100%; max-inline-size: var(--phone-max); margin-inline: auto; }

/* C11 guest steps: an <ol> with inline body-size numerals ("1.") in Figtree 600 at the list's own size, the step's
   name in --ink and its line in --ink-2. Not a ruled list: no hairlines. role="list" keeps the list in VoiceOver
   once list-style is gone. */
.shl-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: shl-step;
  max-inline-size: var(--measure);
  color: var(--ink-2);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
.shl-steps li { counter-increment: shl-step; text-wrap: pretty; }
.shl-steps li + li { margin-top: var(--s-4); }
.shl-steps li::before { content: counter(shl-step) ". "; color: var(--ink); font-weight: var(--fw-strong); }
.shl-step-label { color: var(--ink); font-weight: var(--fw-strong); }
.shl-guest .shl-honesty { margin-top: var(--s-6); }

@media (min-width: 56.25em) {
  .shl-guest h2 { grid-column: 1 / span 10; }
  .shl-guest-copy { grid-column: 1 / span 6; grid-row: 2; margin-top: var(--s-12); }
  .shl-guest-media { grid-column: 8 / span 4; grid-row: 2; align-self: start; }
  .shl-guest-media .shl-bezel { max-inline-size: none; }
}

/* ---------------------------------------------------------------- Home 5 Free tools #thread (8b.5): feature and index */
/* The Thread map on an iPhone, centred in cols 1-7 with its honesty caption under it; the free tool index (C9) in cols 8-12.
   DOM order is H2, map, index, which is also the order under 56.25em. From 56.25em the H2 sits over the map in cols
   1-7 and the index spans both rows, top-aligned with the H2. (8b.5 puts the H2 over the index; with the H2 there, the
   seven rows ran 390 to 700px below the map and caption, and the 5-column H2 broke to 4 lines at 900. Review
   2026-11-01.) */
.shl-tools { padding-block: var(--sec-chapter); }
.shl-tools-map, .shl-tools-index { min-width: 0; }
.shl-tools-map { margin: var(--s-12) 0 0; }
.shl-tools-map .shl-bezel { inline-size: 78%; max-inline-size: var(--phone-max); margin-inline: auto; }
.shl-tools-map figcaption { margin-inline: auto; text-align: center; }
.shl-tools-index { margin-top: var(--s-12); }
.shl-tools-index .shl-ruled { margin-top: 0; }
.shl-tools-more { margin: var(--s-4) 0 0; }

@media (min-width: 56.25em) {
  /* 1fr: when the index is taller than H2 and map together, the extra height goes to the map row, not between the
     H2 and the map. */
  .shl-tools .shl-wrap { grid-template-rows: auto 1fr; }
  .shl-tools h2 { grid-column: 1 / span 7; grid-row: 1; }
  .shl-tools-map { grid-column: 1 / span 7; grid-row: 2; }
  .shl-tools-index { grid-column: 8 / span 5; grid-row: 1 / span 2; align-self: start; margin-top: 0; }
}

/* ---------------------------------------------------------------- Home 6 Energy #energy (8b.6): offset split 7/5 */
/* The iPhone in cols 1-5, the copy in cols 7-12. Plain lines, not a ruled list: one per Energy feature, in two groups
   that say in words which are free and which come with Pro. DOM order is heading, copy, media (the mobile order). */
.shl-energy { padding-block: var(--sec-standard); }
.shl-energy-copy, .shl-energy-media { min-width: 0; }
.shl-energy-media { margin-top: var(--s-12); }
.shl-energy-media .shl-bezel { display: block; inline-size: 100%; max-inline-size: var(--phone-max); margin-inline: auto; }
.shl-energy-group {
  margin: var(--s-6) 0 0;
  color: var(--ink);
  font-weight: var(--fw-strong);
}
.shl-lines {
  margin: var(--s-2) 0 0;
  padding: 0;
  list-style: none;
  max-inline-size: var(--measure);
  color: var(--ink-2);
}
.shl-lines li { text-wrap: pretty; }
.shl-lines li + li { margin-top: var(--s-2); }

@media (min-width: 56.25em) {
  .shl-energy-copy { grid-column: 7 / span 6; grid-row: 1; align-self: start; }
  /* Bottom-aligned, so the hang below is exact whichever column is taller. */
  .shl-energy-media { grid-column: 1 / span 5; grid-row: 1; align-self: end; margin-top: 0; }
  /* The iPhone hangs --s-16 into the next section's top padding (the only overlap besides the hero). Only when a
     section follows: with nothing after it, it would sit on the footer. The next section is Pricing (--sec-chapter);
     the hang never leaves less than --s-12 (section 5's copy to media floor) above its heading, so it shrinks below
     --s-16 where --sec-chapter is under 112px (from 900 to 1120 wide). */
  .shl-energy:has(+ section) .shl-energy-media {
    margin-bottom: calc(-1 * (var(--sec-standard) + min(var(--s-16), var(--sec-chapter) - var(--s-12))));
  }
}
/* Keeps a hyphenated word on one line ("co-op", "off-peak"), so a narrow column never breaks it at the hyphen. */
.shl-nobr { white-space: nowrap; }

/* ---------------------------------------------------------------- Home 7 iPhone Duo #duo (owner ruling 2026-11-11): three poses */
/* A short section: one claim, then the three ways the app sits on the Duo, each in its own bezel on one baseline:
   closed (the outer display), open in portrait, open in landscape. Under 35em they stack, each centred; from 35em the
   two upright ones share a row over the landscape one; from 56.25em all three sit in one row (3, 4 and 5 columns).
   --sec-chapter, because Energy's iPhone hangs into this section's top padding and its hang is sized for it. */
.shl-duo { padding-block: var(--sec-chapter); }
.shl-duo-copy { min-width: 0; }
.shl-duo-stage {
  display: grid;
  gap: var(--s-12) var(--col-gap);
  align-items: end;
  margin: var(--s-12) 0 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}
.shl-duo-item { min-width: 0; }
.shl-duo-item .shl-bezel { margin-inline: auto; }
.shl-duo-item--outer .shl-bezel { inline-size: 62%; max-inline-size: var(--duo-outer-max); }
.shl-duo-item--portrait .shl-bezel { inline-size: 86%; max-inline-size: var(--duo-open-max); }
.shl-duo-cap {
  margin: var(--s-4) 0 0;
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  text-align: center;
}
@media (min-width: 35em) {
  .shl-duo-stage { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shl-duo-item--landscape { grid-column: 1 / -1; }
  .shl-duo-item--landscape .shl-bezel { max-inline-size: calc(var(--duo-open-max) * 1.7); }
}
@media (min-width: 56.25em) {
  .shl-duo-copy { grid-column: 1 / span 7; }
  .shl-duo-stage { grid-column: 1 / -1; grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .shl-duo-item--outer { grid-column: 1 / span 3; }
  .shl-duo-item--portrait { grid-column: 4 / span 4; }
  .shl-duo-item--landscape { grid-column: 8 / span 5; }
  .shl-duo-item .shl-bezel { inline-size: 100%; }
  .shl-duo-item--landscape .shl-bezel { max-inline-size: none; }
}

/* ---------------------------------------------------------------- Home 8 Pricing #pricing (8b.7, ruling 2026-11-01): ledger */
/* Heading and trial line in cols 1-5, the C13 ledger in cols 6-12. One purchase, Smart Home Life Pro, so one row; the
   price comes from the build's store data or reads "See price on the App Store". Prices are --ink, never red. Under
   35em the row becomes a two-line block (name and price, then what it adds) with the column heads kept for screen
   readers only; the role attributes in the markup keep the table semantics once display changes. */
.shl-pricing { padding-block: var(--sec-chapter); }
.shl-pricing-head, .shl-ledger { min-width: 0; }
.shl-ledger {
  inline-size: 100%;
  margin-top: var(--s-8);
  border-collapse: collapse;
  text-align: left;
}
.shl-ledger caption {
  caption-side: top;
  padding-bottom: var(--s-4);
  color: var(--ink-3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  text-align: left;
  text-wrap: pretty;
}
.shl-ledger thead th {
  padding: 0 var(--s-6) var(--s-3) 0;
  border-bottom: 1px solid var(--hair);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-strong);
  vertical-align: bottom;
}
.shl-ledger tbody :is(th, td) {
  padding: var(--s-5) var(--s-6) var(--s-5) 0;
  border-bottom: 1px solid var(--hair);
  vertical-align: top;
}
.shl-ledger tr > :last-child { padding-inline-end: 0; }
.shl-ledger-name, .shl-ledger-price {
  color: var(--ink);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  font-weight: var(--fw-strong);
}
.shl-ledger-name { inline-size: 8em; text-wrap: balance; }
.shl-ledger-num { text-align: right; font-variant-numeric: tabular-nums; }
.shl-ledger-price { inline-size: 7.5em; }
.shl-ledger-list { margin: 0; padding: 0; list-style: none; max-inline-size: var(--measure); color: var(--ink-2); }
.shl-ledger-list li { text-wrap: pretty; }
.shl-ledger-list li + li { margin-top: var(--s-2); }
.shl-ledger-tool { color: var(--ink); font-weight: var(--fw-strong); }

@media not all and (min-width: 35em) {
  .shl-ledger, .shl-ledger tbody, .shl-ledger caption { display: block; }
  /* Blocks inside the 1px box, so the header row does not lay out wider than the screen at 200% text (G9). */
  .shl-ledger thead, .shl-ledger thead tr, .shl-ledger thead th { display: block; }
  .shl-ledger thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .shl-ledger tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--s-4);
    padding-block: var(--s-5);
    border-block: 1px solid var(--hair);
  }
  .shl-ledger tbody :is(th, td) { display: block; inline-size: auto; padding: 0; border: 0; }
  .shl-ledger-name { grid-column: 1; grid-row: 1; }
  .shl-ledger-price { grid-column: 2; grid-row: 1; max-inline-size: 9em; }
  .shl-ledger-adds { grid-column: 1 / -1; grid-row: 2; margin-top: var(--s-3); }
}
@media (min-width: 56.25em) {
  .shl-pricing-head { grid-column: 1 / span 5; grid-row: 1; }
  .shl-ledger { grid-column: 6 / span 7; grid-row: 1; align-self: start; margin-top: 0; }
}

/* ---------------------------------------------------------------- Home 8 What's new #whats-new (8b.8): changelog rail */
/* C15 from the build's store data. Version (h3, tabular) and date in cols 1-3, sticky inside the section; the notes
   in cols 4-10 with the version history link under them. No hairlines: the ledger above is the ruled one. */
.shl-news { padding-block: var(--sec-standard); }
.shl-news-meta, .shl-news-body { min-width: 0; }
.shl-news-meta { margin-top: var(--s-8); }
.shl-rail-ver { font-variant-numeric: tabular-nums; }
.shl-news-date {
  margin: var(--s-1) 0 0;
  color: var(--ink-3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-variant-numeric: tabular-nums;
}
.shl-news-body { margin-top: var(--s-4); }
.shl-news-notes {
  margin: 0;
  padding-left: 1.2em;
  max-inline-size: var(--measure);
  color: var(--ink-2);
}
.shl-news-notes li { text-wrap: pretty; }
.shl-news-notes li + li { margin-top: var(--s-2); }
.shl-news-notes li::marker { color: var(--ink-3); }
.shl-news-more { margin: var(--s-4) 0 0; }

@media (min-width: 56.25em) {
  .shl-news h2 { grid-column: 1 / span 10; grid-row: 1; }
  .shl-news-meta { grid-column: 1 / span 3; grid-row: 2; align-self: start; position: sticky; top: calc(var(--nav-clear) + var(--s-4)); }
  .shl-news-body { grid-column: 4 / span 7; grid-row: 2; margin-top: var(--s-8); }
}

/* ---------------------------------------------------------------- Home 9 FAQ teaser #faq (8b.9): ruled disclosure */
/* Four C14 rows in cols 1-8 (the Support rows' component), then the "See all questions" text link. */
.shl-faqt { padding-block: var(--sec-standard); }
.shl-faqt-rows { min-width: 0; margin-top: var(--s-8); }
.shl-faqt-more { margin: var(--s-4) 0 0; }
@media (min-width: 56.25em) {
  .shl-faqt h2, .shl-faqt-rows, .shl-faqt-more { grid-column: 1 / span 8; }
}

/* ---------------------------------------------------------------- Home 10 Closing #download (8b.10): asymmetric sign-off */
/* Left-aligned, not a centered band: the statement and fine print in cols 1-7, the badge and QR in cols 9-12,
   bottom-aligned with the fine print. Under 56.25em it stacks: statement, fine print, badge (the QR shows only from
   68.75em, never under a coarse pointer). The footer's own top hairline closes it. */
.shl-close { padding-block: var(--sec-chapter); }
.shl-close-copy, .shl-close-actions { min-width: 0; }
.shl-close-fine {
  margin: var(--s-4) 0 0;
  max-inline-size: var(--measure);
  color: var(--ink-3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  text-wrap: pretty;
}
.shl-close-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-6);
  margin-top: var(--s-8);
}
/* The QR's caption goes under the code here, so the badge and the QR fit side by side in four columns. */
.shl-close-actions .shl-qr { flex-direction: column; align-items: flex-start; gap: var(--s-2); }
@media (min-width: 56.25em) {
  .shl-close-copy { grid-column: 1 / span 7; grid-row: 1; align-self: end; }
  .shl-close-actions { grid-column: 9 / span 4; grid-row: 1; align-self: end; margin-top: 0; }
}
