/* ============================================================================
   Shared customer lifecycle panel - styles
   Single source of truth for the #liveSO slide-out used by BOTH the Customers
   page (pages/01) and the Appointments page (pages/03). Only the slideout-
   specific rules live here; generic primitives (.badge, .btn, .empty, .meta,
   .skel) are provided by each page's own design system / canon stylesheet.
   Token-driven only - no hardcoded brand colour.
   ========================================================================== */

/* slide-out shell */
.so-backdrop{position:fixed;inset:0;background:var(--surface-modal-overlay,rgba(0,0,0,.5));opacity:0;pointer-events:none;transition:opacity var(--duration-medium,.18s) var(--ease);z-index:var(--z-modal,1000)}
.so-backdrop.open{opacity:1;pointer-events:auto;background:var(--color-bg-overlay);backdrop-filter:blur(1.5px)}
.so-panel{position:fixed;top:0;right:0;bottom:0;width:clamp(360px,32vw,460px);max-width:94vw;background:var(--surface);border-left:1px solid var(--border);overflow-y:auto;transform:translateX(100%);transition:transform var(--duration-slow,.26s) var(--ease),right var(--motion-slow,.24s) ease;z-index:calc(var(--z-modal,1000) + 1);display:flex;flex-direction:column;box-shadow:var(--shadow-lg)}
.so-panel.open{transform:translateX(0)}
.so-head{padding:var(--space-lg) var(--space-lg) var(--space-md);border-bottom:1px solid var(--border-subtle);position:sticky;top:0;background:var(--surface);z-index:var(--z-raised,2)}
.so-name{font-family:var(--font-heading);font-size:var(--fs-lg,1.125rem);font-weight:var(--fw-semibold,600)}
.so-sub{font-size:var(--fs-xs,.75rem);color:var(--text-tertiary);font-family:var(--font-mono);margin-top:4px}
#liveSO .so-call-btn{display:inline-flex;align-items:center;gap:6px;margin-top:var(--space-sm);padding:6px 13px;border-radius:var(--radius-pill,999px);border:1px solid color-mix(in srgb, var(--accent) 42%, transparent);background:color-mix(in srgb, var(--accent) 15%, transparent);color:var(--accent);font-family:inherit;font-size:var(--text-sm,.8rem);font-weight:var(--fw-semibold,600);cursor:pointer;transition:background .15s ease}
#liveSO .so-call-btn:hover{background:color-mix(in srgb, var(--accent) 26%, transparent)}
#liveSO .so-call-btn i{font-size:.75rem}
.so-close{position:absolute;top:var(--space-md);right:var(--space-md);z-index:2;appearance:none;width:32px;height:32px;border-radius:50%;border:1px solid var(--border);background:var(--color-bg-glass,rgba(255,255,255,.06));color:var(--text);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:.9rem;line-height:1;padding:0}.so-close:hover{border-color:var(--text-tertiary)}
.so-body{flex:1;padding:0 var(--space-lg) var(--space-md)}

/* sections + field rows */
.slideout-section{margin-top:var(--space-lg)}
.slideout-section:first-child{margin-top:0}
.slideout-section-title{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary);margin-bottom:var(--space-sm)}
.field-row{display:grid;grid-template-columns:auto 1fr;gap:var(--space-md);padding:var(--space-sm) 0;border-bottom:1px solid var(--border-subtle);font-size:var(--text-sm)}
.field-row:last-child{border-bottom:0}
.field-label{color:var(--text-tertiary)}
.field-value{color:var(--text);text-align:right;font-variant-numeric:tabular-nums}

/* call summaries */
.so-calls{max-height:300px;overflow-y:auto;display:flex;flex-direction:column;gap:var(--space-sm);padding-right:4px}
.so-call{border-bottom:1px solid var(--border-subtle);padding-bottom:var(--space-sm)}
.so-call:last-child{border-bottom:0;padding-bottom:0}
.so-call-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary);margin-bottom:5px}
.so-call-tag{text-transform:capitalize;letter-spacing:.02em;padding:1px 7px;border-radius:var(--radius-pill);background:var(--glass-bg);color:var(--text-secondary)}
.so-call-tag.ok{background:var(--ok-bg,var(--glass-bg));color:var(--ok)}
.so-call-body{font-size:var(--text-sm);color:var(--text);line-height:1.5}
/* older calls collapse to a one-line, expand-on-click row */
.so-call-mini{border-bottom:1px solid var(--border-subtle);padding-bottom:var(--space-sm)}
.so-call-mini:last-child{border-bottom:0;padding-bottom:0}
.so-call-mini>.so-call-body{margin-top:6px}
.so-call-sum{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:var(--text-sm)}
.so-call-sum::-webkit-details-marker{display:none}
.so-call-when{font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary);flex-shrink:0}
.so-call-gist{color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}
.so-call-mini .so-call-tag{flex-shrink:0}

