/******* Do not edit this file *******
Woody Code Snippets CSS and JS
Saved: 2026-08-20T17:33:10Z */
.rbm-more {

/* ============================================================================
   RBM MORE, product page.
   ALL device/tile visuals are REAL screenshots + a real scroll video captured
   from the running ui-lab rig (Playwright @ iPhone viewport, deviceScaleFactor 3).
   Assets in ./assets/. Nothing is a hand-built tile. Dark is :root; .t-light
   carries the light deltas so sections alternate (the app's real bicolor swap).
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img, svg, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }

& {
  --bg-base: #121419;
  --accent-heat: #D9824F; --accent-cool: #5E92C4; --accent-idle: #8C909B;
  --accent-eco: #6FA67C; --st-warn: #C89B3C; --st-alarm: #C25E54; --accent-ai: #C6B3FF;
  --hairline: rgba(255,255,255,0.08); --hairline-strong: rgba(255,255,255,0.17);
  --surface-sunken: rgba(255,255,255,0.07); --surface-raised: rgba(255,255,255,0.05);
  --dial-heat-vivid: var(--accent-heat); --dial-heat-light: color-mix(in srgb, var(--accent-heat) 25%, var(--surface-sunken)); --dial-heat-dim: color-mix(in srgb, var(--accent-heat) 6%, var(--surface-raised)); --dial-heat-edge: color-mix(in srgb, var(--accent-heat) 45%, transparent);
  --dial-cool-vivid: var(--accent-cool); --dial-cool-light: color-mix(in srgb, var(--accent-cool) 25%, var(--surface-sunken)); --dial-cool-dim: color-mix(in srgb, var(--accent-cool) 6%, var(--surface-raised)); --dial-cool-edge: color-mix(in srgb, var(--accent-cool) 45%, transparent);
  --dial-arc-dim: var(--surface-raised); --dial-arc-med: var(--surface-sunken);
  --dial-handle-fill: var(--t-primary); --dial-punch-stroke: rgba(0,0,0,0.55); --dial-handle-stroke: var(--dial-punch-stroke); --dial-room-dot: #FFFFFF;
  --dial-text-primary: var(--t-primary); --dial-text-secondary: var(--t-secondary); --dial-text-tertiary: var(--t-tertiary);
  --ink-rgb: 236,237,242;
  --t-primary: rgba(var(--ink-rgb),0.95); --t-secondary: rgba(var(--ink-rgb),0.60);
  --t-tertiary: rgba(var(--ink-rgb),0.37);
  --font-sans: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --maxw: 1120px; --pad: clamp(20px, 5vw, 64px);
}
.t-light {
  --bg-base: #F4F3EF;
  --accent-cool: #4A80B5; --accent-idle: #6F7682; --accent-eco: #5A8A66; --st-warn: #AE7C2A; --accent-ai: #6E5BB8;
  --hairline: rgba(0,0,0,0.13); --hairline-strong: rgba(0,0,0,0.24); --surface-sunken: rgba(0,0,0,0.095);
  --ink-rgb: 26,28,36;
  --t-primary: rgba(var(--ink-rgb),0.95); --t-secondary: rgba(var(--ink-rgb),0.72); --t-tertiary: rgba(var(--ink-rgb),0.52);
}
& { font-family: var(--font-sans); background: var(--bg-base); color: var(--t-primary); font-feature-settings: 'tnum'; -webkit-font-smoothing: antialiased; overflow-x: hidden; }

.sec { position: relative; background: var(--bg-base); color: var(--t-primary); padding: clamp(72px,12vh,150px) var(--pad); transition: background 700ms ease, color 700ms ease; overflow: hidden; }
.wrap { max-width: var(--maxw); margin: 0 auto; }
.narrow { max-width: 780px; margin: 0 auto; }

.eyebrow { font-size: clamp(11px,1.4vw,13px); letter-spacing: 0.18em; text-transform: uppercase; font-weight:500; color: var(--accent, var(--t-secondary)); margin-bottom: 18px; }
h1,h2,h3 { font-weight:500; letter-spacing: -0.022em; line-height: 1.04; overflow-wrap: break-word; }
h1 { font-size: clamp(36px,8vw,92px); font-weight: 700; letter-spacing: -0.03em; }
h2 { font-size: clamp(28px,5vw,56px); }
h3 { font-size: clamp(21px,3vw,32px); }
.lead { font-size: clamp(17px,2.1vw,22px); line-height: 1.5; color: var(--t-secondary); max-width: min(44ch,100%); }
.lead.center { margin: 0 auto; text-align: center; }
.kicker { color: var(--t-tertiary); font-size: clamp(13px,1.6vw,15px); }

.btn { display: inline-flex; align-items: center; gap: 8px; padding: 13px 26px; border-radius: 999px; font-weight:500; font-size: 16px; background: var(--t-primary); color: var(--bg-base); transition: transform 140ms ease, opacity 140ms ease; }
.btn:hover { transform: translateY(-1px); opacity: .92; }
.btn.ghost { background: transparent; color: var(--t-primary); box-shadow: inset 0 0 0 1px var(--hairline-strong); }
.btn.sm { padding: 9px 18px; font-size: 14px; }

.reveal { opacity: 0; transform: translateY(28px); transition: opacity 900ms cubic-bezier(.2,.7,.2,1), transform 900ms cubic-bezier(.2,.7,.2,1); }
.reveal.in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 90ms; } .reveal.d2 { transition-delay: 180ms; } .reveal.d3 { transition-delay: 270ms; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } }

/* section headers + feature layout */
.sec-head { max-width: 720px; margin-bottom: clamp(36px,6vw,64px); }
.sec-head.center { margin-inline: auto; text-align: center; }
.sec-head .lead { margin-top: 18px; } .sec-head.center .lead { margin-inline: auto; }
.feat { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px,5vw,80px); align-items: center; }
.feat.rev .feat-copy { order: 2; }
.feat-media { display: flex; justify-content: center; min-width: 0; }
/* tablet: two-column feature rows go single-column (aligned to the site's
   ~992 tablet breakpoint so the page reflows in sync with the WP theme). */
@media (max-width: 992px) { .feat { grid-template-columns: 1fr; } .feat-copy, .feat.rev .feat-copy { order: -1; text-align: center; } .feat-copy .lead { margin-inline: auto; } .feat-media { order: 0; } }

/* Oura-inspired Air section: warm photo backdrop, glass panels, and faithful
   in-loco air tiles floating over the room. */
.warm-photo-sec { isolation:isolate; }
.warm-photo-sec > .wrap { position:relative; z-index:2; }
.warm-photo-sec::before { content:''; position:absolute; inset:-1px; z-index:0; pointer-events:none;
  background-image:var(--warm-photo); background-size:var(--warm-size,cover); background-position:var(--warm-pos,center); background-repeat:var(--warm-repeat,no-repeat);
  opacity:var(--warm-opacity,.18); transform:scale(1.02); animation:warmDrift 18s ease-in-out infinite alternate; }
.warm-photo-sec::after { content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:var(--warm-film,linear-gradient(90deg,var(--bg-base) 0%,color-mix(in srgb,var(--bg-base) 86%,transparent) 42%,color-mix(in srgb,var(--bg-base) 54%,transparent) 100%)); }
.warm-photo-sec.t-light::after {
  background:var(--warm-film,linear-gradient(90deg,rgba(244,243,239,.98) 0%,rgba(244,243,239,.90) 46%,rgba(244,243,239,.52) 100%));
}
.warm-photo-sec .air-tiles .tile,
.warm-photo-sec .ai-card,
.warm-photo-sec .macro-comp,
.warm-photo-sec .apply-comp { backdrop-filter:blur(14px); }
.air-warm .air-tiles { position:relative; z-index:2; width:fit-content; max-width:100%; margin-inline:auto;
  display:grid; grid-template-columns:repeat(2,max-content); column-gap:clamp(28px,6vw,72px); row-gap:clamp(20px,2.4vw,30px); justify-content:center; align-items:start;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; }
.air-warm .air-col { padding:clamp(18px,3vw,28px); border-radius:32px; background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.22); box-shadow:0 24px 70px rgba(76,60,42,.09); backdrop-filter:blur(8px); }
.air-warm .air-cap-group { display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap; }
.air-warm .air-cap-inline { margin-top:18px; padding-top:18px; border-top:1px solid rgba(0,0,0,.06); }
.air-warm .air-cap-label { flex:0 0 100%; text-align:center; font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--t-tertiary); margin-bottom:1px; }
.air-warm .air-cap { display:inline-flex; align-items:center; min-height:38px; padding:8px 14px; border-radius:999px; background:rgba(255,255,255,.56); border:1px solid rgba(0,0,0,.08); box-shadow:0 12px 30px rgba(55,45,34,.08); color:var(--t-secondary); font-size:13px; font-weight:700; white-space:nowrap; }
.air-warm .air-cap i { margin-right:8px; font-size:19px; color:var(--accent); }
.air-warm .air-story { width:min(360px,100%); margin:0 auto 16px; text-align:center; }
.air-warm .air-story strong { display:block; font-size:20px; line-height:1.15; font-weight:700; letter-spacing:-.01em; color:var(--t-primary); margin-bottom:7px; }
.air-warm .air-story p { max-width:32ch; margin:0 auto; font-size:14px; line-height:1.42; color:var(--t-secondary); }
.air-warm .air-scale { display:flex; justify-content:center; gap:8px 11px; flex-wrap:wrap; margin-top:11px; }
.air-warm .air-scale span { display:inline-flex; align-items:center; gap:6px; font-size:12px; line-height:1; font-weight:700; color:var(--t-tertiary); white-space:nowrap; animation:airPalettePulse 3.6s ease-in-out infinite; animation-delay:var(--d,0s); }
.air-warm .air-scale i { width:14px; height:14px; border-radius:4px; flex:0 0 14px; background:var(--sw); border:1px solid color-mix(in srgb,var(--sw) 65%,rgba(0,0,0,.18)); transition:box-shadow .3s ease, transform .3s ease; }
.air-warm .air-scale .sw-normal { background:#fff; border-color:rgba(0,0,0,.22); }

.air-warm .air-scale span i { animation:airSwatchPulse 3.6s ease-in-out infinite; animation-delay:var(--d,0s); }


@media (prefers-reduced-motion: reduce) { .warm-photo-sec::before { animation:none; } }
@media (max-width: 992px) { .warm-photo-sec::before { opacity:var(--warm-opacity,.18); } }
@media (max-width: 1120px) {
  .air-warm .air-tiles { width:min(526px,100%); box-sizing:border-box; grid-template-columns:minmax(0,1fr); }
  .air-warm .air-col { width:100%; box-sizing:border-box; }
}
@media (max-width: 768px) {
  .air-warm .air-col { padding:14px; border-radius:26px; }
}
.ai-warm { background:
  radial-gradient(58% 70% at 10% 72%, color-mix(in srgb,#d9824f 18%,transparent) 0%, transparent 62%),
  radial-gradient(72% 78% at 86% 18%, color-mix(in srgb,var(--accent-ai) 18%,transparent) 0%, transparent 60%),
  #0d0d0f; }
.ai-warm::before { animation:none; transform:none; }
.ai-warm .ai-card { background:rgba(17,18,22,.68); border-color:rgba(255,255,255,.14); box-shadow:0 34px 90px rgba(0,0,0,.46); }
.ai-life-card { width:min(335px,88vw); margin-top:18px; overflow:hidden; border-radius:24px;
  background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.12); box-shadow:0 22px 56px rgba(0,0,0,.34); }
.ai-life-card img { width:100%; height:150px; object-fit:cover; object-position:center; opacity:.94; }
.ai-life-card figcaption { padding:12px 15px 14px; color:rgba(236,237,242,.74); font-size:13px; line-height:1.42; }

/* real-screenshot staging (natural size on the section surface) */
.shot { height: auto; }
.tile-shot { width: 370px; max-width: 100%; height: auto; }
/* tiles are captured as clean opaque squares (no baked shadow); round + shadow
   here in CSS so the corners are always crisp and the shadow never clips. */
.sq-shot { width: 186px; height: auto; border-radius: 22px; box-shadow: 0 10px 30px rgba(40,35,30,.12); }
.t-light .sq-shot { box-shadow: 0 10px 28px rgba(40,35,30,.10); }

/* ---- Air tiles: faithful in-loco VOC + Humidity ports (tokens/layout/segbar/
   L2 halo pulled 1:1 from the engine components); halo breathes the real
   --l2-amount live. Inter (app font) subset for exact match. ---- */
@font-face { font-family:'Inter'; font-style:normal; font-weight:100 900; font-display:swap; src:url('https://messana.tech/controls/wp-content/uploads/sites/4/2026/07/4f6d0fcc.woff2') format('woff2'); }
@property --l2a { syntax:'<percentage>'; inherits:false; initial-value:9%; }
.air-tiles { display:flex; justify-content:center; gap:clamp(28px,6vw,72px); flex-wrap:wrap;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:26,28,36;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.72); --t-tertiary:rgba(var(--ink-rgb),0.52);
  --tile-bg:linear-gradient(180deg,rgba(0,0,0,0.022) 0%,rgba(0,0,0,0.038) 100%);
  --tile-border-color:rgba(0,0,0,0.055);
  --tile-shadow:inset 0 1px 0 rgba(255,255,255,0.50),0 1px 3px rgba(0,0,0,0.06),0 6px 16px rgba(0,0,0,0.07);
  --hairline-strong:rgba(0,0,0,0.24); --surface-sunken:rgba(0,0,0,0.095); --tile-radius:24px;
  --voc-excellent:#5DA8A6; --voc-good:#4F8C5E; --voc-moderate:#B5972E; --voc-elevated:#C25E54;
  --hum-low:#6F7682; --hum-normal:#2A2D36; --hum-optimal:#6E5BB8; --hum-high:#C84676; }
.air-col { text-align:center; }
.air-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; justify-items:center; }
.air-tiles .tile { position:relative; width:186px; height:186px; padding:20px 18px; border:0;
  border-radius:var(--tile-radius); overflow:hidden; display:flex; flex-direction:column;
  box-shadow:inset 0 0 0 1px var(--tile-border-color),var(--tile-shadow);
  background:radial-gradient(ellipse 60% 60% at var(--pos), color-mix(in srgb, var(--accent-l2) var(--l2a), transparent) 0%, transparent 76%), var(--tile-bg);
  animation:airBreathe 3.6s ease-in-out infinite; animation-delay:var(--d,0s); }

.air-tiles .tile::before { content:''; position:absolute; top:0; left:12%; right:12%; height:1px;
  background:linear-gradient(90deg,transparent,var(--hairline-strong),transparent); pointer-events:none; }
.air-tiles .tile-head { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; text-align:left; }
.air-tiles .tile-name { font-size:22px; font-weight:500; color:var(--t-secondary); letter-spacing:0.1px; line-height:1; white-space:nowrap; }
.air-tiles .tile-verdict { font-size:24px; font-weight:600; letter-spacing:-0.3px; line-height:1.05; white-space:nowrap; color:var(--accent); }
.air-tiles .tile-body { flex:0 1 auto; min-height:0; text-align:left; }
.air-tiles .voc-number { display:block; font-size:38px; font-weight:500; letter-spacing:-1px; line-height:1; color:var(--t-primary); font-variant-numeric:tabular-nums; }
.air-tiles .voc-number::after { content:' / 500'; font-size:22px; font-weight:500; color:var(--t-tertiary); letter-spacing:-0.4px; margin-left:2px; }
.air-tiles .hum-body { display:flex; align-items:baseline; color:var(--t-primary); font-variant-numeric:tabular-nums; line-height:1; font-weight:500; letter-spacing:-1px; }
.air-tiles .hum-int { font-size:38px; }
.air-tiles .hum-dec { font-size:24px; font-weight:500; color:var(--t-secondary); letter-spacing:-0.6px; margin-left:1px; }
.air-tiles .hum-unit { font-size:22px; font-weight:500; color:var(--t-secondary); margin-left:3px; letter-spacing:-0.4px; }
.air-tiles .tile-footer { flex:0 0 auto; margin-top:auto; text-align:left; }
.air-tiles .hum-footer { display:block; font-size:17px; font-weight:500; color:var(--t-secondary); line-height:1; margin-bottom:6px; text-transform:uppercase; letter-spacing:0.5px; white-space:nowrap; }
.air-tiles .segbar { position:relative; width:100%; height:8px; display:grid; grid-auto-flow:column; gap:4px; }
.air-tiles .segbar .seg { background:var(--surface-sunken); border-radius:3px; height:100%; }
.air-tiles .segbar .seg.on { background:var(--accent); box-shadow:0 0 6px var(--accent); }
.air-tiles .voc-segbar { grid-template-columns:30fr 25fr 20fr 25fr; }
.air-tiles .hum-segbar { grid-template-columns:repeat(5,1fr); }
.air-tiles .seglabels { position:relative; height:12px; margin-top:4px; font-size:10px; line-height:12px; color:var(--t-tertiary); font-variant-numeric:tabular-nums; }
.air-tiles .seglabels span { position:absolute; top:0; transform:translateX(-50%); }
.air-tiles .voc-seglabels span:nth-child(1){ left:0; transform:translateX(0); }
.air-tiles .voc-seglabels span:nth-child(2){ left:30%; }
.air-tiles .voc-seglabels span:nth-child(3){ left:55%; }
.air-tiles .voc-seglabels span:nth-child(4){ left:75%; }
.air-tiles .voc-seglabels span:nth-child(5){ left:100%; transform:translateX(-100%); }
.air-tiles .hum-seglabels span:nth-child(1){ left:20%; }
.air-tiles .hum-seglabels span:nth-child(2){ left:40%; }
.air-tiles .hum-seglabels span:nth-child(3){ left:60%; }
.air-tiles .hum-seglabels span:nth-child(4){ left:80%; }
@media (prefers-reduced-motion: reduce) { .air-tiles .tile { animation:none; --l2a:15%; } }
.air-single-demo .air-tiles { grid-template-columns:repeat(2,minmax(300px,1fr)); width:min(860px,calc(100% - 32px)); gap:clamp(22px,3vw,44px); }
.air-single-demo .air-col { display:flex; flex-direction:column; align-items:center; }
.air-single-demo .air-grid { position:relative; display:block; width:232px; height:232px; margin:4px auto 0; }
.air-single-demo .air-grid .tile { position:absolute; left:50%; top:50%; width:186px; height:186px; opacity:0; pointer-events:none;
  transform:translate(-50%,-45%) scale(1.16); transform-origin:center; animation:none; --l2a:0%;
  transition:opacity .55s ease, transform .55s cubic-bezier(.2,.75,.2,1), --l2a .55s ease; }
.air-single-demo .air-grid .tile.is-active { opacity:1; transform:translate(-50%,-50%) scale(1.16); --l2a:28%; animation:airBreathe 3.6s ease-in-out infinite; }
.air-single-demo .air-scale span,
.air-single-demo .air-scale span i { animation:none; transition:color .35s ease, box-shadow .35s ease, transform .35s ease; }
.air-single-demo .air-scale span.is-active { color:var(--t-primary); }
.air-single-demo .air-scale span.is-active i { box-shadow:0 0 14px var(--sw); transform:scale(1.2); }
@media (max-width: 1120px) { .air-single-demo .air-tiles { width:min(480px,calc(100% - 24px)); grid-template-columns:minmax(0,1fr); } }
@media (max-width: 480px) { .air-single-demo .air-tiles { width:min(340px,calc(100% - 18px)); } .air-single-demo .air-grid { width:220px; height:220px; } .air-single-demo .air-grid .tile { transform:translate(-50%,-45%) scale(1.08); } .air-single-demo .air-grid .tile.is-active { transform:translate(-50%,-50%) scale(1.08); } }

/* ==== Schedules, four moments · in-loco animated schedule tiles ============
   Faithful in-loco rebuild of the real `schedule` component (engine
   components/schedule + the shared @mixin schedule-section): control row
   (profile name + live status + on/off toggle), the two AM/PM mini-timelines
   with coloured .seg runs + a sweeping now-dot, and the temperature legend.
   Rebuilt in HTML/CSS (not a screenshot) so a shared day-clock can ANIMATE it:
   the dot sweeps the day and each tile's live state follows its own segments.
   Each tile is a translucent dark-glass card that overlays a lifestyle photo. */
.sched-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px; }
.sched-moment { position:relative; min-height:clamp(440px,52vw,540px); overflow:hidden;
  border-radius:28px; background:#17191e; box-shadow:0 24px 64px rgba(0,0,0,.16); isolation:isolate; }
/* overscan the photo 1px on every side so object-fit:cover never leaves a
   sub-pixel hairline on the right/bottom at fractional browser-zoom levels
   (the "picture not big enough" gap near the 2-col->1-col breakpoint). */
.sched-moment > img { position:absolute; top:-1px; left:-1px; width:calc(100% + 2px); height:calc(100% + 2px); max-width:none; object-fit:cover;
  transition:transform 1200ms cubic-bezier(.2,.75,.2,1); }
.sched-moment:hover > img { transform:scale(1.03); }
.sched-moment::after { content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg,rgba(13,15,19,.40) 0%,rgba(13,15,19,.04) 30%,rgba(13,15,19,.20) 56%,rgba(13,15,19,.60) 100%); }
.sched-moment:nth-child(1) > img { object-position:18% center; }
.sched-moment:nth-child(2) > img { object-position:38% center; }
.sched-moment:nth-child(3) > img { object-position:52% center; }
.sched-moment:nth-child(4) > img { object-position:54% center; }
.sched-moment-copy { position:absolute; top:22px; left:24px; right:24px; z-index:3; color:#fff; }
.sched-moment-copy span { display:inline-flex; padding:12px 22px; border-radius:999px;
  background:rgba(18,20,25,.24); box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);
  backdrop-filter:blur(20px) saturate(1.1); -webkit-backdrop-filter:blur(20px) saturate(1.1);
  font-size:13px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; }
.sched-moment-copy strong { display:block; margin-top:12px; max-width:15ch;
  font-size:clamp(22px,2.5vw,30px); line-height:1.06; letter-spacing:-.02em; text-shadow:0 2px 20px rgba(0,0,0,.36); }

/* the tile — its own dark token context (light ink) + the real schedule palette
   tokens, so the faithful component styling resolves exactly as in the app. */
.sched-tile { position:absolute; left:22px; right:22px; bottom:22px; z-index:3;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.62); --t-tertiary:rgba(var(--ink-rgb),0.42);
  --surface-sunken:rgba(255,255,255,0.11); --hairline:rgba(255,255,255,0.10);
  --accent-eco:#6FA67C; --accent-heat:#D9824F; --accent-cool:#5E92C4; --accent-off:#7E828C;
  --segbar-dot-glow:rgba(0,0,0,0.55);
  --schedule-var-1:#C8F2D8; --schedule-var-2:#98E06A; --schedule-var-3:#1ABF45; --schedule-var-4:#0A7C54; --schedule-var-5:#04401E;
  --schedule-heat-1:#F5DFA0; --schedule-heat-2:#EAC45A; --schedule-heat-3:#E8A030; --schedule-heat-4:#C87020; --schedule-heat-5:#8C4010;
  --schedule-cool-1:#B8DCF8; --schedule-cool-2:#78B8F0; --schedule-cool-3:#5AA8F0; --schedule-cool-4:#2E6EC8; --schedule-cool-5:#1A3E90;
  --accent:var(--accent-eco);
  padding:15px 16px 14px; border-radius:20px;
  background:rgba(18,20,25,.24); backdrop-filter:blur(32px) saturate(1.08); -webkit-backdrop-filter:blur(32px) saturate(1.08);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09), 0 20px 46px rgba(0,0,0,.36); }