/* memory: inline stat chips + short labelled lines with more/less */
.so-stats{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-bottom:var(--space-sm)}
.so-stat{display:inline-flex;flex-direction:column;gap:2px;background:var(--surface-raised);border:1px solid var(--border-subtle);border-radius:var(--radius-md);padding:6px 10px;min-width:72px}
.so-stat-k{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary)}
.so-stat-v{font-size:var(--text-sm);color:var(--text);font-variant-numeric:tabular-nums}
.so-mem-line{display:flex;flex-direction:column;gap:2px;padding:var(--space-sm) 0;border-bottom:1px solid var(--border-subtle);font-size:var(--text-sm)}
.so-mem-line:last-child{border-bottom:0}
.so-mem-k{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-tertiary)}
.so-mem-v{color:var(--text);line-height:1.5}
.so-more{background:none;border:0;color:var(--accent);cursor:pointer;font-family:var(--font-mono);font-size:var(--text-2xs);padding:0 2px;margin-top:2px;align-self:flex-start}
.so-more:hover{text-decoration:underline}

/* risk line - pulled out as the emphasis of the AI narrative, not a fifth equal-weight paragraph */
#liveSO .so-risk-line{display:flex;align-items:baseline;gap:8px;padding:var(--space-sm) var(--space-md);margin:var(--space-sm) 0;border-radius:var(--radius-sm);background:var(--warn-bg);font-size:var(--text-sm)}
#liveSO .so-risk-line[data-risk="clear"]{background:var(--ok-bg,var(--glass-bg));border-left-color:var(--ok)}
#liveSO .so-risk-k{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary);flex-shrink:0}
#liveSO .so-risk-v{color:var(--text);font-weight:var(--fw-medium,500)}

/* note / calm line */
.so-panel .note{display:flex;gap:var(--space-sm);background:color-mix(in srgb, var(--accent) 6%, transparent);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm);margin:var(--space-sm) 0;font-size:var(--text-sm);color:var(--text-secondary)}
.so-panel .note strong{color:var(--text)}
.so-panel .note .tag{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.1em;text-transform:uppercase;color:var(--accent);flex-shrink:0;padding-top:2px}

/* compact lifecycle timeline */
.lifecycle-timeline{display:flex;align-items:center;gap:0;padding:var(--space-md) 0;overflow-x:auto}
.tl-step{display:flex;flex-direction:column;align-items:center;flex:1;min-width:50px;position:relative}
.tl-step::after{content:'';position:absolute;top:11px;left:60%;right:-40%;height:1px;background:var(--border-subtle);z-index:0}
.tl-step:last-child::after{display:none}
.tl-dot{width:22px;height:22px;border-radius:50%;background:var(--surface-raised);border:2px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:var(--text-2xs);color:var(--text-tertiary);position:relative;z-index:1}
.tl-step.done .tl-dot{background:var(--accent);border-color:var(--accent);color:var(--text-on-accent)}
.tl-step.done::after{background:var(--accent)}
.tl-step.current .tl-dot{background:var(--bg);border-color:var(--warn);color:var(--warn);box-shadow:0 0 0 4px var(--warn-bg)}
.tl-label{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-tertiary);margin-top:8px;text-align:center}
.tl-step.current .tl-label,.tl-step.done .tl-label{color:var(--text-secondary)}
/* Unknown onboarding_state (never tracked / not honestly derivable yet): every dot dashed
   and dimmed - visibly NOT the same as "hasn't reached this step yet", never dot 0 lit as
   current. See components/lifecycle-timeline.js renderDots(). */
.tl-step.unknown .tl-dot{border-style:dashed;opacity:.55}
.tl-step.unknown::after{background:var(--border-subtle);opacity:.55}
.tl-step.unknown .tl-label{opacity:.55}
/* NEVER TRACKED HERE, BUT IT HAPPENED (2026-09-01, operator ruling). An account
   whose onboarding_state is ABSENT was onboarded somewhere other than Teglo -
   true of 86 of Conduct Connect's 844 accounts, every one an active subscriber.
   Its steps carry a TICK at reduced opacity rather than an empty circle, because
   an empty circle reads as outstanding work and the card printed thirteen of
   them above copy saying onboarding was never tracked.
   The tick is deliberately --text-tertiary and NOT --accent: accent is the
   colour of work completed HERE, and this platform may not claim credit for
   work it did not do. Same reading, same reasoning and the same two tokens as
   .sp-stepper li.inherited in components/subject-panel.css. A solid border
   rather than the dashed one above: this step is not a gap, it is just not ours. */
.tl-step.unknown.inherited .tl-dot{border-style:solid;border-color:var(--border);color:var(--text-tertiary)}
.tl-step.unknown.inherited .tl-label{color:var(--text-tertiary)}
.lifecycle-unknown-note{font-size:var(--text-xs);color:var(--text-tertiary);margin-top:var(--space-xs)}

/* onboarding checklist disclosure */
.stages{margin-top:var(--space-md);display:flex;flex-direction:column;gap:8px}
.stage{background:var(--surface-raised);border:1px solid var(--border-subtle);border-radius:var(--radius-md);overflow:hidden}
.stage-summary{list-style:none;cursor:pointer;padding:10px var(--space-md);display:flex;align-items:center;gap:var(--space-sm);font-size:var(--text-sm)}
.stage-summary::-webkit-details-marker{display:none}
.stage-summary::before{content:'\25B8';color:var(--text-tertiary);transition:transform var(--motion-fast,.12s) var(--ease)}
.stage[open] .stage-summary::before{transform:rotate(90deg)}
.stage-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--text-tertiary)}
.stage[data-state="done"] .stage-dot{background:var(--ok)}
.stage[data-state="partial"] .stage-dot{background:var(--warn);box-shadow:0 0 0 3px var(--warn-bg)}
.stage-name{font-weight:500;color:var(--text)}
.stage-progress{margin-left:auto;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.08em;color:var(--text-tertiary)}
.stage-pdf-hint{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.08em;color:var(--text-tertiary);margin-right:var(--space-sm)}
.stage-body{padding:0 var(--space-md) var(--space-md) calc(var(--space-md) + 16px)}
.checklist-step{display:grid;grid-template-columns:22px 1fr auto;gap:var(--space-sm);align-items:flex-start;padding:10px 0;border-bottom:1px dashed var(--border-subtle);font-size:var(--text-sm)}
.checklist-step:last-child{border-bottom:0}
.check-box{width:18px;height:18px;border-radius:4px;border:1.5px solid var(--border);background:var(--bg);display:flex;align-items:center;justify-content:center;color:var(--bg);font-size:12px;cursor:pointer;margin-top:2px}
.check-box[data-checked="true"]{background:var(--accent);border-color:var(--accent);color:var(--text-on-accent)}
.check-label{color:var(--text);display:flex;flex-direction:column;gap:4px;min-width:0}
.check-label small{color:var(--text-tertiary);font-family:var(--font-mono);font-size:var(--text-2xs)}
.check-when{font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary);white-space:nowrap;align-self:flex-start;padding-top:2px}
/* Step metadata badges (owner / system / auto-derivable vs manual tick) - config-driven from
   vertical_lifecycle_stages.step_meta, see renderStages()/stageDefs() in lifecycle-panel.js. */
.step-badges{display:flex;flex-wrap:wrap;gap:4px}
.step-badge{border:0;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.04em;text-transform:uppercase;padding:1px 6px;border-radius:var(--radius-xs);color:var(--text-tertiary);background:var(--surface-raised)}
.step-owner[data-owner="support"]{color:var(--accent)}
.step-owner[data-owner="field"]{color:var(--warn)}
.step-owner[data-owner="customer"]{color:var(--text-secondary)}
.step-owner[data-owner="system"]{color:var(--success,var(--accent))}
.step-auto[data-auto="true"]{border-style:dashed}
/* HONEST STATE (2026-08-16). A completed step says WHO completed it, and an
   evidence-completed step names what was observed. The two actor classes write through one
   state machine (apply_onboarding_step_toggle) but must never look alike: an observed fact
   and an asserted one are different kinds of truth. See actorBadge() in lifecycle-panel.js. */
.step-actor{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.02em;color:var(--text-tertiary)}
.step-actor i{font-size:.85em;opacity:.8}
.step-actor[data-by="evidence"]{color:var(--success,var(--accent))}
.step-actor .ev-when{opacity:.65}
/* The tick itself carries the distinction too, so a scan down the column reads at a glance
   without hovering: an observed completion is ringed rather than solid-filled. */
.check-box[data-checked="true"][data-by="evidence"]{background:transparent;color:var(--success,var(--accent));border-color:var(--success,var(--accent));border-style:double;border-width:3px}
.cap-form{display:flex;flex-wrap:wrap;gap:var(--space-sm);align-items:flex-end;margin:var(--space-xs) 0 var(--space-sm) calc(22px + var(--space-sm))}
.cap-form label{display:flex;flex-direction:column;gap:4px;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.04em;text-transform:capitalize;color:var(--text-tertiary)}
.cap-form input{background:var(--bg);border:1px solid var(--border-subtle);border-radius:var(--radius-xs);padding:4px 8px;color:var(--text);font-family:var(--font-mono);font-size:var(--text-xs);min-width:160px}