/* control row */
.sched-ctrl { display:flex; align-items:center; gap:9px; }
.sched-name { flex:1; min-width:0; font-size:15px; font-weight:500; color:var(--t-primary);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; letter-spacing:-.1px; line-height:1.3; }
.sched-status { flex:none; font-size:11.5px; font-weight:600; letter-spacing:.2px; padding:3px 9px;
  border-radius:8px; background:color-mix(in srgb,var(--accent) 20%,transparent); color:var(--accent);
  font-variant-numeric:tabular-nums; white-space:nowrap; transition:color .45s ease, background .45s ease; }
/* dual deadband readout — sits in the normal accent pill like every other tile;
   ONLY the arrows carry colour: orange up = heat setpoint, blue down = cool
   setpoint (the app's "keep the room between the two" convention). */
.sched-status .sp { font-weight:600; }
.sched-status .sp + .sp { margin-left:9px; }
.sched-status .ar-up { color:var(--accent-heat); }
.sched-status .ar-dn { color:var(--accent-cool); }
.sched-toggle { flex:none; width:44px; height:26px; border-radius:13px; background:var(--surface-sunken); position:relative; }
.sched-toggle.on { background:var(--accent); transition:background .45s ease; }
.sched-toggle .knob { position:absolute; top:2px; left:2px; width:22px; height:22px; border-radius:50%;
  background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.35); transition:transform .3s ease; }
.sched-toggle.on .knob { transform:translateX(18px); }
/* timelines */
.sched-tl { display:flex; flex-direction:column; gap:8px; padding-top:11px; }
.sched-mode { font-size:10px; font-weight:700; letter-spacing:.7px; text-transform:uppercase; color:var(--t-tertiary); }
/* dual: the channel label + its temperature legend share one compact row, so
   the two channels stack tighter and the tile is shorter. */
.sched-modehead { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.sched-modehead.ch2 { margin-top:4px; }
.sched-modehead.solo { justify-content:flex-end; }
.sched-modehead .sched-legend { padding:0; gap:10px; }
/* reserve the header-row height on the headerless tiles (on/off, season) so
   their first bar lines up with the variable/dual tiles that carry a legend. */
.sched-headpad { height:12px; flex:none; }
.sched-tl-row { position:relative; display:flex; flex-direction:column; gap:3px; }
.sched-bar { position:relative; height:8px; background:var(--surface-sunken); border-radius:3px; overflow:hidden; }
.sched-bar .seg { position:absolute; top:0; height:100%; border-radius:3px; background:var(--accent); }
.sched-labels { position:relative; height:12px; font-size:9px; line-height:12px; color:var(--t-tertiary); font-variant-numeric:tabular-nums; }
.sched-labels span { position:absolute; top:0; transform:translateX(-50%); }
.sched-labels span:nth-child(1){ left:0; transform:translateX(0); }
.sched-labels span:nth-child(2){ left:8.333%; } .sched-labels span:nth-child(3){ left:16.667%; }
.sched-labels span:nth-child(4){ left:25%; } .sched-labels span:nth-child(5){ left:33.333%; }
.sched-labels span:nth-child(6){ left:41.667%; } .sched-labels span:nth-child(7){ left:50%; }
.sched-labels span:nth-child(8){ left:58.333%; } .sched-labels span:nth-child(9){ left:66.667%; }
.sched-labels span:nth-child(10){ left:75%; } .sched-labels span:nth-child(11){ left:83.333%; }
.sched-labels span:nth-child(12){ left:91.667%; } .sched-labels span:nth-child(13){ left:100%; transform:translateX(-100%); }
.sched-dot { position:absolute; top:4px; transform:translate(-50%,-50%); width:11px; height:11px; border-radius:50%;
  background:var(--t-primary); box-shadow:0 0 8px var(--segbar-dot-glow); z-index:2; display:none; transition:left .12s linear; }
.sched-dot.show { display:block; }
.sched-legend { display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:11px; padding:9px 2px 1px; }
.sched-legend .li { display:inline-flex; align-items:center; gap:5px; }
.sched-legend .dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.sched-legend .v { font-size:10px; color:var(--t-secondary); font-variant-numeric:tabular-nums; letter-spacing:.2px; }
@media (max-width:768px){ .sched-grid { grid-template-columns:1fr; } }
@media (prefers-reduced-motion: reduce){ .sched-moment:hover > img { transform:none; } .sched-dot { transition:none; } }

/* ---- Convective integration tile: faithful in-loco rebuild of the app's CI
   card (dark). Reuses the schedule toggle/timeline/legend + palette tokens so it
   resolves 1:1. Built in-loco (not a screenshot) so the fan can spin and the air
   intensity can modulate live — "radiant leads, air only closes the gap". ---- */
.ci-tile { width:392px; max-width:92vw; box-sizing:border-box;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.62); --t-tertiary:rgba(var(--ink-rgb),0.42);
  --surface-sunken:rgba(255,255,255,0.09); --hairline:rgba(255,255,255,0.09);
  --accent-eco:#6FA67C; --accent-cool:#5E92C4; --accent-off:#7E828C; --accent:var(--accent-off); --l2a:0%;
  --segbar-dot-glow:rgba(0,0,0,0.55); --schedule-cool-3:#5AA8F0;
  padding:17px 19px 15px; border-radius:21px; color:var(--t-primary); position:relative; isolation:isolate;
  background:
    radial-gradient(150% 120% at 12% 0%, color-mix(in srgb, var(--accent-cool) var(--l2a), transparent) 0%, transparent 60%),
    linear-gradient(180deg,rgba(255,255,255,.028),rgba(255,255,255,.012)), #14161b;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07), 0 20px 50px rgba(0,0,0,.4);
  transition:box-shadow .5s ease, --l2a .5s ease; }
/* ACTIVE (dot over the cooling band): blue accent + blue L2 halo + fan spinning.
   Idle: grey accent, no halo, fan still. Mirrors the app's integ state machine. */
.ci-tile.run { --accent:var(--accent-cool); --l2a:15%;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent-cool) 22%,transparent), 0 20px 50px rgba(0,0,0,.4), 0 0 30px color-mix(in srgb,var(--accent-cool) 20%,transparent); }
.ci-tile .sched-toggle.on { background:var(--accent-eco); }   /* master/sub toggles stay green (enabled) */
.ci-head { display:flex; align-items:center; gap:11px; margin-bottom:12px; }
.ci-fan { font-size:19px; color:var(--accent); line-height:1; transform-origin:50% 50%; will-change:transform; transition:color .5s ease; }
.ci-tile.run .ci-fan { animation:integFanSpin 2s linear infinite; }

.ci-title { flex:1; font-size:16px; font-weight:500; color:var(--t-secondary); letter-spacing:-.2px; }
.ci-chev { font-size:15px; color:var(--t-tertiary); line-height:1; }
.ci-row { display:flex; align-items:center; gap:11px; min-height:33px; }
.ci-div { height:1px; background:var(--hairline); }
.ci-pill { font-size:12px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--accent);
  padding:5px 13px; border-radius:999px; box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent) 50%,transparent);
  background:color-mix(in srgb,var(--accent) 12%,transparent); transition:color .5s ease, box-shadow .5s ease, background .5s ease; }
.ci-spacer { flex:1; }
/* same size/shape as the state pill — just neutral (no accent) */
.ci-set { margin-left:9px; font-size:12px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--t-secondary);
  font-variant-numeric:tabular-nums; padding:5px 13px; border-radius:999px; box-shadow:inset 0 0 0 1px var(--hairline); }
.ci-label { flex:1; font-size:15px; font-weight:400; color:var(--t-secondary); letter-spacing:-.1px; }
.ci-step { display:inline-flex; align-items:center; gap:12px; }
.ci-step button { width:27px; height:27px; border-radius:50%; background:var(--surface-sunken); color:var(--t-secondary);
  font-size:17px; line-height:1; border:0; display:inline-flex; align-items:center; justify-content:center; }