/* location card */
.map{height:160px;background:linear-gradient(135deg,var(--map-grad-from) 0%,var(--map-grad-to) 100%);border-radius:var(--radius-md);position:relative;overflow:hidden}
.map-pin{position:absolute;top:50%;left:50%;transform:translate(-50%,-100%);color:var(--accent);font-size:1.6rem;filter:drop-shadow(0 4px 12px rgba(var(--accent-rgb),.6))}
.map-label{position:absolute;bottom:10px;left:12px;font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-secondary);background:var(--color-bg-overlay);padding:4px 8px;border-radius:var(--radius-xs)}

/* ============================================================================
   PREMIUM LAYER (2026-06-23) - everything below is scoped under #liveSO so the
   shared stylesheet is the single source of truth and wins over the Customers
   page's legacy inline panel rules. Token-driven only, no raw brand colour.
   ========================================================================== */

/* head: a touch of depth + breathing room */
#liveSO .so-head{background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 7%,var(--surface)) 0%,var(--surface) 100%);border-bottom:1px solid var(--border-subtle)}
#liveSO .so-name{font-size:var(--fs-lg,1.125rem);letter-spacing:-.01em}

/* section titles get a small leading accent tick */
#liveSO .slideout-section{margin-top:var(--space-lg)}
#liveSO .slideout-section-title{position:relative;display:flex;align-items:center;gap:8px;margin-bottom:var(--space-sm)}
#liveSO .slideout-section-title::before{content:'';width:3px;height:11px;border-radius:2px;background:var(--accent);opacity:.85;flex-shrink:0}

/* grouped field card - lifts the order/account block off the bare panel bg */
#liveSO .so-card{background:var(--surface-raised);border:1px solid var(--border-subtle);border-radius:var(--radius-md);padding:2px var(--space-md)}
#liveSO .so-card .field-row{padding:var(--space-sm) 0}

/* account+billing merged card: primary facts run 2-up on desktop, 1-up narrow, so the card reads
   as one compact block instead of a long single-column list. Auto-flow means an omitted (empty)
   fact just closes the gap - no dead cell. */