.ci-val { min-width:24px; text-align:center; font-size:16px; font-weight:700; color:var(--t-primary); font-variant-numeric:tabular-nums; }
.ci-sub { flex:1; font-size:16px; font-weight:600; color:var(--t-primary); letter-spacing:-.2px; display:inline-flex; align-items:center; gap:8px; }
.ci-caret { color:var(--t-tertiary); font-size:13px; }
.ci-tl { display:flex; flex-direction:column; gap:6px; margin-top:13px; }
.ci-foot { margin-top:13px; font-size:12.5px; line-height:1.42; color:var(--t-tertiary); }
.ci-tile .sched-dot.ci-dot { transition:none; display:block; opacity:0; }
.ci-tile .sched-dot.ci-dot.on { opacity:1; }
.ci-tile.run .sched-dot.ci-dot.on { box-shadow:0 0 10px color-mix(in srgb,var(--accent-cool) 70%,transparent); }
@media (prefers-reduced-motion: reduce){ .ci-tile.run .ci-fan { animation:none; } }

/* subtle blue section halo behind the CI tile (like #override's cinema glow,
   but barely-there) — reinforces the "cool/air" read without adding colour weight */
#rbm-integration { background:
  radial-gradient(58% 48% at 34% 40%, color-mix(in srgb,var(--accent-cool) 7%, transparent) 0%, transparent 62%),
  var(--bg-base); }
/* mobile: keep the controls list left-aligned (the global .feat-copy centring
   makes the wrapped bullet descriptions read as ragged/centred) */
@media (max-width:992px){ #rbm-integration .feat-copy { text-align:left; } }

/* ---- Floor warmer tile: faithful in-loco rebuild of the app's
   floor-warmer-tile (dark). Header = sun-haze glyph + "Floor warmer" + power
   toggle; body = Floor temperature (read-only) + Setpoint (+/- steppers, real
   22px .stepper-btn spec); then the shared schedule sub-block (the engine's
   @mixin schedule-section scaffold, same classes the schedule tiles reuse),
   pinned accentMode=season season=heating: amber bars while the schedule is
   on. Rebuilt in-loco (not a screenshot) so the floor reading can ease toward
   the setpoint and the day dot can sweep. Mirrors the app's 3-state accent
   machine (fw-off / fw-enabled=idle slate / fw-active-now=heat amber + L2
   halo). Dark-glass card like .sched-tile so the two sections read as one. */
.fw-tile { width:392px; max-width:92vw; box-sizing:border-box; text-align:left;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.62); --t-tertiary:rgba(var(--ink-rgb),0.42);
  --surface-sunken:rgba(255,255,255,0.11); --hairline:rgba(255,255,255,0.10);
  --accent-heat:#D9824F; --accent-idle:#8C909B; --accent-eco:#6FA67C; --accent-off:#7E828C;
  --segbar-dot-glow:rgba(0,0,0,0.55);
  --accent:var(--accent-idle);
  padding:17px 19px 15px; border-radius:21px; color:var(--t-primary); position:relative; isolation:isolate;
  background:rgba(18,20,25,.30); backdrop-filter:blur(32px) saturate(1.08); -webkit-backdrop-filter:blur(32px) saturate(1.08);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09), 0 20px 46px rgba(0,0,0,.36);
  transition:box-shadow .8s ease; }
/* the amber L2 halo (corner-anchored, like the app's tile-shell radial) fades
   in as an overlay so the active state breathes on smoothly */
.fw-tile::before { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none; z-index:0;
  background:radial-gradient(150% 120% at 12% 0%, color-mix(in srgb,var(--accent-heat) 14%,transparent) 0%, transparent 60%);
  opacity:0; transition:opacity .8s ease; }
.fw-tile > * { position:relative; z-index:1; }
/* ACTIVE (dot inside an amber run): heat accent + halo + warm edge. Standby:
   idle slate accent, no halo. Same machine as the real .fw-enabled states. */
.fw-tile.on { --accent:var(--accent-heat);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent-heat) 22%,transparent), 0 20px 46px rgba(0,0,0,.36), 0 0 30px color-mix(in srgb,var(--accent-heat) 16%,transparent); }
.fw-tile.on::before { opacity:1; }
.fw-head { display:flex; align-items:center; gap:11px; padding-bottom:9px; }
.fw-ic { font-size:20px; color:var(--accent); line-height:1; flex-shrink:0; transition:color .8s ease, text-shadow .8s ease; }
.fw-tile.on .fw-ic { text-shadow:0 0 10px color-mix(in srgb,var(--accent-heat) 50%,transparent); }
.fw-title { flex:1; min-width:0; font-size:16px; font-weight:500; color:var(--t-secondary); letter-spacing:-.2px; }
.fw-tile .sched-toggle.on { background:var(--accent-eco); }   /* toggles read "enabled" green, like the CI tile */
.fw-row { display:flex; align-items:center; justify-content:space-between; gap:11px; padding:12px 0; }
.fw-row + .fw-row { border-top:1px solid var(--hairline); }
.fw-label { flex:1; font-size:15px; font-weight:400; color:var(--t-secondary); letter-spacing:-.1px; }
.fw-val { font-size:16px; font-weight:600; color:var(--t-primary); font-variant-numeric:tabular-nums; }
.fw-step { display:inline-flex; align-items:center; gap:8px; flex-shrink:0; }
.fw-step button { width:22px; height:22px; border-radius:50%; background:var(--surface-sunken); border:1px solid var(--hairline);
  color:var(--t-secondary); display:inline-flex; align-items:center; justify-content:center; padding:0; cursor:pointer; }
.fw-step button i { font-size:10px; line-height:1; }
.fw-ctr { min-width:36px; text-align:center; font-size:16px; font-weight:600; color:var(--t-primary); font-variant-numeric:tabular-nums; }
/* schedule sub-block: hairline above (the tile-specific `schedule` border the
   real component adds), selector row (profile name + caret + live status +
   sub-toggle), then the shared AM/PM timelines + sweeping dot */
.fw-sched { border-top:1px solid var(--hairline); margin-top:1px; }
.fw-sched-row { display:flex; align-items:center; gap:9px; padding:11px 0 9px; }
.fw-sched-name { flex:1; min-width:0; display:inline-flex; align-items:center; gap:6px; font-size:15px; font-weight:500; color:var(--t-primary);
  letter-spacing:-.1px; line-height:1.3; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.fw-caret { color:var(--t-tertiary); font-size:13px; line-height:1; }
.fw-tl { display:flex; flex-direction:column; gap:8px; padding:4px 0 2px; }
@media (prefers-reduced-motion: reduce){ .fw-tile, .fw-tile::before, .fw-ic { transition:none; } }

/* subtle amber section halo behind the floor-warmer tile (the #rbm-integration
   pattern, warm side) — reinforces "heat underfoot" without colour weight */
#rbm-floor-warmer { background:
  radial-gradient(58% 48% at 34% 42%, color-mix(in srgb,var(--accent-heat) 7%, transparent) 0%, transparent 62%),
  var(--bg-base); }
@media (max-width:992px){ #rbm-floor-warmer .feat-copy { text-align:left; } }

/* ---- Timer tile: faithful in-loco rebuild of the app's timer-tile.component
   (dark) — the towel & bathrobe warmer (RBM MORE PAD HV). Header (timer glyph
   + name + toggle), the real override row (four 48-64px duration circles,
   value 16px / MIN 9px, 2px rings, active fills the accent) with the
   remaining-time arc orbiting OUTSIDE the active button (r=48 in a 100×100
   viewBox inflated -7px past the button, hairline-strong track + depleting
   70/30-black accent stroke, circumference 301.59), the 3-state hint, then
   the shared schedule sub-block (reuses the .fw-sched scaffold). Rebuilt
   in-loco (not the old screen capture) so the demo can tap a duration and
   run the countdown. State machine mirrored: tt-enabled = idle slate;
   tt-firing + tt-heat (.run here) = heat amber + L2 halo + warm edge;
   while firing the other buttons read disabled (faded ring), the app's
   faded → outlined → filled ramp. ---- */
.tt-tile { width:392px; max-width:92vw; box-sizing:border-box; text-align:left;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.62); --t-tertiary:rgba(var(--ink-rgb),0.42); --t-quaternary:rgba(var(--ink-rgb),0.25);
  --surface-sunken:rgba(255,255,255,0.09); --hairline:rgba(255,255,255,0.09); --hairline-strong:rgba(255,255,255,0.17);
  --accent-heat:#D9824F; --accent-idle:#8C909B; --accent-eco:#6FA67C; --accent-off:#7E828C;
  --segbar-dot-glow:rgba(0,0,0,0.55);
  --accent:var(--accent-idle); --l2a:0%;
  padding:17px 19px 15px; border-radius:21px; color:var(--t-primary); position:relative; isolation:isolate;
  background:
    radial-gradient(150% 120% at 12% 0%, color-mix(in srgb, var(--accent-heat) var(--l2a), transparent) 0%, transparent 60%),
    linear-gradient(180deg,rgba(255,255,255,.028),rgba(255,255,255,.012)), #14161b;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07), 0 20px 50px rgba(0,0,0,.4);
  transition:box-shadow .6s ease, --l2a .6s ease; }
/* FIRING (override running): heat accent + halo + warm edge, like fw-tile.on */
.tt-tile.run { --accent:var(--accent-heat); --l2a:14%;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent-heat) 22%,transparent), 0 20px 50px rgba(0,0,0,.4), 0 0 30px color-mix(in srgb,var(--accent-heat) 16%,transparent); }
.tt-head { display:flex; align-items:center; gap:11px; padding-bottom:5px; }
.tt-ic { font-size:20px; color:var(--accent); line-height:1; flex-shrink:0; transition:color .6s ease, text-shadow .6s ease; }
.tt-tile.run .tt-ic { text-shadow:0 0 10px color-mix(in srgb,var(--accent-heat) 50%,transparent); }
.tt-title { flex:1; min-width:0; font-size:16px; font-weight:500; color:var(--t-secondary); letter-spacing:-.2px; }
.tt-tile .sched-toggle.on { background:var(--accent-eco); }   /* toggles read "enabled" green, like the CI/FW tiles */
.tt-ovr { display:flex; flex-direction:column; gap:10px; padding:10px 0 14px; }
.tt-row { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.tt-btn { flex:1 1 0; aspect-ratio:1; max-width:64px; min-width:48px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px;
  border:2px solid var(--t-secondary); border-radius:50%; background:transparent; color:var(--t-primary); padding:0; position:relative;
  transition:background .2s ease, border-color .2s ease, color .2s ease, transform .1s ease; }
.tt-btn.press { transform:scale(.95); }
.tt-btn.active { background:var(--accent); border-color:var(--accent); color:#fff; }
/* output already ON: the other durations lock (faint ring, faded value) */
.tt-tile.run .tt-btn:not(.active) { border-color:var(--hairline); color:var(--t-quaternary); }
.tt-v { font-size:16px; font-weight:600; line-height:1; }
.tt-u { font-size:9px; font-weight:500; line-height:1; color:inherit; opacity:.75; text-transform:uppercase; letter-spacing:.3px; }
/* the ring box is EXACTLY the real tile's computed geometry (measured on the
   running rig: button 64×64, svg 74×74 concentric → ring radius 35.5px,
   stroke 4.44px, ~1.3px outside the button). Fixed px + explicit centering,
   NOT inset/calc(%): percentages resolve against the padding box and made
   the ring drift off-center in some engines. The buttons are effectively
   always at their 64px cap (the 48px floor only binds below ~275px vw). */
.tt-arc-svg { position:absolute; left:50%; top:50%; width:74px; height:74px; max-width:none; margin:-37px 0 0 -37px; transform:rotate(-90deg); pointer-events:none; overflow:visible; z-index:1; }
/* ^ max-width:none is LOAD-BEARING: the page reset puts max-width:100% on
   every svg, which clamped this ring to the button's 60px padding box and
   skewed it off-center (the misaligned dark disc bug). */
.tt-arc-svg circle { fill:none; stroke-width:6; stroke-linecap:butt; }
.tt-arc-track { stroke:var(--hairline-strong); }
.tt-arc { stroke:color-mix(in srgb, var(--accent) 70%, black); stroke-dasharray:301.59; }
/* about to expire (remaining ≤ 5%): the arc pulses, as in the app */

.tt-tile.expiring .tt-btn.active .tt-arc { animation:ttArcPulse 1.1s ease-in-out infinite; }
/* 12px = the real --tile-meta-size (min(0.75rem,15px)), probed on the rig —
   at 12px the OFF text fits one line exactly like the real tile. Two lines
   stay RESERVED anyway (min-height = 2 × 1.3 line-height, centered) so the
   tile never changes height when the hint swaps or wraps on narrow screens. */
.tt-hint { margin:0; font-size:12px; color:var(--t-tertiary); text-align:center; line-height:1.3; min-height:32px; align-content:center; }
.tt-hint b { color:var(--t-secondary); font-weight:600; }
@media (prefers-reduced-motion: reduce){ .tt-tile, .tt-ic { transition:none; } .tt-tile.expiring .tt-btn.active .tt-arc { animation:none; } }

/* subtle amber section halo behind the timer tile (the #rbm-floor-warmer pattern) */
#rbm-timers { background:
  radial-gradient(58% 48% at 34% 42%, color-mix(in srgb,var(--accent-heat) 7%, transparent) 0%, transparent 62%),
  var(--bg-base); }
@media (max-width:992px){ #rbm-timers .feat-copy { text-align:left; } }

/* ---- WIDE zone-card: faithful in-loco port of the app's horizontal zone-card
   (dark). Tokens/stripe/left-wash/L2 halo mirror the .zsq port 1:1. Accent is
   per-card (--accent / --accent-l2), so one build carries every state colour.
   The halo breathes (airBreathe on --l2a) so the accent pulses live — the reason
   it is rebuilt in-loco, not a screenshot. Used stacked in the "colour" section,
   activated one at a time (.zc-stack below). ---- */
.zc-live { display:block;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.60); --t-tertiary:rgba(var(--ink-rgb),0.37);
  --tile-sheen:linear-gradient(180deg,rgba(255,255,255,0.030) 0%,rgba(255,255,255,0.014) 100%);
  --tile-border-color:rgba(255,255,255,0.06); --tile-radius:22px;
  --accent-heat:#D9824F; --accent-cool:#5E92C4; --accent-idle:#8C909B; --accent-eco:#6FA67C; --st-warn:#C89B3C;
  --accent:var(--accent-heat); --accent-l2:var(--accent-heat); --l2a:9%; }
.zc-live .zcard { position:relative; display:flex; align-items:center; gap:15px; width:100%; padding:15px 20px; overflow:hidden; border:0; border-radius:var(--tile-radius);
  box-shadow:inset 0 0 0 1px var(--tile-border-color), 0 20px 50px rgba(0,0,0,.40);
  background:
    radial-gradient(ellipse 78% 150% at 7% 42%, color-mix(in srgb, var(--accent-l2) var(--l2a), transparent) 0%, transparent 72%),
    var(--tile-sheen); }
.zc-live .zcard::before { content:''; position:absolute; top:0; bottom:0; left:0; width:2px; background:var(--accent); box-shadow:0 0 8px var(--accent); z-index:2; }
.zc-live .zcard::after { content:''; position:absolute; left:0; top:0; bottom:0; width:14%; pointer-events:none; opacity:.85;
  background:linear-gradient(90deg, color-mix(in srgb,var(--accent) 14%,transparent) 0%, color-mix(in srgb,var(--accent) 4%,transparent) 45%, transparent 100%); }
.zc-live .zcard > * { position:relative; z-index:1; }
.zc-live .zcard-icon { font-size:29px; width:32px; line-height:1; text-align:center; flex-shrink:0; color:var(--accent); }
.zc-live .zcard-text { display:flex; flex-direction:column; gap:3px; min-width:0; }
.zc-live .zcard-name { font-size:24px; font-weight:600; color:var(--t-primary); letter-spacing:-0.3px; line-height:1.12; white-space:nowrap; }
.zc-live .zcard-sub { font-size:16px; font-weight:400; color:var(--t-secondary); letter-spacing:-0.1px; line-height:1.15; white-space:nowrap; }
.zc-live .zcard-right { margin-left:auto; display:flex; flex-direction:column; align-items:flex-end; gap:7px; flex-shrink:0; }
.zc-live .zcard-badges { display:flex; align-items:center; gap:9px; }
/* badges default to muted "off"; they take their colour only when the tile is
   the active one (leaf/setback → eco green, override → amber) */
.zc-live .zcard-badge { font-size:18px; line-height:1; color:var(--t-tertiary); transition:color .45s ease, text-shadow .45s ease; }
.zc-live .zcard-temp { font-size:31px; font-weight:400; color:var(--t-primary); letter-spacing:-1px; line-height:1; font-variant-numeric:tabular-nums; }
/* off tile reads as OFF: no colour band, no halo, and its text/icon are muted
   (secondary, not primary) since nothing is running. No badge/dot. When it is
   the followed state, a soft pulsing edge draws attention (there is no state
   colour to show), and the text lifts back toward primary. */
.zc-live.mode-off { --accent:#20232b; --accent-l2:#20232b; }
.zc-live.mode-off .zcard::before { display:none; }
.zc-live.mode-off .zcard-icon,
.zc-live.mode-off .zcard-name,
.zc-live.mode-off .zcard-temp { color:var(--t-secondary); transition:color .45s ease; }

/* Stacked colour demo (section 2): four state cards, each ALWAYS in its own
   state colour (no dimming). The colour "follows" the sequence by breathing
   ONLY the active card's L2 halo — the others hold a faint static halo — and the
   active card's green leaf, if it has one, glows in step. JS toggles .is-active. */
.zc-stack { display:flex; flex-direction:column; gap:12px; width:360px; max-width:100%; }
.zc-stack .zc-live .zcard { animation:none; --l2a:7%; }
/* active tile: halo breathes AND a coloured edge pulses in its own accent —
   an extra cue that this is the one being followed. */
.zc-stack .zc-live.is-active .zcard { animation:zcActive 3.6s ease-in-out infinite; }
/* active tile: its badges take colour (leaf/setback green, override amber) */
.zc-stack .zc-live.is-active .zcard-badge { color:var(--accent-eco); text-shadow:0 0 8px color-mix(in srgb,var(--accent-eco) 45%,transparent); }
.zc-stack .zc-live.is-active .zcard-badge.warn { color:var(--st-warn); text-shadow:0 0 8px color-mix(in srgb,var(--st-warn) 45%,transparent); }
.zc-stack .zc-live.is-active .zcard-badge.alarm { color:var(--st-alarm); text-shadow:0 0 8px color-mix(in srgb,var(--st-alarm) 45%,transparent); }
/* off, when followed: no colour to show — a white edge instead of a coloured one */
.zc-stack .zc-live.mode-off.is-active .zcard { animation:offEdge 3.6s ease-in-out infinite; }


@media (prefers-reduced-motion: reduce){
  .zc-stack .zc-live.is-active .zcard { animation:none; --l2a:22%; box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--accent) 55%,transparent), 0 20px 50px rgba(0,0,0,.4); }
  .zc-stack .zc-live.mode-off.is-active .zcard { animation:none; box-shadow:inset 0 0 0 1.5px rgba(236,237,242,0.4), 0 20px 50px rgba(0,0,0,.4); } }