#liveSO .so-fact-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:var(--space-lg)}
#liveSO .so-fact-grid .field-row{padding:var(--space-sm) 0}
@media (max-width:420px){#liveSO .so-fact-grid{grid-template-columns:1fr}}

/* location: real OSM tile when coordinates exist, token gradient otherwise */
#liveSO .map{height:172px;border:1px solid var(--border-subtle);border-radius:var(--radius-md);overflow:hidden;background:radial-gradient(120% 120% at 50% 18%,color-mix(in srgb,var(--accent) 22%,var(--surface-raised)) 0%,var(--surface-raised) 70%)}
#liveSO .map-tile{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.92) contrast(1.02)}
/* PANEL-1: OSM slippy-tile mosaic (staticmap.openstreetmap.de is gone). The 768px 3x3 grid is
   anchored at the card centre and shifted by the fractional tile offset so the pin sits on the
   building. Attribution chip is an ODbL requirement of tile.openstreetmap.org. */
#liveSO .map-osm{inset:auto;left:50%;top:50%;width:768px;height:768px;object-fit:unset}
#liveSO .map-osm-tile{position:absolute;width:256px;height:256px;filter:saturate(.92) contrast(1.02)}
#liveSO .map-attr{position:absolute;right:6px;bottom:6px;z-index:2;font-size:9px;color:var(--text-tertiary);background:color-mix(in srgb,var(--surface) 70%,transparent);padding:1px 5px;border-radius:var(--radius-xs)}
/* PANEL-1: Go live + Install booking side by side (pair row; stacks on narrow panels) */
#liveSO .so-pair{display:flex;gap:var(--space-sm);align-items:stretch}
#liveSO .so-pair>*{flex:1;min-width:0}
#liveSO .so-pair>*:empty{display:none}
#liveSO .so-pair .slideout-section{margin-top:var(--space-lg)}
@media (max-width:420px){#liveSO .so-pair{flex-direction:column;gap:0}}
#liveSO .map-grid{position:absolute;inset:0;background-image:linear-gradient(color-mix(in srgb,var(--border) 60%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--border) 60%,transparent) 1px,transparent 1px);background-size:26px 26px;opacity:.5;pointer-events:none}
#liveSO .map.map-has-tile .map-grid{display:none}
#liveSO .map-pin{position:absolute;top:50%;left:50%;transform:translate(-50%,-100%);color:var(--accent);font-size:1.7rem;filter:drop-shadow(0 6px 14px color-mix(in srgb,var(--accent) 55%,transparent));z-index:2}
#liveSO .map-label{position:absolute;left:10px;bottom:10px;display:flex;flex-direction:column;gap:1px;background:color-mix(in srgb,var(--surface) 78%,transparent);backdrop-filter:blur(4px);border:1px solid var(--border-subtle);padding:6px 10px;border-radius:var(--radius-sm);z-index:2}
#liveSO .map-name{font-size:var(--text-sm);color:var(--text);font-weight:var(--fw-medium,500)}
#liveSO .map-loc{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.06em;text-transform:uppercase;color:var(--text-tertiary)}
/* Honest no-geocode state: plain surface (no accent gradient pretending to be a
   map), muted pin, and a plain-language note in the label chip. */

/* lifecycle timeline: stronger dots, current-step pulse */
#liveSO .lifecycle-timeline{padding:var(--space-md) 2px}
#liveSO .tl-dot{width:24px;height:24px;font-weight:var(--fw-semibold,600);box-shadow:var(--shadow-sm)}
#liveSO .tl-step.done::after,#liveSO .tl-step.done .tl-dot{background:var(--accent);border-color:var(--accent)}
#liveSO .tl-step.current .tl-dot{animation:soPulse 2s var(--ease,ease) infinite}
@keyframes soPulse{0%,100%{box-shadow:0 0 0 4px var(--warn-bg)}50%{box-shadow:0 0 0 7px color-mix(in srgb,var(--warn) 18%,transparent)}}

/* trust: confidence donut + side stats */
#liveSO .trust-row{display:flex;align-items:center;gap:var(--space-md);margin-bottom:var(--space-sm)}
#liveSO .trust-donut{position:relative;width:64px;height:64px;flex-shrink:0}
#liveSO .td-track{fill:none;stroke:var(--border-subtle);stroke-width:7}
#liveSO .td-arc{fill:none;stroke:var(--accent);stroke-width:7;stroke-linecap:round;transition:stroke-dashoffset var(--duration-slow,.5s) var(--ease)}
#liveSO .td-center{position:absolute;inset:0;display:flex;align-items:baseline;justify-content:center;gap:1px}
#liveSO .td-pct{font-family:var(--font-heading);font-size:var(--fs-md,1rem);font-weight:var(--fw-semibold,600);color:var(--text)}
#liveSO .td-unit{font-size:var(--text-2xs);color:var(--text-tertiary)}
#liveSO .trust-side{flex:1;min-width:0}
#liveSO .trust-cap{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary);margin-bottom:6px}
#liveSO .trust-side .so-stats{margin-bottom:0}

/* billing and payments */
#liveSO .so-bill-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-md);background:var(--surface-raised);border:1px solid var(--border-subtle);border-radius:var(--radius-md);padding:var(--space-sm) var(--space-md);margin-bottom:var(--space-sm)}
#liveSO .so-bill-mrr{display:flex;align-items:baseline;gap:3px}
#liveSO .so-bill-amt{font-family:var(--font-heading);font-size:var(--fs-lg,1.125rem);font-weight:var(--fw-semibold,600);color:var(--text);font-variant-numeric:tabular-nums}
#liveSO .so-bill-cy{font-size:var(--text-2xs);color:var(--text-tertiary)}
#liveSO .so-bill-meta{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.04em;color:var(--text-tertiary);text-align:right}
#liveSO .so-bill-list{margin-top:var(--space-sm)}
#liveSO .so-bill-row{display:grid;grid-template-columns:auto 1fr auto;gap:var(--space-sm);align-items:center;padding:7px 0;border-bottom:1px solid var(--border-subtle);font-size:var(--text-sm)}
#liveSO .so-bill-row:last-child{border-bottom:0}
#liveSO .so-bill-d{font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary)}
#liveSO .so-bill-g{color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#liveSO .so-bill-st{justify-self:start;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.02em;text-transform:capitalize;padding:1px 8px;border-radius:var(--radius-pill);background:var(--glass-bg);color:var(--text-secondary)}
#liveSO .so-bill-st.ok{background:var(--ok-bg,var(--glass-bg));color:var(--ok)}
#liveSO .so-bill-st.warn{background:var(--warn-bg,var(--glass-bg));color:var(--warn)}
#liveSO .so-bill-amt2{font-variant-numeric:tabular-nums;color:var(--text);text-align:right}
#liveSO .so-bill-amt2.pos{color:var(--ok)}
#liveSO .so-bill-amt2.neg{color:var(--warn)}
#liveSO .so-bill-empty{font-size:var(--text-sm);color:var(--text-tertiary);line-height:1.5}

/* ============================================================================
   TWO-AXIS REBUILD (2026-06-23) - tabs, account-status chip, live fibre feed,
   reliability heatmap, trust pre-state. All bound to semantic status tokens.
   ========================================================================== */

/* header account-status chip (axis B) */
#liveSO .so-head{padding-top:var(--space-md)}
#liveSO .so-status{display:flex;align-items:center;gap:6px;margin-bottom:4px}
#liveSO .so-status-chip{border:0;font-family:var(--font-mono);font-size:var(--text-2xs);font-weight:var(--fw-semibold,600);letter-spacing:.14em;text-transform:uppercase;padding:2px 9px;border-radius:var(--radius-pill);color:var(--status-active);background:var(--status-active-bg);}
#liveSO .so-status-chip[data-status="lead"]{color:var(--status-lead);background:var(--status-lead-bg);}
#liveSO .so-status-chip[data-status="shipped"]{color:var(--status-shipped);background:var(--status-shipped-bg);}
#liveSO .so-status-chip[data-status="active"]{color:var(--status-active);background:var(--status-active-bg);}
#liveSO .so-status-chip[data-status="overdue"]{color:var(--status-overdue);background:var(--status-overdue-bg);}
#liveSO .so-status-chip[data-status="churned"]{color:var(--status-churned);background:var(--status-churned-bg);}
#liveSO .so-test-badge{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.1em;text-transform:uppercase;padding:2px 8px;border-radius:var(--radius-pill);color:var(--warn);background:var(--warn-bg)}

/* inline status pill (Account card + billing meta) */
#liveSO .so-status-inline{font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.04em;text-transform:uppercase;padding:1px 7px;border-radius:var(--radius-pill);color:var(--status-active);background:var(--status-active-bg)}
#liveSO .so-status-inline[data-status="lead"]{color:var(--status-lead);background:var(--status-lead-bg)}
#liveSO .so-status-inline[data-status="shipped"]{color:var(--status-shipped);background:var(--status-shipped-bg)}
#liveSO .so-status-inline[data-status="overdue"]{color:var(--status-overdue);background:var(--status-overdue-bg)}
#liveSO .so-status-inline[data-status="churned"]{color:var(--status-churned);background:var(--status-churned-bg)}
#liveSO .so-sys{font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary)}

/* TAB STRIP RESTORED (2026-08-27, operator repro). The 2026-08-26 one-pane
   merge took these rules with it; the merge's real win - no fact stated in
   both halves - is kept, and the two halves are addressable again. Same
   visual language as the network page's slide-out strip (pages/02-network.html),
   which is where this pattern already lives, so the two panels read alike.
   Bound to the panel head, which is sticky, so the strip stays reachable
   however far either pane scrolls. */
#liveSO .so-tabs{display:flex;gap:var(--space-md);margin-top:var(--space-md)}
#liveSO .so-tab{background:transparent;border:0;color:var(--text-tertiary);font-family:var(--font-mono);font-size:var(--fs-xs,.75rem);letter-spacing:var(--ls-wide,.08em);text-transform:uppercase;padding:4px 0;cursor:pointer;border-bottom:2px solid transparent;transition:color var(--duration-fast,.15s) var(--ease),border-color var(--duration-fast,.15s) var(--ease)}
#liveSO .so-tab:hover{color:var(--text-secondary)}
#liveSO .so-tab[aria-selected="true"]{color:var(--accent);border-bottom-color:var(--accent)}
#liveSO .so-pane[hidden]{display:none}

/* go live row */
.so-golive{display:flex;gap:var(--space-sm);align-items:center;flex-wrap:wrap}

/* live fibre indicator (reads client_building_health, never the button/DB) */
#liveSO .fibre-ind{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.04em;text-transform:uppercase;padding:2px 9px;border-radius:var(--radius-pill);background:var(--glass-bg);color:var(--text-secondary)}
#liveSO .fibre-dot{width:7px;height:7px;border-radius:50%;background:var(--text-tertiary)}
#liveSO .fibre-ind[data-fibre="live"]{color:var(--status-active);background:var(--status-active-bg)}
#liveSO .fibre-ind[data-fibre="live"] .fibre-dot{background:var(--status-active);box-shadow:0 0 0 3px color-mix(in srgb, var(--status-active) 22%, transparent)}
#liveSO .fibre-ind[data-fibre="down"]{color:var(--status-overdue);background:var(--status-overdue-bg)}
#liveSO .fibre-ind[data-fibre="down"] .fibre-dot{background:var(--status-overdue)}
#liveSO .fibre-ind[data-fibre="degraded"]{color:var(--warn);background:var(--warn-bg)}
#liveSO .fibre-ind[data-fibre="degraded"] .fibre-dot{background:var(--warn)}

/* reliability heatmap */
#liveSO .so-hm{margin-bottom:var(--space-sm)}
#liveSO .so-hm-row{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
#liveSO .so-hm-sq{width:18px;height:18px;border-radius:3px;background:var(--surface-raised);border:1px solid var(--border-subtle)}
#liveSO .so-hm-sq[data-pay="paid"]{background:var(--status-active);border-color:transparent}
#liveSO .so-hm-sq[data-pay="unpaid"]{background:var(--status-overdue);border-color:transparent}
#liveSO .so-hm-sq[data-pay="void"]{background:var(--status-churned);border-color:transparent}
#liveSO .so-hm-sq[data-pay="other"]{background:var(--warn);border-color:transparent}

/* trust pre-state */
#liveSO .trust-pre{padding:var(--space-md);background:var(--surface-raised);border:1px solid var(--border-subtle);border-radius:var(--radius-md);text-align:center}
#liveSO .trust-pre .empty-title{color:var(--text-secondary);margin-bottom:2px}
#liveSO .trust-pre>div:last-child{font-size:var(--text-sm);color:var(--text-tertiary)}

/* ============================================================================
   PANEL-REUSE-FIX (2026-06-23) - reused canonical components ported into the
   shared panel stylesheet (the page links only tokens.css): the coloured status
   card, the connection (line indicator) card, the conic-gradient .donut, and the
   12-month payment-reliability strip. Bound to the semantic status tokens.
   ========================================================================== */

/* dominant coloured status card (axis B) - the bold state cue from the mockup */
#liveSO .so-statuscard{position:relative;border-radius:var(--radius-md);padding:var(--space-md);background:var(--status-active-bg);border:1px solid color-mix(in srgb,var(--status-active) 30%,transparent)}
#liveSO .so-statuscard[data-status="lead"]{background:var(--status-lead-bg);border-color:color-mix(in srgb,var(--status-lead) 30%,transparent)}
#liveSO .so-statuscard[data-status="shipped"]{background:var(--status-shipped-bg);border-color:color-mix(in srgb,var(--status-shipped) 30%,transparent)}
#liveSO .so-statuscard[data-status="active"]{background:var(--status-active-bg);border-color:color-mix(in srgb,var(--status-active) 30%,transparent)}
#liveSO .so-statuscard[data-status="overdue"]{background:var(--status-overdue-bg);border-color:color-mix(in srgb,var(--status-overdue) 30%,transparent)}
#liveSO .so-statuscard[data-status="churned"]{background:var(--status-churned-bg);border-color:color-mix(in srgb,var(--status-churned) 30%,transparent)}
#liveSO .sc-label{display:flex;align-items:center;gap:4px;font-family:var(--font-mono);font-size:var(--text-2xs);letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary)}
#liveSO .sc-big{font-family:var(--font-heading);font-size:1.5rem;font-weight:var(--fw-bold,700);line-height:1.05;margin:4px 0 3px;color:var(--status-active)}
#liveSO .so-statuscard[data-status="lead"] .sc-big{color:var(--status-lead)}
#liveSO .so-statuscard[data-status="shipped"] .sc-big{color:var(--status-shipped)}
#liveSO .so-statuscard[data-status="active"] .sc-big{color:var(--status-active)}
#liveSO .so-statuscard[data-status="overdue"] .sc-big{color:var(--status-overdue)}
#liveSO .so-statuscard[data-status="churned"] .sc-big{color:var(--text-secondary)}
#liveSO .sc-meta{font-size:var(--text-xs);color:var(--text);opacity:.85}

/* status + connection side by side - neither needs a full-width bar */
#liveSO .so-duo{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm);align-items:stretch}
#liveSO .so-duo>*{min-width:0}
#liveSO .so-duo .sc-big{font-size:1.15rem}
@media (max-width:420px){#liveSO .so-duo{grid-template-columns:1fr}}

/* connection / line indicator card (reused .tile-status pattern) */
#liveSO .so-conncard{border-radius:var(--radius-md);padding:var(--space-md);background:var(--surface-raised);border:1px solid var(--border-subtle)}
#liveSO .so-conncard.st-up{background:color-mix(in srgb,var(--ok) 16%,var(--surface-raised))}
#liveSO .so-conncard.st-down{background:color-mix(in srgb,var(--danger) 16%,var(--surface-raised))}
#liveSO .so-conncard.st-degraded{background:color-mix(in srgb,var(--warn) 16%,var(--surface-raised))}
#liveSO .so-conncard.st-unknown{background:color-mix(in srgb,var(--color-status-muted) 18%,var(--surface-raised))}
#liveSO .so-conncard .sc-big{font-size:1.25rem;color:var(--ok)}
#liveSO .so-conncard.st-down .sc-big{color:var(--danger)}
#liveSO .so-conncard.st-degraded .sc-big{color:var(--warn)}
#liveSO .so-conncard.st-unknown .sc-big{color:var(--text-secondary)}
#liveSO .so-conn-last{font-family:var(--font-mono);font-size:var(--text-2xs);color:var(--text-tertiary);margin-top:6px}

/* conic-gradient donut (canonical 00-global donut; defined locally since the page links only tokens.css) */
#liveSO .donut{border-radius:var(--radius-circle);position:relative;flex-shrink:0}
#liveSO .donut::after{content:'';position:absolute;inset:16px;border-radius:var(--radius-circle);background:var(--surface)}
#liveSO .donut-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1}
#liveSO .donut-center .v{font-family:var(--font-heading);font-weight:var(--fw-bold,700);font-size:var(--fs-md,1rem);color:var(--text);line-height:1.1}
#liveSO .donut-center .l{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-tertiary)}
#liveSO .so-trust-row{display:flex;align-items:center;gap:var(--space-md)}
#liveSO .so-trust-side{flex:1;min-width:0}
#liveSO .so-trust-meta{font-size:var(--text-sm);color:var(--text-secondary);line-height:1.5;margin-top:4px}
#liveSO .so-trust-meta strong{color:var(--text)}

/* 12-month payment-reliability strip (reused from 02-subscribers) */
#liveSO .billing-strip{display:flex;gap:3px;align-items:flex-end;height:42px;margin-top:var(--space-xs)}
#liveSO .bs-month{flex:1;border-radius:2px}
#liveSO .bs-paid{background:var(--ok);height:100%}
#liveSO .bs-late{background:var(--warn);height:72%}
/* A REAL unpaid invoice: it fell due and was never paid. This is the only month that
   earns the danger palette, because it is the only one a customer actually failed. */
#liveSO .bs-missed{background:color-mix(in srgb,var(--danger) 70%,var(--surface-raised));height:60%}
/* A month with NO RECORD is not a failure and must never wear a failure's colour
   (operator finding, 2026-08-28: an all-zero billing feed rendered a whole year in the
   delinquent palette beside an ACTIVE badge). Neutral, and visibly "we were not told". */
#liveSO .bs-gap{background:var(--glass-bg);height:40%;border:1px dashed var(--border-subtle)}
/* ...months outside the account's active billing life (pre-signup or post-termination) - always
   neutral, dashed border reads as "not applicable", never as missed/bad behaviour */
#liveSO .bs-outside{background:var(--glass-bg);height:24%;border:1px dashed var(--border-subtle)}
#liveSO .bs-none{background:var(--glass-bg);height:30%;border:1px solid var(--border-subtle)}

/* per-stage Advance (rule-48 clickable): sits under the stage's steps */
#liveSO .stage-advance{display:flex;justify-content:flex-end;padding:10px 0 4px}
#liveSO .stage-adv[disabled]{opacity:.6;cursor:progress}

/* ============================================================================
   LAYOUT REVISION (2026-08 owner mock) - accessible info tooltip (moved the old
   "Go live" explainer + the billing-cache source line off the main flow), the
   hero trust donut, and plain (no table/box) lifetime facts lines.
   ========================================================================== */

/* info tooltip: real toggle (click/Enter/Space), not hover-only - works on touch and for
   keyboard users. Default focus ring is left alone on purpose (keyboard accessibility). */
/* The tooltip and the activate row render inside whichever panel hosts the block (the unified subject panel today), so they are not scoped to the retired shell. */

/* hero trust donut - larger, centred, standalone above the payment timeline. The ring stroke
   width is a fixed 16px inset (.donut::after) at any diameter, so scaling this up keeps the same
   ring width per the owner's mock, just a bigger overall donut. */
#liveSO .so-trust-hero{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-sm);margin:var(--space-sm) 0 var(--space-lg)}
#liveSO .so-donut-hero{width:176px;height:176px}
#liveSO .so-donut-hero .donut-center .v{font-size:1.6rem}
#liveSO .so-donut-hero .donut-center .l{font-size:10px}
#liveSO .so-trust-hero-legend{font-size:var(--text-sm);color:var(--text-secondary)}

/* lifetime facts - plain muted lines, no table, no box */
#liveSO .so-facts-plain{display:flex;flex-direction:column;gap:4px;margin-top:var(--space-sm)}