/* ---- Eco pair (§7c): energy saving + setback shown ON the rooms, as square
   zone TILES. .zsq is the faithful in-loco port of the app's .zone-sq
   (engine pages/zones/_zones-pages.scss): 180px 3:4 card, accent stripe +
   left wash + corner L2 halo, glyph/name/setpoint/now/RH/VOC scale 1:1.
   Extended (page-only) with the per-mode accent machine + the is-on breathe
   so the shared temp loop can flip each tile idle ⇄ heating/cooling — state
   is the COLOR, exactly as on the real tile (no invented status text). ---- */
.zsq { zoom:0.955; display:inline-block;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),0.95); --t-secondary:rgba(var(--ink-rgb),0.60); --t-tertiary:rgba(var(--ink-rgb),0.37);
  --tile-bg:linear-gradient(180deg,rgba(255,255,255,0.030) 0%,rgba(255,255,255,0.014) 100%);
  --tile-border-color:rgba(255,255,255,0.05);
  --hairline:rgba(255,255,255,0.08); --surface-sunken:rgba(255,255,255,0.07);
  --tile-radius:24px; --l2a:9%; --status-icon-size:18px;
  --accent-heat:#D9824F; --accent-cool:#5E92C4; --accent-idle:#8C909B; --accent-eco:#6FA67C;
  --voc-good:#6FA67C; --hum-normal:#F4F4F5;
  --zone-glyph-size:26px; --zone-name-size:22px; --tile-meta-size:15px; --tile-tick-size:13px; --tile-supporting-size:18px;
  --accent:var(--accent-idle); --accent-l2:var(--accent-idle); }
.zsq .zone-sq { position:relative; display:flex; flex-direction:column; width:180px; aspect-ratio:3/4; padding:18px; overflow:hidden; border:0; border-radius:var(--tile-radius);
  box-shadow:inset 0 0 0 1px var(--tile-border-color), 0 20px 50px rgba(0,0,0,.4);
  background:radial-gradient(ellipse 135% 115% at 14% 6%, color-mix(in srgb, var(--accent-l2) var(--l2a), transparent) 0%, transparent 76%), var(--tile-bg); }
.zsq .zone-sq::before { content:''; position:absolute; top:0; bottom:0; left:0; width:2px; background:var(--accent); box-shadow:0 0 8px var(--accent); z-index:2; transition:background .45s ease, box-shadow .45s ease; }
.zsq .zone-sq::after { content:''; position:absolute; left:0; top:0; bottom:0; width:20%; pointer-events:none; opacity:.8;
  background:linear-gradient(90deg, color-mix(in srgb,var(--accent) 12%,transparent) 0%, color-mix(in srgb,var(--accent) 4%,transparent) 45%, transparent 100%); }
.zsq .zone-sq > * { position:relative; z-index:1; }
.zsq .zone-sq-head { display:flex; align-items:center; justify-content:space-between; min-height:var(--zone-glyph-size); }
.zsq .zone-sq-icon { font-size:var(--zone-glyph-size); width:var(--zone-glyph-size); line-height:1; text-align:center; flex-shrink:0; color:var(--accent); transition:color .45s ease; }
.zsq .zone-sq-badges { display:flex; align-items:center; gap:7px; }
/* badges start muted; .on = the activation idiom (eco green + soft glow);
   .lit = always-on leaf (energy saving enabled), breathing gently */
.zsq .zsb { font-size:var(--status-icon-size); line-height:1; color:var(--t-tertiary); transition:color .45s ease, text-shadow .45s ease; }
.zsq .zsb.on, .zsq .zsb.lit { color:var(--accent-eco); text-shadow:0 0 8px color-mix(in srgb,var(--accent-eco) 45%,transparent); }
.zsq .zsb.lit { animation:ecoLeafPulse 2.8s ease-in-out infinite; }

.zsq .zone-sq-name { margin-top:8px; min-height:48px; font-size:var(--zone-name-size); font-weight:600; color:var(--t-primary); letter-spacing:-0.2px; line-height:1.2; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.zsq .zone-sq-body { margin-top:10px; display:flex; flex-direction:column; align-items:flex-start; gap:7px; }
.zsq .zone-sq-set { display:inline-flex; align-items:baseline; font-size:44px; line-height:1; color:var(--t-primary); font-variant-numeric:tabular-nums; }
.zsq .zone-sq-int { font-weight:400; letter-spacing:-1.8px; }
.zsq .zone-sq-unit { color:inherit; }
.zsq .zone-sq-now { font-size:var(--tile-meta-size); color:var(--t-tertiary); font-variant-numeric:tabular-nums; letter-spacing:0.1px; line-height:1; }
.zsq .zone-sq-foot { margin-top:auto; padding-top:0; display:grid; grid-template-columns:repeat(3,1fr); column-gap:8px; align-items:end; }
.zsq .zone-sq-metric { display:flex; flex-direction:column; gap:4px; align-items:flex-start; line-height:1; min-width:0; }
.zsq .zone-sq-mlabel { font-size:var(--tile-tick-size); font-weight:700; letter-spacing:0.7px; text-transform:uppercase; color:var(--t-tertiary); }
.zsq .zone-sq-mval { font-size:var(--tile-supporting-size); font-weight:600; font-variant-numeric:tabular-nums; color:var(--t-secondary); }
.zsq .zone-sq-mval.hum-normal { color:var(--hum-normal); }
.zsq .zone-sq-mval.voc-good { color:var(--voc-good); }
/* engaged: the L2 halo breathes and the accent edge pulses (the color
   section's zcActive idiom, on the square tile's own base shadow) */
.zsq.is-on .zone-sq { animation:zsqActive 3.6s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce){
  .zsq .zsb.lit { animation:none; }
  .zsq.is-on .zone-sq { animation:none; --l2a:24%; box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--accent) 55%,transparent), 0 20px 50px rgba(0,0,0,.4); } }

.eco-duo { display:flex; justify-content:center; align-items:flex-start; gap:clamp(28px,5vw,64px); flex-wrap:wrap; }
.eco-col { display:flex; flex-direction:column; gap:14px; align-items:center; }
.eco-col .kicker { max-width:320px; text-align:center; line-height:1.5; }
/* caption pill = the energy-saving page's real state pill (SAVING / ENGAGED,
   .pill-ok): eco-lit while the control is actively paying off, muted otherwise */
.eco-pill { display:inline-block; font-size:11.5px; font-weight:600; letter-spacing:.4px; padding:3px 9px; border-radius:8px; margin-right:8px; vertical-align:1px;
  background:color-mix(in srgb,var(--accent-eco) 20%,transparent); color:var(--accent-eco); transition:color .45s ease, background .45s ease; }
.eco-pill.dim { background:rgba(255,255,255,.07); color:var(--t-tertiary); }
/* soft green section halo behind the pair (the #rbm-integration pattern, eco side) */
#rbm-eco { background:
  radial-gradient(56% 44% at 50% 36%, color-mix(in srgb,var(--accent-eco) 6%, transparent) 0%, transparent 62%),
  var(--bg-base); }
@media (prefers-reduced-motion: reduce){ .eco-duo .zcard-badge.lit { animation:none; } }

/* crossfade stack for real captures */
.xfade { position: relative; display: inline-block; }
.xfade > img { display: block; }
.xfade > img:not(:first-child) { position: absolute; inset: 0; }
.xfade > img { opacity: 0; transition: opacity 700ms ease; }
.xfade > img.on { opacity: 1; }
/* theme phone: dark screenshot is an always-opaque base, only the light one
   fades on top -> no midpoint transparency dip, so the status strip's color
   transition and the screenshot blend stay in lockstep (no seam) */
#homeShots > img:first-child { opacity: 1; }

/* ===== iPhone frame, built in LAYERS (screen → black edge → metal rim),
   the Xcode-simulator look. Sim-true proportions at 344px width:
   rim 3 + bezel 5 = 8/side (2.3%, the iPhone-17-class thin edge);
   body radius 50, screen 50 − 8 = 42. Every device takes a SUBTLE metal
   tint from its section via --rail (mixed ~22% into graphite, never a
   flat colored ring). ===== */
.device-wrap { width: 344px; max-width: 86vw; }
.device {
  position: relative; width: 100%;
  /* the machined two-tone edge: ONE color, two tones, a lighter outer band
     (--mA, the box-shadow ring) over a darker inner band (--mB, the border) */
  --mA: color-mix(in srgb, var(--rail,#8e9095) 30%, #97999e);
  --mB: color-mix(in srgb, var(--rail,#3f4145) 26%, #3f4145);
  border: 2px solid transparent; padding: 5px; border-radius: 50px;
  background:
    linear-gradient(#050506,#050506) padding-box,
    linear-gradient(155deg, color-mix(in srgb, var(--mA) 40%, var(--mB)) 0%, var(--mB) 22%,
      color-mix(in srgb, var(--mB) 70%, #1b1c1e) 55%, var(--mB) 82%,
      color-mix(in srgb, var(--mA) 35%, var(--mB)) 100%) border-box;
  box-shadow: 0 0 0 1.5px var(--mA), 0 0 0 2.5px rgba(0,0,0,.5),
              0 30px 70px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.04);
}
.t-light .device { box-shadow: 0 0 0 1.5px var(--mA), 0 0 0 2.5px rgba(0,0,0,.3),
              0 30px 70px rgba(0,0,0,.25), inset 0 0 0 1px rgba(255,255,255,.04); }
.device.dv-orange { --rail:#C56A38; } .device.dv-blue { --rail:#3F6E9C; }
.device.dv-green { --rail:#5D8C6A; } .device.dv-silver { --rail:#b6b7bd; } .device.dv-violet { --rail:#8B79C6; }
.device.dv-titanium { --rail:#8e9095; }
/* side buttons, the sim's: simple slabs of the SAME metal, the lighter tone
   on the outer face over the darker seam. Left = action + vol-up + vol-down,
   right = the long side button.
   They must protrude from OUTSIDE the rim: `left`/`right` resolve against the
   padding box, whose edge sits inside the 2px border, and the rim's outer metal
   reaches -3.5px, so -6.5px seats the slab 0.5px under the ring and stands it
   ~3px proud. Every offset is a % of body height (never px): the device scales
   with the viewport, and px gaps drift apart as it shrinks.
   Proportions are the real iPhone's, volume keys are longer than the action
   key, and the side button's top sits level with volume-up. */
.dvb { position: absolute; width: 3.5px; }
.dvb.l { left: -6.5px; border-radius: 2px 0 0 2px; background: linear-gradient(90deg, var(--mA), var(--mB)); }
.dvb.r { right: -6.5px; border-radius: 0 2px 2px 0; background: linear-gradient(270deg, var(--mA), var(--mB)); }
.dvb.b-act  { top: 20.1%; height: 3.4%; }
.dvb.b-vup  { top: 26.6%; height: 5.0%; }
.dvb.b-vdn  { top: 32.9%; height: 5.0%; }
.dvb.b-side { top: 26.6%; height: 8.5%; }
.device .dvs { border-radius: 42px; }
.device .di { width:98px; height:28px; top:15px; border-radius:16px; }
.device .sbar { height:46px; padding:17px 30px 0; font-size:15px; }
.dvs { position:relative; border-radius:46px; overflow:hidden; transition:background-color 700ms ease, color 700ms ease; }
.dvs[data-scr=dark]  { background:#121419; color:#fff; }
.dvs[data-scr=light] { background:#F4F3EF; color:#1A1C24; }
.dvs > img, .dvs > video { width:100%; display:block; }
.sbar { position:relative; height:42px; display:flex; align-items:center; justify-content:space-between; padding:15px 26px 0; font-size:14px; font-weight:500; z-index:3; letter-spacing:.2px; }
.sbar .sbi { display:flex; align-items:center; gap:6px; }
.sbar svg { display:block; }
.di { position:absolute; top:14px; left:50%; transform:translateX(-50%); width:88px; height:26px; background:#000; border-radius:15px; z-index:5; }

/* ===== hero dial, faithful port of dial-thermostat.component (geometry + typography 1:1) ===== */
.dial-zone { font-size: clamp(14px,1.9vw,17px); font-weight:500; letter-spacing:.16em; text-transform:uppercase; color: var(--t-secondary); text-align:center; margin-bottom: 6px; min-height: 21px; transition: color .4s ease; }
.dial-shell { position: relative; width: min(92vw, 450px); aspect-ratio: 450 / 400; margin: 0 auto; --dial-scale: 1; }
.dial-shell svg { display:block; width:100%; height:100%; overflow:visible; }
.dial-mode-label { font-size: 18px; }
.dial-setpoint-display { position:absolute; top:51%; left:50%; transform:translate(-50%,-50%) scale(var(--dial-scale,1)); display:flex; align-items:stretch; font-variant-numeric:tabular-nums; line-height:1; color:var(--dial-text-primary); }
.ds-int { font-size:80px; font-weight:500; letter-spacing:-3px; height:80px; line-height:80px; display:flex; align-items:center; }
.ds-frac { display:grid; grid-template-rows:13px 30px 29px 8px; margin-left:2px; }
.ds-unit, .ds-dec { display:flex; align-items:center; justify-content:center; overflow:visible; line-height:1; }
.ds-unit { grid-row:2; font-size:46px; font-weight:500; }
.ds-dec { grid-row:3; font-size:30px; font-weight:500; }
.ds-num { display:flex; align-items:stretch; }
.dial-dual-display { position:absolute; top:51%; left:50%; transform:translate(-50%,-50%) scale(var(--dial-scale,1)); display:flex; gap:40px; font-variant-numeric:tabular-nums; line-height:1; color:var(--dial-text-primary); }
.dial-dual-display .ds-int { font-size:56px; height:56px; line-height:56px; letter-spacing:-2px; }
.dial-dual-display .ds-frac { grid-template-rows:8px 24px 19px 5px; }
.dial-dual-display .ds-unit { font-size:38px; }
.dial-dual-display .ds-dec { font-size:25px; }
.dial-room-display { position:absolute; top:80%; left:50%; transform:translate(-50%,-50%); display:flex; align-items:center; justify-content:center; gap:8px; color:var(--dial-text-secondary); font-size:28px; font-weight:300; line-height:1; }
/* thermometer = the app's real fa-temperature-half glyph (regular), inheriting
   the row font-size exactly like the app's <app-icon name="temperature">. */
.dial-room-display .thermo { font-size:1em; line-height:1; }
.dial-room-value { font-weight:500; letter-spacing:-1px; }
@media (max-width:450px){
  .ds-int{font-size:68px;height:68px;line-height:68px} .ds-frac{grid-template-rows:11px 26px 25px 6px} .ds-unit{font-size:39px} .ds-dec{font-size:26px}
  .dial-dual-display{gap:30px} .dial-dual-display .ds-int{font-size:48px;height:48px;line-height:48px} .dial-dual-display .ds-frac{grid-template-rows:7px 21px 16px 4px} .dial-dual-display .ds-unit{font-size:33px} .dial-dual-display .ds-dec{font-size:21px}
}

/* ===== AI floating chat card (no phone) ===== */
.ai-card { width: min(100%, 400px); margin: 0 auto; border-radius: 26px; background: rgba(255,255,255,0.035);
  border: 1px solid var(--hairline); padding: 16px 16px 22px; box-shadow: 0 24px 60px rgba(0,0,0,0.4); }

/* ===== browser chrome (CSS only, the web-app section) ===== */
.browser { width: min(100%, 900px); border-radius: 14px; overflow: hidden;
  background: #23252B; border: 1px solid rgba(0,0,0,0.18); box-shadow: 0 26px 60px rgba(0,0,0,0.28); }
.browser-bar { display: flex; align-items: center; gap: 8px; padding: 11px 14px; background: #2C2F36; }
.browser-bar .bdot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.browser-bar .burl { margin-left: 12px; flex: 1; max-width: 320px; padding: 4px 14px; border-radius: 999px;
  background: rgba(0,0,0,0.28); color: rgba(255,255,255,0.62); font-size: 12px; text-align: center; }
.webshots { position: relative; width: 100%; aspect-ratio: 2752 / 2064; }
.webshots .webshot { position: absolute !important; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; animation: webfade 15s infinite; }
.webshots .webshot:nth-child(1) { animation-delay: 0s; }
.webshots .webshot:nth-child(2) { animation-delay: -5s; }
.webshots .webshot:nth-child(3) { animation-delay: -10s; }

@media (prefers-reduced-motion: reduce) {
  .webshots .webshot { animation: none; opacity: 0; }
  .webshots .webshot:nth-child(1) { opacity: 1; }
}

/* legend (color meaning) */
/* two named categories: HVAC mode | status signals. each is a titled column,
   so the square chips line up in a palette; groups center when the copy does. */
.legend { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 22px 60px; margin-top: 30px; }
.legend-group { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.legend-label { font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--t-tertiary); }
.legend-items { display: flex; flex-direction: column; gap: 11px; }
.legend .li { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--t-tertiary); transition: color 300ms ease; }
.legend .li .dot { width: 14px; height: 14px; border-radius: 4px; transition: box-shadow 300ms ease, transform 300ms ease; }
.legend .li.active { color: var(--t-primary); font-weight:500; }
.legend .li.active .dot { box-shadow: 0 0 12px currentColor; transform: scale(1.2); }
@media (max-width: 992px) { .legend { justify-content: center; } }

/* theme demo controls */
.seg-toggle { display: inline-flex; padding: 4px; border-radius: 999px; background: var(--surface-sunken); gap: 4px; margin-bottom: 22px; }
.seg-toggle button { padding: 8px 18px; border-radius: 999px; font-size: 14px; font-weight:500; color: var(--t-secondary); transition: all 240ms ease; }
.seg-toggle button.on { background: var(--t-primary); color: var(--bg-base); }

/* AI chat (designed concept, the assistant is beta; no real screen yet) */
/* height is reserved at runtime (measured from the full script) and the stack
   is bottom-anchored, so the loop never resizes the card or the row beside it */
.chat { display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; padding: 8px 2px; }
.bubble { max-width: 84%; padding: 11px 14px; border-radius: 18px; font-size: 14px; line-height: 1.35; color: var(--t-primary); opacity: 0; transform: translateY(10px); }
.bubble.show { opacity: 1; transform: none; transition: opacity 400ms ease, transform 400ms ease; }
.bubble.me { align-self: flex-end; background: color-mix(in srgb, var(--accent-ai) 26%, var(--bg-base)); border-bottom-right-radius: 6px; }
.bubble.ai { align-self: flex-start; background: rgba(255,255,255,0.06); border-bottom-left-radius: 6px; }
.confirm { align-self: flex-start; display: flex; gap: 8px; opacity: 0; transform: translateY(10px); }
.confirm.show { opacity: 1; transform: none; transition: opacity 400ms ease, transform 400ms ease; }
.confirm button { font-size: 13px; font-weight:500; padding: 7px 16px; border-radius: 999px; }
.confirm .yes { background: var(--accent-ai); color: #fff; } .confirm .no { box-shadow: inset 0 0 0 1px var(--hairline-strong); color: var(--t-secondary); }
.ai-accent { color: var(--accent-ai); }
/* composer, the app's real message bar. It caps the card with a fixed bottom
   edge (the chat fills upward into reserved space above it) and carries the
   mic: voice is the next thing shipping. */
.ai-composer { margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.08); }
.ai-composer .field { display: flex; align-items: center; gap: 10px; height: 46px; padding: 0 7px 0 16px;
  border-radius: 999px; background: rgba(255,255,255,0.05); border: 1px solid var(--hairline); }
.ai-composer .ph { flex: 1; font-size: 14px; color: var(--t-tertiary); }
.ai-composer .mic { font-size: 16px; color: var(--t-secondary); padding: 0 2px; }
.ai-composer .send { width: 32px; height: 32px; border-radius: 50%; flex: none; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent-ai) 30%, transparent); color: var(--accent-ai); }
.ai-screen { background: #121419; padding: 10px 12px 24px; min-height: 420px; }
.ai-hd { display: flex; align-items: center; gap: 8px; padding: 2px 2px 10px; border-bottom: 1px solid rgba(255,255,255,0.08); color: rgba(236,237,242,.95); }

/* chips */
.chips { display: grid; grid-template-columns: repeat(auto-fit,minmax(230px,1fr)); gap: 14px; margin-top: 40px; }
.chip { border: 1px solid var(--hairline); border-radius: 18px; padding: 22px; }
.chip h4 { font-size: 18px; font-weight:500; margin-bottom: 8px; }
.chip p { font-size: 15px; color: var(--t-secondary); line-height: 1.5; }
/* real FA icon, sized to blend into the chip (was a hand-drawn SVG that
   ballooned because the inline span ignored width/height) */
.chip-ic { display: block; font-size: 24px; line-height: 1; color: var(--accent-cool); margin-bottom: 16px; }
/* access-level ladder in the People copy column (not the tiles) */
.role-list { list-style: none; margin: 22px 0 0; display: flex; flex-direction: column; gap: 11px; }
.role-list li { display: flex; align-items: baseline; gap: 14px; font-size: 15px; line-height: 1.45; color: var(--t-secondary); }
.role-list .role { flex: none; min-width: 96px; font-weight: 500; color: var(--t-primary); }
/* mControls "m" mark in the nav lockup, inherits the brand text color */
.m-mark { height: 19px; width: auto; display: inline-block; vertical-align: -4px; }
.photo-panel { position: relative; border-radius: 30px; overflow: hidden; background: color-mix(in srgb, var(--bg-base) 86%, #c8b79e); box-shadow: 0 24px 70px rgba(0,0,0,.18); }
.photo-panel img { width: 100%; height: 100%; object-fit: cover; }
.photo-panel.warm img { aspect-ratio: 1.08 / 1; }

/* ── feel section — the lifestyle photo as a FULL-BLEED stage, the app's real
   readings floating on it (no story list). ── */
.feel-sec { padding: 0; }
.feel-stage { position: relative; min-height: clamp(680px, 96vh, 940px); overflow: hidden; isolation: isolate; background: color-mix(in srgb, var(--bg-base) 86%, #c8b79e); margin: 0; }
.feel-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* left-to-right light scrim so the copy stays readable over the photo */
.feel-stage::before { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(90deg, rgba(244,243,239,.96) 0%, rgba(244,243,239,.84) 26%, rgba(244,243,239,.46) 46%, rgba(244,243,239,.12) 66%, rgba(244,243,239,.02) 100%); }
.feel-content { position: relative; z-index: 2; display: grid; grid-template-columns: minmax(0,520px) 1fr; min-height: inherit; padding: clamp(40px,6vw,88px) var(--pad); align-items: center; }
.feel-copy { max-width: 520px; }
/* floating real tiles on the photo — same size, gently translucent so they
   read as part of the room, not pasted on. Clean square PNGs rounded here. */
.photo-overlays { position: absolute; top: clamp(28px,4vw,54px); right: clamp(24px,4vw,54px); width: min(19vw, 178px); display: flex; flex-direction: column; gap: 16px; align-items: flex-end; z-index: 3; pointer-events: none; }
.photo-overlays .ov-tile { width: 100%; border-radius: 18px; overflow: hidden; box-shadow: 0 18px 44px rgba(60,45,30,.22); opacity: .78; }
.photo-overlays .ov-tile img { width: 100%; height: auto; display: block; border-radius: 18px; }
/* feel-stage banner: dark glass + white text (3-class specificity so it beats
   the light-theme .t-light .photo-pull default), inset bottom-left, readable
   over the bright photo. */
.feel-sec .feel-stage .feel-pull { z-index: 3; left: clamp(40px,6vw,88px); bottom: clamp(36px,5vw,60px); max-width: min(380px, calc(100% - 2*clamp(40px,6vw,88px))); background: rgba(16,18,22,.45); box-shadow: inset 0 0 0 1px rgba(255,255,255,.16), 0 18px 44px rgba(0,0,0,.3); }
.feel-sec .feel-stage .feel-pull strong { color: #fff; }
.feel-sec .feel-stage .feel-pull span { color: rgba(255,255,255,.82); }
.photo-panel.evening img { aspect-ratio: 1.14 / 1; }
.photo-pull { position: absolute; left: 22px; bottom: 22px; max-width: 320px; padding: 18px 20px; border-radius: 20px; background: rgba(18,20,25,.68); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); box-shadow: inset 0 0 0 1px rgba(255,255,255,.08); }
.photo-pull strong { display: block; font-size: 18px; line-height: 1.2; color: #fff; }
.photo-pull span { display: block; margin-top: 8px; font-size: 14px; line-height: 1.5; color: rgba(255,255,255,.74); }
.people-grid { display: grid; grid-template-columns: minmax(0,.95fr) minmax(0,1.05fr); gap: clamp(28px,5vw,64px); align-items: center; margin-bottom: clamp(34px,5vw,56px); }
.people-copy .lead { max-width: 42ch; }
.people-copy .kicker { margin-top: 18px; max-width: 42ch; }
.t-light .photo-panel { box-shadow: 0 20px 60px rgba(0,0,0,.12); }
.t-light .photo-pull { background: rgba(244,243,239,.82); box-shadow: inset 0 0 0 1px rgba(255,255,255,.45), 0 18px 40px rgba(0,0,0,.08); }
.t-light .photo-pull strong { color: rgba(26,28,36,.96); }
.t-light .photo-pull span { color: rgba(26,28,36,.72); }

/* two-up (override: modal + result) */
.twoup { display: flex; gap: clamp(16px,3vw,40px); justify-content: center; align-items: center; flex-wrap: wrap; }
.twoup .arrow { color: var(--t-tertiary); font-size: 30px; }
/* stack the set->result pair vertically before it would wrap awkwardly; the
   arrow rotates to point down between the two cards. */
@media (max-width: 640px) { .twoup { flex-direction: column; } .twoup .arrow { transform: rotate(90deg); margin: 2px 0; } }
.card-shot { border-radius: 22px; box-shadow: 0 20px 50px rgba(0,0,0,.4); }
.t-light .card-shot { box-shadow: 0 20px 50px rgba(0,0,0,.18); }

/* nav */
.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 14px var(--pad); background: color-mix(in srgb,#121419 62%,transparent); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); border-bottom: 1px solid rgba(255,255,255,.06); transition: background 400ms ease; }
.nav .brand { display: flex; align-items: center; gap: 11px; font-weight: 700; color: #fff; }
.nav .brand small { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500; letter-spacing: .04em; color: rgba(255,255,255,.5); }
.nav .brand .logo { height: 22px; width: auto; display: block; }
.hero-logo { height: clamp(36px,6.5vw,54px); width: auto; margin-bottom: 24px; }
.hero-wordmark { font-size: clamp(17px,2vw,21px); font-weight: 800; letter-spacing: -0.025em; line-height: 1.0; color: #fff; margin-bottom: 8px; }
.hero-by { font-size: clamp(12px,1.4vw,15px); letter-spacing: 0.14em; color: var(--t-primary); margin-bottom: 44px; white-space: nowrap; }
.hero-by .m-wired { display: inline-block; width: 1.728em; height: 1.728em; vertical-align: middle; margin: 0 0.25em; color: var(--t-primary); position: relative; top: -0.05em; }
.hero-by .m-wired.m-wired-lg2 { width: 2.2464em; height: 2.2464em; margin: 0 -0.15em 0 -0.1em; }
.hero-by .m-wired svg { width: 100%; height: 100%; display: block; }
#rbm-onboard { display: none !important; }
#rbm-get .stats { display: none !important; }
.ai-life-card { display: none !important; }
#rbm-get .hero-cta .btn { width: min(100%, 300px); justify-content: center; }
.nav-links { display: flex; gap: 26px; align-items: center; }
.nav-links a { font-size: 14px; color: rgba(255,255,255,.72); transition: color 160ms ease; }
.nav-links a:hover { color: #fff; }
.nav .btn { background: #fff; color: #121419; }
@media (max-width: 720px) { .nav-links a:not(.btn) { display: none; } }

/* footer + stats */
.footer { background: #0d0f13; color: rgba(255,255,255,.7); padding: 64px var(--pad) 40px; }
.footer .wrap { display: flex; flex-wrap: wrap; gap: 40px; justify-content: space-between; }
.footer h5 { color: #fff; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 14px; }
.footer a { display: block; font-size: 14px; padding: 5px 0; color: rgba(255,255,255,.62); }
.footer a:hover { color: #fff; }
.footer .fine { width: 100%; border-top: 1px solid rgba(255,255,255,.1); margin-top: 24px; padding-top: 22px; font-size: 12px; color: rgba(255,255,255,.4); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
.stats { display: grid; grid-template-columns: repeat(auto-fit,minmax(160px,1fr)); gap: 30px; text-align: center; }
.stats .n { font-size: clamp(34px,5vw,54px); font-weight: 700; letter-spacing: -.03em; }
.stats .l { font-size: 14px; color: var(--t-secondary); margin-top: 6px; }
.mt { margin-top: 26px; } .center { text-align: center; }

/* hero */
.hero { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding-top: 170px; }
.hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(24px,5vw,72px); align-items: center; }
.hero h1 { margin-bottom: 24px; } .hero .lead { margin-bottom: 34px; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-dial { width: min(88vw, 440px); }
@media (max-width: 992px) {
  .hero-grid, .people-grid { grid-template-columns: 1fr; text-align: center; }
  .hero .lead, .people-copy .lead, .people-copy .kicker { margin-inline: auto; }
  .hero .lead { margin-bottom: 34px; }
  .hero-cta { justify-content: center; }
  .hero-media { order: 0; margin-top: 12px; }
  .people-copy { max-width: none; order: -1; }
  .photo-pull { left: 16px; right: 16px; max-width: none; }
  /* feel stage stacks: photo on top, then the banner, then the copy — all
     pinned to the bottom of the stage (banner rides the bottom of the photo,
     directly above the title). bg + tiles are absolute, so the only flow items
     are the banner and the copy. */
  .feel-stage { display: flex; flex-direction: column; justify-content: flex-end; }
  .feel-content { grid-template-columns: 1fr; align-items: end; min-height: 0; padding: 20px 18px 26px; }
  .feel-copy { max-width: none; padding-top: 0; }
  .feel-stage::before { background: linear-gradient(180deg, rgba(244,243,239,.06) 0%, rgba(244,243,239,.20) 22%, rgba(244,243,239,.66) 50%, rgba(244,243,239,.95) 74%, rgba(244,243,239,.99) 100%); }
  .photo-overlays { top: 16px; right: 14px; width: 108px; gap: 10px; }
  .feel-sec .feel-stage .feel-pull { position: static; left: auto; right: auto; top: auto; bottom: auto; margin: 0 16px 20px; max-width: none; }
}

/* feel-sec: in-loco air tiles replace the old screenshot chips — single source
   of truth with section 8, vector-crisp at any DPI. Static here (halo off,
   this section's message is "the app disappears"). Scale the two-tile column as
   ONE unit with transform (not per-tile zoom — zoom is non-standard and
   Safari/iOS compute zoom+flex alignment differently, which desynced the tiles).
   transform-origin pins the top-right corner where the column sits. */
.feel-tiles { width: auto; transform: scale(.92); transform-origin: top right; }
/* both tiles are identical fixed 186px boxes; force it here too so no flex
   grow/shrink or content-sizing can ever make them differ. */
.feel-tiles .tile { flex: 0 0 auto; width: 186px; height: 186px; box-sizing: border-box;
  animation: none; --l2a: 0%;
  /* halo off + a frosted light surface: the section-8 tile-bg is near-transparent
     (built to sit on the cream section); over the photo it needs an opaque-ish
     glass card so the readings read, the way the old screenshot baked one in. */
  background: var(--tile-bg), rgba(246,245,241,0.40);
  backdrop-filter: blur(6px) saturate(1.05);
  -webkit-backdrop-filter: blur(6px) saturate(1.05);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.55), 0 18px 44px rgba(60,45,30,.24); }
@media (max-width: 992px) { .feel-tiles { transform: scale(.85); } }

/* ============================================================================
   Store-neutral toggle: add class "no-notch" to <body> to hide the iPhone
   status bar + Dynamic Island on every device, for an Android/iOS-agnostic
   frame. Default OFF (the iPhone chrome shows). One switch, all devices.
   ============================================================================ */
body.no-notch .sbar,
body.no-notch .di { display: none; }
body.no-notch .dvs > img,
body.no-notch .dvs > video,
body.no-notch .xfade { border-radius: inherit; }

/* ============================================================================
   Reduced motion: honour the OS "reduce motion" setting. Reveals appear
   instantly, infinite/keyframe animations and transitions collapse, and the
   videos are paused by the small script at the end of <body>.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ============================================================
   §5b · LIVE OVERRIDE — the app's real dial + override sheet, rebuilt
   in-loco and animated. Same technology + style as the hero dial (JS-rendered
   SVG, real FA glyphs, dial tokens). Everything scoped under .ovlive so it
   cannot leak into the rest of the page. The .app panel carries its own dark
   app tokens, so it stays dark regardless of the page section theme.
   ============================================================ */
.ovlive .app{
  --bg-base:#121419;
  --accent-heat:#D9824F; --st-warn:#C89B3C; --accent-override:#C89B3C;
  --hairline:rgba(255,255,255,.08); --hairline-strong:rgba(255,255,255,.17);
  --surface-raised:rgba(255,255,255,.05); --surface-sunken:rgba(255,255,255,.07);
  --icon-btn-border:rgba(255,255,255,.09);
  --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),.95); --t-secondary:rgba(var(--ink-rgb),.60); --t-tertiary:rgba(var(--ink-rgb),.37);
  --dial-punch-stroke:rgba(0,0,0,.55);
  /* full dial tiers — identical to the hero dial so the two are equivalent */
  --dial-heat-vivid:var(--accent-heat);
  --dial-heat-light:color-mix(in srgb,var(--accent-heat) 25%,var(--surface-sunken));
  --dial-heat-dim:color-mix(in srgb,var(--accent-heat) 6%,var(--surface-raised));
  --dial-heat-edge:color-mix(in srgb,var(--accent-heat) 45%,transparent);
  --dial-arc-dim:var(--surface-raised); --dial-arc-med:var(--surface-sunken);
  --dial-override:var(--st-warn); --dial-room-dot:#FFFFFF;
  --dial-handle-fill:var(--t-primary); --dial-handle-stroke:var(--dial-punch-stroke);
  position:relative;width:318px;height:452px;margin:0 auto;
  background:var(--bg-base);border-radius:26px;overflow:hidden;color:var(--t-primary);
}
/* top bar (engine .page-bar-row + .icon-btn) */
.ovlive .topbar{position:absolute;top:12px;left:12px;right:12px;z-index:6;display:flex;align-items:center;justify-content:space-between}
.ovlive .actions{display:flex;gap:8px}
.ovlive .icon-btn{width:42px;height:42px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--bg-base) 55%,transparent);border:1px solid var(--icon-btn-border);
  color:var(--t-secondary);font-size:18px;cursor:pointer;transition:color .2s,background .2s,border-color .2s,box-shadow .2s}
.ovlive .icon-btn .fa-regular{font-size:1em;line-height:1}
.ovlive .app.ov .ovr-toggle{color:var(--accent-override);
  background:color-mix(in srgb,var(--accent-override) 16%,var(--bg-base));
  border-color:color-mix(in srgb,var(--accent-override) 45%,transparent);
  box-shadow:0 0 12px color-mix(in srgb,var(--accent-override) 28%,transparent)}
.ovlive .app.ov .power-btn{color:var(--t-primary);background:color-mix(in srgb,var(--t-primary) 9%,transparent);border-color:var(--hairline-strong)}
/* room-name switcher */
.ovlive .switcher{position:absolute;top:64px;left:0;right:0;text-align:center;z-index:5}
.ovlive .room-name{font-size:21px;font-weight:600;letter-spacing:-.3px;line-height:1}
.ovlive .switcher .chev{position:absolute;top:-3px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;
  color:var(--t-secondary);font-size:22px;font-weight:300;line-height:1}
.ovlive .switcher .chev.l{left:14px}.ovlive .switcher .chev.r{right:14px}
.ovlive .dots{display:flex;gap:5px;justify-content:center;margin-top:9px}
.ovlive .dots i{width:15px;height:4px;border-radius:3px;background:var(--hairline-strong)}
.ovlive .dots i.on{width:20px;background:var(--t-secondary)}
/* running override banner (engine .ovr-banner) */
.ovlive .ovr-banner{position:absolute;left:12px;right:12px;top:104px;z-index:4;display:flex;align-items:center;gap:8px;
  padding:8px 10px;border-radius:12px;background:color-mix(in srgb,var(--accent-override) 13%,var(--bg-base));
  border:1px solid color-mix(in srgb,var(--accent-override) 34%,transparent);
  opacity:0;transform:translateY(-10px) scale(.98);transition:opacity .4s ease,transform .4s cubic-bezier(.2,.9,.25,1)}
.ovlive .app.ov .ovr-banner{opacity:1;transform:none}
.ovlive .ovr-b-ic{flex:none;font-size:15px;color:var(--accent-override)}
.ovlive .ovr-b-txt{flex:1;font-size:14px;color:var(--t-primary);letter-spacing:-.1px;font-variant-numeric:tabular-nums}
.ovlive .ovr-b-txt b{color:var(--accent-override);font-weight:700}
.ovlive .ovr-b-x{flex:none;width:22px;height:22px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--hairline-strong);color:var(--t-secondary);font-size:10px}
/* dial — fixed position, banner space reserved above it */
.ovlive .dial-wrap{position:absolute;left:0;right:0;top:162px;height:250px;display:flex;align-items:center;justify-content:center}
.ovlive .dial{position:relative;width:274px;height:238px}
.ovlive .dial svg{display:block;width:100%;height:100%;overflow:visible}
.ovlive .seg{fill:none;stroke-width:32;stroke-linecap:round;transition:stroke .45s ease}
.ovlive .demand{fill:none;stroke-width:32;stroke-linecap:round;transition:opacity .5s ease}
.ovlive .glow{fill:none;stroke-width:42;stroke-linecap:round;opacity:.32;transition:opacity .5s ease}
.ovlive .d-label{position:absolute;left:0;right:0;top:30%;text-align:center;font-size:15px;font-weight:700;letter-spacing:4.5px;
  color:var(--t-tertiary);transition:color .5s ease}
.ovlive .app.ov .d-label{color:var(--dial-override)}
.ovlive .d-num{position:absolute;left:50%;top:54%;transform:translate(-50%,-50%);display:flex;align-items:stretch;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--t-primary);transition:color .5s ease}
.ovlive .app.off .d-num{color:var(--t-secondary)}
.ovlive .ds-int{font-size:68px;font-weight:600;letter-spacing:-2.5px;height:68px;line-height:68px;display:flex;align-items:center}
.ovlive .ds-frac{display:grid;grid-template-rows:11px 26px 25px 6px;margin-left:2px}
.ovlive .ds-unit,.ovlive .ds-dec{display:flex;align-items:center;justify-content:center;line-height:1}
.ovlive .ds-unit{grid-row:2;font-size:39px;font-weight:500}
.ovlive .ds-dec{grid-row:3;font-size:26px;font-weight:600}
.ovlive .d-count{position:absolute;left:0;right:0;top:73%;text-align:center;font-size:15px;font-weight:500;letter-spacing:2px;
  color:var(--dial-override);opacity:0;transition:opacity .45s ease}
.ovlive .app.ov .d-count{opacity:1}
.ovlive .d-room{position:absolute;left:50%;top:92%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:7px;
  color:var(--t-secondary);font-size:27px;font-weight:300;line-height:1}
.ovlive .d-room .fa-regular{font-size:1em;line-height:1}
.ovlive .d-room b{font-weight:500;letter-spacing:-1px}
/* override sheet (engine .ovr-*) */
.ovlive .scrim{position:absolute;inset:0;z-index:8;background:rgba(0,0,0,.32);opacity:0;pointer-events:none;transition:opacity .4s ease}
.ovlive .app.sheet-open .scrim{opacity:1}
.ovlive .sheet{position:absolute;left:0;right:0;bottom:0;z-index:9;
  background:color-mix(in srgb,var(--t-primary) 4%,var(--bg-base));border-radius:20px 20px 0 0;
  transform:translateY(100%);transition:transform .46s cubic-bezier(.22,1,.32,1),box-shadow .3s ease;box-shadow:0 0 0 rgba(0,0,0,0)}
/* shadow ONLY while open — otherwise the closed sheet's upward shadow bleeds
   into the panel bottom as a dark blob under the room temp. */
.ovlive .app.sheet-open .sheet{transform:translateY(0);box-shadow:0 -16px 44px rgba(0,0,0,.5)}
.ovlive .ov-sheet-grab{width:34px;height:5px;border-radius:3px;background:var(--hairline-strong);margin:9px auto 0}
/* compact sheet — sized so it stays a BOTTOM sheet (~360px) and leaves the
   dimmed dial visible above it, instead of swallowing the whole panel. */
.ovlive .ovr-inner{padding:3px 18px 14px}
.ovlive .ovr-title{font-size:19px;font-weight:600;letter-spacing:-.2px;color:var(--t-primary)}
.ovlive .ovr-eyebrow{font-size:12px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--t-tertiary);margin-top:11px}
.ovlive .ovr-eyebrow-2{margin-top:13px}
.ovlive .ovr-temp{display:flex;align-items:center;justify-content:center;gap:16px;margin-top:7px}
.ovlive .ovr-step{width:40px;height:40px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;
  background:var(--surface-sunken);border:1px solid var(--hairline);color:var(--t-secondary);font-size:15px;
  transition:background .15s,border-color .15s,color .15s,transform .1s}
.ovlive .ovr-step.press{transform:scale(.9);background:var(--hairline-strong);color:var(--t-primary)}
.ovlive .ovr-num{font-size:48px;font-weight:400;letter-spacing:-1.5px;line-height:1;color:var(--t-primary);font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:baseline;min-width:120px;justify-content:center;transition:color .3s ease}
.ovlive .ovr-deg{font-weight:400;color:var(--t-secondary);transition:color .3s ease}
.ovlive .ovr-num.is-changed,.ovlive .ovr-num.is-changed .ovr-deg{color:var(--accent-override)}
.ovlive .ovr-seg{display:flex;background:var(--surface-sunken);border-radius:12px;padding:4px;margin-top:7px}
.ovlive .ovr-seg button{flex:1;min-height:34px;border-radius:9px;color:var(--t-secondary);font-size:14px;font-weight:500;letter-spacing:-.1px;
  background:none;border:0;font-family:inherit;transition:background .2s,color .2s}
.ovlive .ovr-seg button.on{background:color-mix(in srgb,var(--accent-override) 17%,transparent);color:var(--accent-override)}
.ovlive .ovr-exact-link{display:block;width:100%;margin-top:6px;padding:2px;text-align:center;color:var(--t-secondary);font-size:13px;background:none;border:0;font-family:inherit}
.ovlive .ovr-plain{margin-top:11px;font-size:14px;line-height:1.4;color:var(--t-secondary)}
.ovlive .ovr-plain b{color:var(--t-primary);font-weight:600}
.ovlive .ovr-plain b.acc{color:var(--accent-override);font-weight:700}
.ovlive .ovr-confirm{width:100%;margin-top:10px;padding:11px;border-radius:12px;background:var(--accent-override);color:#fff;
  font-size:15px;font-weight:700;letter-spacing:.1px;border:0;font-family:inherit;transition:transform .12s,filter .12s}
.ovlive .ovr-confirm.press{transform:scale(.97);filter:brightness(.9)}
.ovlive .ovr-cancel{width:100%;margin-top:3px;padding:6px;color:var(--t-tertiary);font-size:14px;background:none;border:0;font-family:inherit}

/* ── Option B · CINEMA background — darkest mood: a warm lamp pool low on the
   copy side, a faint film-grain texture over the whole section. Self-contained
   (grain is an inline SVG data-URI; no external requests). ── */
.sec.ovl-cinema{background:
  linear-gradient(90deg,rgba(7,7,8,.95) 0%,rgba(7,7,8,.82) 35%,rgba(7,7,8,.46) 64%,rgba(7,7,8,.76) 100%),
  radial-gradient(42% 54% at 68% 47%, color-mix(in srgb,#e0a24e 16%, transparent) 0%, transparent 58%),
  radial-gradient(50% 62% at 18% 82%, color-mix(in srgb,#c8822f 18%, transparent) 0%, transparent 64%),
  radial-gradient(100% 100% at 50% 48%, transparent 38%, rgba(0,0,0,.58) 100%),
  url('https://messana.tech/controls/wp-content/uploads/sites/4/2026/07/a63413c0.webp') center / cover no-repeat,
  #070708;}
.sec.ovl-cinema::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.6;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}
.ovl-cinema .wrap{position:relative;z-index:2}
/* the amber override glyph in the eyebrow reads as the section's little logo */
.ovl-cinema .eyebrow i{margin-right:6px;font-size:.95em}
/* the panel lifts off the dark bg with a soft shadow */
.ovlive .app{box-shadow:0 40px 90px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.05);}

/* ============================================================
   §6 · MACROZONE, shared settings. One composition (macro card + its nested
   zone tiles) + the apply-to-all dialog, on a light section (real theme-light
   tiles). Scoped under .mzsec; the zone tile is renamed .mzz-* so it never
   clashes with the dark .zsq eco tile. Diagonal 2×2 desktop / stacked mobile. */
.mzsec{--accent-heat:#D9824F;--st-ok:#4F8C5E;--surface-raised:rgba(0,0,0,.05);
  --tile-bg-top:rgba(0,0,0,.022);--tile-bg-bottom:rgba(0,0,0,.045);--tile-border-color:rgba(0,0,0,.07);
  --tile-shadow:inset 0 1px 0 rgba(255,255,255,.55), 0 1px 3px rgba(0,0,0,.06), 0 10px 26px rgba(30,26,20,.09);
  --hum-optimal:#6E5BB8;--voc-good:#4F8C5E}
.mzsec h2{font-size:clamp(30px,3.4vw,42px);line-height:1.08}
.mzsec .mz-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,5vw,72px);align-items:start}
.mzsec .mz-cell{min-width:0}
.mzsec .mz-cell.txt .lead{max-width:440px}
.mzsec .mz-cell.applytxt{padding-top:26px}
.mzsec .mz-cell.applytxt h3{font-size:clamp(24px,3vw,30px);line-height:1.1;font-weight:500;letter-spacing:-.02em;color:var(--t-primary);margin-bottom:14px}
/* macro composition */
.mzsec .macro-comp{width:min(100%,396px);justify-self:end;display:flex;flex-direction:column;gap:12px}
.mzsec .mzone{display:flex;flex-direction:column;gap:12px;padding:17px 19px;border-radius:22px;background:linear-gradient(180deg,rgba(252,251,248,.80),rgba(246,245,241,.68));border:1px solid rgba(255,255,255,.36);box-shadow:var(--tile-shadow);backdrop-filter:blur(18px) saturate(1.05)}
.mzsec .mz-head{display:flex;align-items:center;gap:9px}
.mzsec .mz-ic{font-size:17px;color:var(--t-tertiary);line-height:1;flex-shrink:0}
.mzsec .mz-name{font-size:20px;font-weight:600;color:var(--t-primary);letter-spacing:-.2px;white-space:nowrap}
.mzsec .mz-count{font-size:12px;font-weight:600;letter-spacing:.3px;text-transform:uppercase;color:var(--t-tertiary);white-space:nowrap}
.mzsec .mz-sp{flex:1}
.mzsec .mz-pill{display:inline-flex;align-items:center;font-size:12.5px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;padding:3px 9px;border-radius:20px;flex-shrink:0;background:color-mix(in srgb,var(--accent-cool) 15%,transparent);color:var(--accent-cool);border:1px solid color-mix(in srgb,var(--accent-cool) 34%,transparent)}
.mzsec .mz-stats{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap}
.mzsec .mz-stat{display:inline-flex;align-items:baseline;gap:5px}
.mzsec .mz-lbl{font-size:12px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--t-tertiary)}
.mzsec .mz-val{font-size:18px;font-weight:600;color:var(--t-secondary);font-variant-numeric:tabular-nums}
.mzsec .mz-mk{font-size:15px;font-weight:700}.mzsec .mz-mk.heat{color:var(--accent-heat)}.mzsec .mz-mk.cool{color:var(--accent-cool)}
.mzsec .mz-zlabel{font-size:12px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--t-tertiary);margin:2px 0 -2px 3px}
.mzsec .mz-zrow{display:grid;grid-template-columns:1fr 1fr;gap:13px}
/* zone tile (.mzz-*, light) */
.mzsec .mzz{--accent:var(--accent-cool)}
.mzsec .mzz-c{position:relative;display:flex;flex-direction:column;height:210px;padding:15px;overflow:hidden;border-radius:20px;box-shadow:var(--tile-shadow),inset 0 0 0 1px var(--tile-border-color);background:radial-gradient(ellipse 135% 115% at 14% 6%, color-mix(in srgb,var(--accent) 14%,transparent) 0%, transparent 74%), linear-gradient(180deg,var(--tile-bg-top),var(--tile-bg-bottom))}
.mzsec .mzz-c::before{content:'';position:absolute;top:0;bottom:0;left:0;width:2px;background:var(--accent);box-shadow:0 0 8px color-mix(in srgb,var(--accent) 60%,transparent);z-index:2}
.mzsec .mzz-c::after{content:'';position:absolute;left:0;top:0;bottom:0;width:22%;pointer-events:none;opacity:.9;background:linear-gradient(90deg,color-mix(in srgb,var(--accent) 12%,transparent) 0%,transparent 100%)}
.mzsec .mzz-c>*{position:relative;z-index:1}
.mzsec .mzz-head{display:flex;align-items:center;justify-content:space-between;min-height:24px}
.mzsec .mzz-ic{font-size:23px;line-height:1;color:var(--accent)}
.mzsec .mzz-b{font-size:17px;line-height:1;color:var(--accent-eco)}
.mzsec .mzz-name{margin-top:7px;font-size:19px;font-weight:600;color:var(--t-primary);letter-spacing:-.2px}
.mzsec .mzz-body{margin-top:8px;display:flex;flex-direction:column;align-items:flex-start;gap:5px}
.mzsec .mzz-dual{display:inline-flex;align-items:baseline;gap:4px;font-size:29px;line-height:1;color:var(--t-primary);font-variant-numeric:tabular-nums}
.mzsec .mzz-dual .mk{font-size:14px;font-weight:700}.mzsec .mzz-dual .mk.heat{color:var(--accent-heat)}.mzsec .mzz-dual .mk.cool{color:var(--accent-cool)}
.mzsec .mzz-dual .v{font-weight:400;letter-spacing:-1px}.mzsec .mzz-dual .sepv{width:6px}
.mzsec .mzz-now{font-size:13px;color:var(--t-tertiary);font-variant-numeric:tabular-nums;line-height:1}
.mzsec .mzz-foot{margin-top:auto;display:grid;grid-template-columns:1fr 1fr;column-gap:8px;align-items:end}
.mzsec .mzz-metric{display:flex;flex-direction:column;gap:4px;line-height:1}
.mzsec .mzz-mlabel{font-size:11px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--t-tertiary)}
.mzsec .mzz-mval{font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}
.mzsec .mzz-mval.rh{color:var(--hum-optimal)}.mzsec .mzz-mval.voc{color:var(--voc-good)}
/* apply composition */
.mzsec .apply-comp{width:min(100%,392px);display:flex;flex-direction:column;gap:9px;padding:20px;border-radius:22px;background:linear-gradient(180deg,rgba(252,251,248,.82),rgba(246,245,241,.70));border:1px solid rgba(255,255,255,.38);box-shadow:var(--tile-shadow);backdrop-filter:blur(18px) saturate(1.05)}
.mzsec .apply-hd{font-size:12px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--t-tertiary)}
.mzsec .apply-title{font-size:19px;font-weight:600;color:var(--t-primary);letter-spacing:-.2px;margin:-2px 0 2px}
.mzsec .apply-sub{font-size:14px;line-height:1.5;color:var(--t-secondary);margin-bottom:9px}
.mzsec .apply-sub b{color:var(--t-primary);font-weight:600}
.mzsec .ar-line{display:flex;align-items:center;gap:10px;padding:12px 14px;border-radius:13px;background:rgba(0,0,0,.032);border:1px solid var(--tile-border-color)}
.mzsec .ar-name{font-size:15px;font-weight:600;color:var(--t-primary)}.mzsec .ar-sp{flex:1}
.mzsec .ar-from{font-size:15px;color:var(--t-tertiary);font-variant-numeric:tabular-nums}.mzsec .ar-arrow{color:var(--t-tertiary);font-size:14px}
.mzsec .ar-to{font-size:15px;font-weight:700;color:var(--st-warn);font-variant-numeric:tabular-nums}
.mzsec .apply-btn{display:flex;align-items:center;justify-content:center;gap:9px;margin-top:6px;padding:14px;border-radius:14px;background:var(--st-ok);color:#fff;font-size:15.5px;font-weight:700;letter-spacing:.1px}
.mzsec .apply-btn .fa-solid{font-size:13px}
/* responsive: single column, each text block BEFORE its drawing, centered */
@media(max-width:900px){
  .mzsec .mz-grid{grid-template-columns:1fr;gap:34px;justify-items:center;text-align:center}
  .mzsec .mz-cell.txt .lead{max-width:none;margin-inline:auto}
  .mzsec .mz-cell.applytxt{padding-top:0}
  .mzsec .mz-cell.macro,.mzsec .mz-cell.apply{justify-self:stretch}
  .mzsec .macro-comp,.mzsec .apply-comp{justify-self:center;margin-inline:auto}
  .mzsec .mz-cell.intro{order:1}.mzsec .mz-cell.macro{order:2}
  .mzsec .mz-cell.applytxt{order:3}.mzsec .mz-cell.apply{order:4}
}

/* ===== #rbm-dashboard — "wall tablet" dashboard, rebuilt in-loco =====
   A dark app screen embedded in the light section (same idea as the phone
   screens). The zone rows reuse the page's real .zc-live component; the square
   tiles / pulse / mechanical tile / edit choreography live here, namespaced
   under .wdash so nothing leaks into the rest of the page. */
.dash-areas{list-style:none;margin:clamp(28px,4vw,44px) auto 0;padding:0;max-width:1000px;
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2.6vw,34px);text-align:left;}
.dash-areas li{display:grid;grid-template-columns:14px 1fr;gap:12px;padding-top:16px;
  border-top:1px solid color-mix(in srgb, var(--t-primary) 14%, transparent);}
.dash-areas .g{color:var(--accent);font-weight:400;font-size:23px;line-height:1.15;}
.dash-areas b{font-weight:600;color:var(--t-primary);} .dash-areas span{color:var(--t-secondary);}
@media(max-width:760px){ .dash-areas{grid-template-columns:1fr;max-width:440px;} }

/* Shared editorial bullet list — separator lines between rows (like #rbm-dashboard),
   left-aligned even inside centered columns, a prominent chevron/icon marker. */
.feat-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;}
.feat-list > li{display:grid;grid-template-columns:22px 1fr;column-gap:13px;align-items:start;
  padding:16px 2px;border-top:1px solid color-mix(in srgb, var(--t-primary) 13%, transparent);text-align:left;}
.feat-list > li strong{font-weight:600;color:var(--t-primary);}
.feat-list .mk{font-size:23px;line-height:1.15;font-weight:400;color:var(--accent);justify-self:center;margin-top:1px;}
.feat-list > li > i:first-child{font-size:20px !important;justify-self:center;margin-top:2px;}

.wall-frame{width:100%;max-width:1000px;margin:clamp(34px,5vw,60px) auto 0;border-radius:34px;
  background:#0a0b0e;box-shadow:0 44px 100px rgba(0,0,0,.45),inset 0 0 0 1.5px rgba(255,255,255,.08);padding:16px;}
.wdash{ --bg:#0d0f13; --ink-rgb:236,237,242;
  --t-primary:rgba(var(--ink-rgb),.95); --t-secondary:rgba(var(--ink-rgb),.60); --t-tertiary:rgba(var(--ink-rgb),.37);
  --tile-sheen:linear-gradient(180deg,rgba(255,255,255,.030) 0%,rgba(255,255,255,.014) 100%);
  --tile-border:rgba(255,255,255,.06); --tile-radius:20px;
  --accent-heat:#D9824F; --accent-cool:#5E92C4; --accent-eco:#6FA67C; --accent-idle:#8C909B; --amber:#E0A83E;
  --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  position:relative;width:100%;text-align:left;background:var(--bg);border-radius:24px;
  padding:22px 16px 18px;display:flex;flex-direction:column;gap:13px;font-family:var(--font);color:var(--t-primary);}
.wdash .thead{display:flex;justify-content:space-between;align-items:baseline;padding:0 6px 2px;gap:12px;}
.wdash .thead .tnm{font-size:22px;font-weight:600;letter-spacing:-.3px;}
.wdash .thead .tsub{font-size:13px;color:var(--t-secondary);}
.wdash .mv{position:relative;}
.wdash .mv .m{position:absolute;top:-6px;left:-6px;width:23px;height:23px;border-radius:50%;background:#7a7d85;
  display:flex;align-items:center;justify-content:center;box-shadow:0 2px 5px rgba(0,0,0,.4);z-index:9;
  opacity:0;transform:scale(.5);transition:opacity .22s ease,transform .22s ease;}
.wdash .mv .m::before{content:"";width:10px;height:2.2px;border-radius:2px;background:#1c1e23;}
.wdash.editing .mv .m{opacity:1;transform:scale(1);}
/* Wiggle the WHOLE .mv (minus + tile as one layer), not the overflow:hidden
   .dt — otherwise iOS WebKit clips the poking-out "−" to the transformed tile. */
.wdash.editing .mv{animation:wjig .4s ease-in-out infinite;}
.wdash.editing .mv:nth-child(3n){animation-delay:-.14s;} .wdash.editing .mv:nth-child(3n+1){animation-delay:-.27s;}

.wdash .grid{display:grid;grid-template-columns:repeat(4,1fr);gap:11px;}
.wdash .mv,.wdash .grid>.dt{min-width:0;}
/* grid tiles: the .mv itself is the square cell and the .dt fills it. Do NOT
   make .mv a flex container — on iOS Safari a flex box + transform (the wiggle)
   clips its absolutely-positioned "−" badge to the tile. Block .mv doesn't. */
.wdash .grid .mv{aspect-ratio:1;} .wdash .grid .mv>.dt{height:100%;}
.wdash .dt{position:relative;overflow:hidden;border-radius:var(--tile-radius);padding:14px 15px;
  box-shadow:inset 0 0 0 1px var(--tile-border);background:var(--tile-sheen),#181b21;}
.wdash .dt>*{position:relative;z-index:1;}
.wdash .lbl{font-size:15px;color:var(--t-secondary);line-height:1.25;}
.wdash .strong{font-size:17px;font-weight:600;color:var(--t-primary);margin-top:1px;}
.wdash .dt.sq{min-height:0;display:flex;flex-direction:column;}   /* size comes from the .mv wrapper */
.wdash .addslot.sqs{aspect-ratio:1;min-height:0;display:flex;flex-direction:column;}
.wdash .pulse{display:flex;align-items:center;gap:14px;min-height:98px;}
.wdash .pdot{position:relative;width:58px;height:58px;flex:none;display:flex;align-items:center;justify-content:center;}
.wdash .pdot i{width:14px;height:14px;border-radius:50%;background:#cfe0f2;animation:wdotPulse 2.6s ease-in-out infinite;}
.wdash .pdot::after{content:"";position:absolute;width:14px;height:14px;border-radius:50%;border:1.5px solid rgba(160,195,235,.55);animation:wping 2.6s ease-out infinite;}


.wdash .ptext .l1{font-size:19px;color:var(--t-secondary);line-height:1.15;}
.wdash .ptext .l2{font-size:21px;font-weight:600;letter-spacing:-.3px;line-height:1.15;margin-top:1px;}
.wdash .ptext .sub{font-size:13px;color:var(--t-tertiary);margin-top:8px;white-space:nowrap;}
.wdash .clock{margin-top:auto;font-size:46px;font-weight:300;letter-spacing:-2px;line-height:1;font-variant-numeric:tabular-nums;}
.wdash .clock .c{color:var(--t-tertiary);margin:0 1px;}
.wdash .mer{font-size:18px;color:var(--t-secondary);margin-top:7px;}
.wdash .wx{margin-top:auto;display:flex;align-items:center;gap:10px;}
.wdash .wx svg{width:40px;height:40px;flex:none;color:var(--amber);}
.wdash .wtemp{font-size:42px;font-weight:300;letter-spacing:-2px;line-height:1;}
.wdash .hilo{margin-top:11px;font-size:15px;color:var(--t-secondary);display:flex;gap:15px;}
.wdash .hilo .d{color:var(--accent-cool);} .wdash .hilo .u{color:var(--accent-heat);}
.wdash .avg{background:radial-gradient(ellipse 95% 85% at 28% 112%,color-mix(in srgb,var(--accent-cool) 26%,transparent) 0%,transparent 62%),var(--tile-sheen),#181b21;}
.wdash .big{margin-top:5px;font-size:42px;font-weight:300;letter-spacing:-2px;line-height:1;}
.wdash .aispark{margin-top:auto;} .wdash .aispark svg{width:100%;height:30px;display:block;overflow:visible;}
.wdash .aispark .ln{fill:none;stroke:var(--accent-cool);stroke-width:1.6;stroke-linecap:round;}
.wdash .aispark .fl{fill:color-mix(in srgb,var(--accent-cool) 42%,transparent);opacity:.4;}
.wdash .aicap{font-size:13px;color:var(--accent-cool);margin-top:6px;font-weight:500;}
.wdash .pills{margin-top:8px;display:flex;flex-wrap:wrap;gap:7px;}
.wdash .pill{font-size:12px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:4px 10px;border-radius:999px;box-shadow:inset 0 0 0 1px currentColor;}
.wdash .pill.on{color:var(--accent-eco);} .wdash .pill.cool{color:var(--accent-cool);} .wdash .pill.auto{color:var(--accent-idle);}
.wdash .calling{margin-top:auto;display:flex;justify-content:space-between;align-items:baseline;font-size:14px;color:var(--t-secondary);}
.wdash .calling b{font-weight:600;color:var(--t-primary);font-variant-numeric:tabular-nums;}
.wdash .favl{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--t-tertiary);margin:4px 6px -1px;}
.wdash .wfavs{display:flex;flex-direction:column;gap:11px;}
.wdash .lower{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start;}
.wdash .lower .wfavs{margin-top:6px;}
.wdash .hys{padding:16px 18px;}
.wdash .hys-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:6px;}
.wdash .hys-eyebrow{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--t-tertiary);}
.wdash .hys-title{font-size:20px;font-weight:600;letter-spacing:-.3px;margin-top:2px;} .wdash .hys-chev{font-size:17px;color:var(--t-tertiary);line-height:1;}
.wdash .hys-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 0;border-top:1px solid var(--tile-border);}
.wdash .hys-l{font-size:16px;color:var(--t-secondary);} .wdash .hys-v{font-size:16px;color:var(--t-primary);font-variant-numeric:tabular-nums;}
.wdash .pill2{font-size:12px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:4px 12px;border-radius:999px;color:var(--t-secondary);box-shadow:inset 0 0 0 1px currentColor;}
.wdash .pill2.cool{color:var(--accent-cool);} .wdash .pill2.ok{color:var(--accent-eco);}
.wdash .collapsing{animation:wcoll .5s forwards cubic-bezier(.4,0,.2,1);overflow:hidden;}
.wdash .collapsing .m{display:none;}   /* the collapsing tile has overflow:hidden; hide its "−" so it never shows clipped as it shrinks away */

.wdash .addslot{border:1.7px dashed var(--t-tertiary);display:flex;align-items:center;justify-content:center;color:var(--t-tertiary);font-size:28px;font-weight:300;border-radius:20px;}
.wdash .addslot.zs{min-height:86px;}   /* match the real zone-card height so the card doesn't grow when the "+" is replaced */
/* drop-in on the inner tile so it composes with the .mv wiggle (which owns the
   transform during editing) instead of being overridden by it */
.wdash .mv.dropin>.dt,.wdash .mv.dropin>.zc-live{animation:wdrop .55s cubic-bezier(.2,.85,.25,1);}

@media(max-width:840px){
  .wdash .grid{grid-template-columns:1fr 1fr;}
  .wdash .grid .mv{aspect-ratio:auto;}
  .wdash .dt.sq,.wdash .addslot.sqs{aspect-ratio:auto;min-height:166px;}
  /* keep the System pills compact in the tight 2-column cell so the tile fits
     the 166 floor like the others — otherwise its row grows to ~172 and the
     tiles visibly jump size when the add-slot ("+") is replaced by the tile */
  .wdash .pills{gap:4px;}
  .wdash .pill{padding:3px 8px;font-size:11px;}
  .wdash .lower{grid-template-columns:1fr;}
  .wdash .thead{flex-direction:column;gap:1px;}
}
@media (prefers-reduced-motion:reduce){ .wdash.editing .mv>*{animation:none;} .wdash .pdot i,.wdash .pdot::after{animation:none;} }

}
@keyframes airPalettePulse {
  0%,100% { color:var(--t-tertiary); }
  50% { color:var(--t-primary); }
}
@keyframes airSwatchPulse {
  0%,100% { box-shadow:none; transform:scale(1); }
  50% { box-shadow:0 0 12px var(--sw); transform:scale(1.18); }
}
@keyframes warmDrift { from { transform:scale(1.02) translate3d(-.4%,0,0); } to { transform:scale(1.06) translate3d(.8%,-.5%,0); } }
@keyframes airBreathe { 0%,100%{--l2a:0%;} 50%{--l2a:30%;} }
@keyframes integFanSpin { from{transform:rotate(0)} to{transform:rotate(360deg)} }
@keyframes ttArcPulse { 0%,100%{ opacity:1; } 50%{ opacity:.35; } }
@keyframes zcActive {
  0%,100%{ --l2a:7%; box-shadow:inset 0 0 0 1px var(--tile-border-color), 0 20px 50px rgba(0,0,0,.4); }
  50%{ --l2a:30%; box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--accent) 60%,transparent), 0 0 16px color-mix(in srgb,var(--accent) 24%,transparent), 0 20px 50px rgba(0,0,0,.4); } }
@keyframes offEdge {
  0%,100%{ box-shadow:inset 0 0 0 1px var(--tile-border-color), 0 20px 50px rgba(0,0,0,.4); }
  50%{ box-shadow:inset 0 0 0 1.5px rgba(236,237,242,0.42), 0 0 16px rgba(236,237,242,0.12), 0 20px 50px rgba(0,0,0,.4); } }
@keyframes ecoLeafPulse { 0%,100%{ opacity:1; } 50%{ opacity:.55; } }
@keyframes zsqActive {
  0%,100%{ --l2a:9%; box-shadow:inset 0 0 0 1px var(--tile-border-color), 0 20px 50px rgba(0,0,0,.4); }
  50%{ --l2a:30%; box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--accent) 60%,transparent), 0 0 16px color-mix(in srgb,var(--accent) 24%,transparent), 0 20px 50px rgba(0,0,0,.4); } }
@keyframes webfade { 0% { opacity: 1; } 27% { opacity: 1; } 33% { opacity: 0; } 94% { opacity: 0; } 100% { opacity: 1; } }
@keyframes wjig{0%,100%{transform:rotate(-.5deg)}50%{transform:rotate(.5deg)}}
@keyframes wdotPulse{0%,100%{transform:scale(1);box-shadow:0 0 9px rgba(150,185,228,.5)}50%{transform:scale(1.14);box-shadow:0 0 20px rgba(150,185,228,.85)}}
@keyframes wping{0%{transform:scale(1);opacity:.65}75%,100%{transform:scale(2.7);opacity:0}}
@keyframes wcoll{0%{transform:scale(1);opacity:1}40%{transform:scale(.55);opacity:0}100%{transform:scale(.4);opacity:0;max-height:0;margin:-6px 0 0}}
@keyframes wdrop{from{transform:translateY(-15px) scale(.94);opacity:0}to{transform:none;opacity:1}}

/* ---------------------------------------------------------------------------
   WordPress overrides: nav pill, CTA hide, brand hide, section fixes.
   Emitted outside the .rbm-more nesting block so they can beat the original
   selectors with (0,1,1)+ specificity.
   --------------------------------------------------------------------------- */
/* Nav wrapper: FIXED (not sticky) to the viewport, sitting under the Ohio
   header. Sized to its content and centered via translateX(-50%). Sticky was
   silently broken by an Elementor ancestor breaking the containing-block
   chain; fixed is relative to the viewport (or the nearest ancestor with
   transform/filter/perspective) and predictable. The wrapper itself is
   invisible: transparent bg, no bottom line, no horizontal padding. The
   pill visuals live on .nav-links. */
.rbm-more #rbm-nav {
  position: fixed !important;
  top: var(--rbm-wp-header-h, 120px);
  left: 50% !important;
  right: auto !important;
  transform: translateX(-50%);
  width: auto !important;
  height: auto !important;
  min-height: 0 !important;
  z-index: 40;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-bottom: 0 !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
}
/* Brand (RBM MORE logo + Messana SVG mark): hidden. The RBM MORE identity is
   already carried by the Ohio site header, and the two SVGs referenced here
   were rejected by WP core on upload (not in Media Library). */
.rbm-more #rbm-nav .brand { display: none !important; }
/* Pill container for the Dashboard/Comfort/AI links. Provisional styling:
   translucent bg + backdrop blur + thin border. The pill grows as the active
   link picks up an inner pad; keep the outer padding small so the pill stays
   compact. */
.rbm-more #rbm-nav .nav-links {
  display: inline-flex;
  gap: 6px;
  padding: 6px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bg-base, #F4F3EF) 60%, transparent);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border: 1px solid color-mix(in srgb, var(--t-primary, #1a1c24) 12%, transparent);
  box-shadow: 0 4px 14px -6px rgba(0, 0, 0, 0.15);
}
.rbm-more #rbm-nav .nav-links a {
  color: var(--t-primary, #1a1c24) !important;
  font-size: 14px;
  font-weight: 500;
  padding: 6px 14px;
  border-radius: 999px;
  transition: background 220ms ease, box-shadow 220ms ease, color 220ms ease;
}
/* Hover atmosphere in neutral grey — same tile treatment as .active but with
   the ink colour (--t-primary) at low opacities so the pill only *hints* at
   selection on hover. The coloured accent (orange / violet) is reserved for
   the destination pill after a click has settled. Skipped when already
   .active so the colour doesn't flip while the pointer crosses. */
.rbm-more #rbm-nav .nav-links a:hover:not(.active) {
  background:
    radial-gradient(120% 130% at 20% 20%,
      color-mix(in srgb, var(--t-primary, #1a1c24) 14%, transparent) 0%,
      transparent 68%),
    color-mix(in srgb, var(--t-primary, #1a1c24) 6%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--t-primary, #1a1c24) 20%, transparent),
    0 0 14px color-mix(in srgb, var(--t-primary, #1a1c24) 10%, transparent);
}
/* Active-link "atmosphere" glow: mirrors the ui-lab tile treatment (soft
   radial accent tint in the top-left corner + inset accent border + outer
   accent glow). The color is driven by --nav-accent, which the JS below
   copies from the currently visible section's own --accent custom property.
   The .active class is toggled by the JS observer, and cleared when the
   user is near the top of the page (no active pill at rest). */
.rbm-more #rbm-nav .nav-links a.active {
  color: var(--nav-accent, var(--accent-heat, #D9824F)) !important;
  background:
    radial-gradient(120% 130% at 20% 20%,
      color-mix(in srgb, var(--nav-accent, var(--accent-heat, #D9824F)) 28%, transparent) 0%,
      transparent 68%),
    color-mix(in srgb, var(--nav-accent, var(--accent-heat, #D9824F)) 10%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--nav-accent, var(--accent-heat, #D9824F)) 45%, transparent),
    0 0 14px color-mix(in srgb, var(--nav-accent, var(--accent-heat, #D9824F)) 30%, transparent);
}
/* "Get the app" CTAs: hidden everywhere (nav, hero) by link fragment. The
   dedicated #rbm-get section is stripped at the HTML level. */
.rbm-more a[href="#rbm-get"] { display: none !important; }
/* Reusable utility to hide targeted elements without removing them. */
.rbm-hidden { display: none !important; }
/* Ohio applies `h1..h6 { color: var(--clb-title-color) }` (white) directly
   on the tags, which broke the color inheritance from Alessandro's
   `.sec.t-light`. Light sections rendered white titles on white bg. Restore
   inherit with (0,1,1) specificity, beating Ohio's (0,0,1). */
.rbm-more :is(h1, h2, h3, h4, h5, h6) { color: inherit; }
/* Full-bleed: Elementor's Shortcode widget lives inside a boxed section
   (max 1300px). Force the .rbm-more wrapper to occupy the full viewport
   width via the classic negative-margin trick, without needing to change
   the page template or stretch the parent section. */
.rbm-more {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}
/* Feel section: the <figure class="feel-stage reveal d2"> fades in from
   opacity 0 to 1 (~1s). The `.sec.t-light.feel-sec` underneath had bg
   `var(--bg-base)` = `#F4F3EF` (a near-white warm off-white), so during the
   fade-in a white flash was visible before the stage reached full opacity
   and revealed its own warm-beige bg. Match the sec bg to the stage bg so
   the fade stays perceptually smooth (same hue) instead of flashing white. */
.rbm-more #rbm-feel.feel-sec {
  background: color-mix(in srgb, var(--bg-base) 86%, #c8b79e);
}
/* Feel section tiles (Humidity / VOC): originally anchored at
   `right: clamp(24px,4vw,54px)` from the stage. With `.rbm-more` full-bleed
   (100vw) the tiles end up ~54px from the right viewport edge, while Ohio's
   social bar (Instagram/LinkedIn/Facebook/YouTube) sits ~40px from the same
   edge: the tiles visually overlapped the social column. Push the tile
   group left with clamp 90-130px from the edge, leaving ~50-90px of gap
   with the social bar. */
.rbm-more #rbm-feel .photo-overlays.feel-tiles {
  right: clamp(90px, 9vw, 130px);
}
/* Macrozone tiles (Living Room / Kitchen): the parent `.mz-cell.macro` has
   `.reveal.d1` with an opacity 0 -> 1 transition (900ms, ~90ms delay). The
   children `.mzsec .mzone` and `.mzsec .apply-comp` have
   `backdrop-filter: blur(18px) saturate(1.05)`. Chrome (and Safari to a
   lesser extent) delays creating the compositor layer for backdrop-filter
   when an ancestor has an active opacity animation: the tile appears on
   screen and a few frames later the compositor promotes the layer and the
   blur pops in. Force eager promotion with `will-change: backdrop-filter`
   plus `transform: translateZ(0)` so the layer exists from first paint and
   the blur is present from the start of the reveal. `isolation: isolate`
   ensures the backdrop is the container itself, not an ancestor with
   opacity (which could produce doubled compositing). */
.rbm-more .mzsec .mzone,
.rbm-more .mzsec .apply-comp {
  will-change: backdrop-filter;
  transform: translateZ(0);
  isolation: isolate;
}
/* Ohio site footer (#colophon) is a light section (`clb__light_section`) with a
   white background, rendered site-wide below the app block and OUTSIDE the
   `.rbm-more` dark scope, so it stays white. This snippet loads only on page
   3000, so recolour the colophon dark (matching `--bg-base` #121419) to blend
   with the app theme, without affecting the footer on other /controls pages. */
#colophon.site-footer {
  background: #121419 !important;
}
#colophon.site-footer .site-footer-copyright,
#colophon.site-footer .-left,
#colophon.site-footer .-right {
  color: rgba(255,255,255,0.6) !important;
}
#colophon.site-footer a {
  color: rgba(255,255,255,0.72) !important;
}
#colophon.site-footer a:hover {
  color: #ffffff !important;
}
/* Responsive: hide the one-page anchor pill (Comfort/Dashboard/AI). On phones and
   tablets the pill links collapse to an empty oval that reads as a stray element;
   Enrico prefers it removed there. Kept on desktop (>900px). */
@media (max-width: 900px) {
  .rbm-more #rbm-nav { display: none !important; }
}
